diff -u gcc-4.8-4.8.2/debian/README.Debian.ppc64el gcc-4.8-4.8.2/debian/README.Debian.ppc64el --- gcc-4.8-4.8.2/debian/README.Debian.ppc64el +++ gcc-4.8-4.8.2/debian/README.Debian.ppc64el @@ -45,7 +45,7 @@ svn-updates: - updates from the 4.8 branch upto 20131220 (r206145). + updates from the 4.8 branch upto 20131121 (r205210). rename-info-files: Allow transformations on info file names. Reference the @@ -110,6 +110,9 @@ sparc-force-cpu: On sparc default to ultrasparc (v9a) in 32bit mode +pr24619: + Proposed patch for PR mudflap/24619 (instrumentation of dlopen) + gccgo-version: Omit the subminor number from the go libdir @@ -133,6 +136,9 @@ arm-sanitizer: Enable libsanitizer on ARM. +aarch64-libjava: + Build gcj for aarch64-linux-gnu + libgo-setcontext-config: libgo: Overwrite the setcontext_clobbers_tls check on mips* @@ -143,7 +149,6 @@ Fix cross building a native compiler. kfreebsd-unwind: - DWARF2 EH unwinding support for AMD x86-64 and x86 KFreeBSD. libgcc-no-limits-h: Don't include in libgcc/libgcc2.c. @@ -152,84 +157,15 @@ boehm-gc: use mmap instead of brk also on kfreebsd-*. pr49847: - Proposed patch for PR rtl-optimization/49847 (cc0 targets). libffi-m68k: Apply #660525 fix to in-tree libffi -m68k-picflag: - backport of trunk r204854 - fixes relocation errors when linking large libs (smokeqt, python-qt4) - -sys-auxv-header: - Check for the sys/auxv.h header file. - -go-use-gold: - Pass -fuse-ld=gold to gccgo on targets supporting -fsplit-stack - -go-testsuite: - Skip Go testcase on AArch64 which hangs on the buildds. - -pr57363: - Fix PR libgcc/57363, taken from the trunk. +gotest-elfv2: libstdc++-python3: Make the libstdc++-v3 pretty printer compatible with Python3. -ada-driver-check: - Simplify Ada driver check (we always build using the required - Ada version. Needed for warnings on alpha. - -ada-gcc-name: - use gcc-4.8 instead of gcc as the command name. - -ada-default-project-path: - - Change the default search path for project files to the one specified - by the Debian Policy for Ada: /usr/share/ada/adainclude. - -ada-symbolic-tracebacks: - - Enable support for symbolic tracebacks in exceptions (delete the dummy - convert_addresses from adaint.c, and provide a real one separately.) - -ada-library-project-files-soname: - - in project files, use the exact Library_Version provided, if any, as - the soname of libraries; do not strip minor version numbers - (PR ada/40025). - -ada-ppc64: - -ada-link-lib: - - Install the shared Ada libraries as '.so.1', not '.so' to conform - to the Debian policy. - - Don't include a runtime link path (-rpath), when linking binaries. - - Build the shared libraries on hppa-linux. - - Instead of building libada as a target library only, build it as - both a host and, if different, target library. - - Build the GNAT tools in their top-level directory; do not use - recursive makefiles. - - Link the GNAT tools dynamically. - -ada-libgnatvsn: - - Introduce a new shared library named libgnatvsn, containing - common components of GNAT under the GNAT-Modified GPL, for - use in GNAT tools, ASIS, GLADE and GPS. Link the gnat tools - against this new library. - -ada-libgnatprj: - - Introduce a new shared library named libgnatprj, containing - the GNAT project file manager licensed under the pure GPL, for - use in GNAT tools, GLADE and GPS. Link the GNAT tools against - this new library. - -ada-acats: - - When running the ACATS, look for the gnat tools in their new - directory (build/gnattools), and for the shared libraries in - build/gcc/ada/rts-shared-zcx, build/libgnatvsn and build/libgnatprj. - -ada-link-shlib: - In gnatlink, pass the options and libraries after objects to the - linker to avoid link failures with --as-needed. Closes: #680292. - gdc-updates: gdc updates up to 20130611. @@ -254,32 +190,11 @@ Modify gdc driver to have no libphobos by default. disable-gdc-tests: - Disable D tests, hang on many buildds - -m68k-ada: - -m68k-revert-pr45144: - -pr52714: - Proposed fix for PR rtl-optimization/52714: - Revert gcc 4.8 to gcc the 4.5 version of the PR rtl-optimization/45695 fix: - -pr58369: - backport of trunk r204224 - fixes ICE during building boost 1.54 - - PR rtl-optimization/58369 - * reload1.c (compute_reload_subreg_offset): New function. - (choose_reload_regs): Use it to pass endian-correct - offset to subreg_regno_offset. - -pr52306: - Disable -fauto-inc-dec by default for m68k - since it can generate ICEs in C++ code, - until a fix is found. gcc-ppc64el: - Changes from the ibm/gcc-4_8-branch (20131212) + Changes from the ibm/gcc-4_8-branch (20131125) + +libffi-ppc64el: gcc-ppc64el-doc: Changes from the ibm/gcc-4_8-branch (documentation) @@ -287,23 +202,12 @@ gcc-sysroot: Allow building --with-sysroot=/ -goarch-aarch64: - Introduce the arm64 goarch. - -libgo-explicit-reservation: - Fix statically linked gccgo binaries on AArch64. - ada-kfreebsd: - add support for GNU/kFreeBSD. + Fix gnat build failure on kfreebsd. arm-multilib-defaults: Set MULTILIB_DEFAULTS for ARM multilib builds -cross-fixes: - Fix the linker error when creating an xcc for ia64 - -cross-install-location: - gcc-ice-hack: Retry the build on an ice, save the calling options and preprocessed source when the ice is reproducible. @@ -341,9 +245,9 @@ - Disable some biarch libraries for biarch builds. - Fix multilib builds on kernels which don't support all multilibs. -cross-no-locale-include: - Don't add /usr/local/include for cross compilers. Assume that - /usr/include is ready for multiarch, but not /usr/local/include. +g++-multiarch-incdir: + Use /usr/include//c++/4.x as the include directory + for host dependent c++ header files. gcc-multilib-multiarch: Don't auto-detect multilib osdirnames. @@ -362,7 +265,0 @@ - -gcc-default-ssp: - Turn on -fstack-protector by default for C, C++, ObjC, ObjC++. - Build libgcc using -fno-stack-protector. - -gcc-default-format-security: - Turn on -Wformat -Wformat-security by default for C, C++, ObjC, ObjC++. diff -u gcc-4.8-4.8.2/debian/README.maintainers gcc-4.8-4.8.2/debian/README.maintainers --- gcc-4.8-4.8.2/debian/README.maintainers +++ gcc-4.8-4.8.2/debian/README.maintainers @@ -9,53 +9,32 @@ almost 100 binary packages, using a single set of build scripts. The 3 source packages are: -gcc-x.y: C, C++, Fortran, Objective-C and Objective-C++, plus many +gcc-4.3: C, C++, Fortran, Objective-C and Objective-C++, plus many common libraries like libssp and libgcc. -gcj-x.y: Java. -gnat-x.y: Ada. +gcj-4.3: Java. +gnat-4.3: Ada. The way we do this is quite peculiar, so listen up :) -When we build from the gcc-x.y source package, we produce, among many -others, a gcc-x.y-source binary package that contains the pristine +When we build from the gcc-4.3 source package, we produce, among many +others, a gcc-4.3-source binary package that contains the pristine upstream tarball and some Debian-specific patches. Any user can then install this package on their Debian system, and will have the full -souces in /usr/src/gcc-x.y/gcc-.tar.bz2, along with the +souces in /usr/src/gcc-4.3/gcc-.tar.bz2, along with the Makefile snippets that unpack and patch them. The intended use for this package is twofold: (a) allow users to build their own cross-compilers, and (b) build the other two packages, -gcj-x.y and gnat-x.y. +gcj-4.3 and gnat-4.3. -- gcc-x.y requires only a C compiler to build and produces C, C++, - Fortran, Go and Objective-C compilers and libraries. It also - produces the binary package gcc-x.y-source containing all the - sources and patches in a tarball. +For gcj-4.3 and gnat-4.3, the "source tarball" just contains an empty +directory; e.g.: -- gcj-x.y build-depends on gcc-x.y-source and C++ and Java compilers. - Its .orig.tar.bz2 file only contains an empty directory; the real - sources from which it builds the binary packages are in - gcc-x.y-source. +$ tar tzf gnat-4.3_4.3-20070609.orig.tar.gz +gnat-4.3-4.3-20070609.orig/ -- gnat-x.y build-depends on gcc-x.y-source and an Ada compiler. It - does not even have an .orig.tar.bz2 package; it is a Debian native - package. - -The benefits of this split are many: - -- bootstrapping a subset of languages is much faster than - bootstrapping all languages and libraries (which can take a full - week on slow architectures like mips or arm) - -- the language maintainers don't have to wait for each other - -- for new ports, the absence of a port of, say, gnat-x.y does not - block the porting of gcc-x.y. - -gcc-x.y-source is also intended for interested users to build -cross-compiler packages. Debian cannot provide all possible -cross-compiler packages (i.e. all possible host, target, language and -library combinations), so instead tries to facilitate building them. +The build scripts for all source packages are the same, and they are +included, as usual, in the .diff.gz file. * The build sequence @@ -74,66 +53,67 @@ then, debian/rules will build only the Java binary packages. -The second step is to build debian/control from debian/control.m4 and -a complex set of rules specified in debian/rules.conf. The resulting +The second step is to unpack the GCC source tarball. This tarball is +either in the build directory (when building gcc-4.3), or in +/usr/src/gcc-4.3/gcc-.tar.bz2 (when building the other +source packages). + +The third step is to build debian/control from debian/control.m4 and a +complex set of rules specified in debian/rules.conf. The resulting control file contains only the binary packages to be built. -The third step is to select which patches to apply (this is done in +The fourth step is to select which patches to apply (this is done in debian/rules.defs), and then to apply the selected patches (see -debian/rules.patch). The result of this step is a generated -debian/patches/series file for use by quilt. - -The fourth step is to unpack the GCC source tarball. This tarball is -either in the build directory (when building gcc-x.y), or in -/usr/src/gcc-x.y/gcc-x.y.z.tar.xz (when building the other source -packages). +debian/rules.patch). -The fifth step is to apply all patches to the unpacked sources with -quilt. - -The sixth step is to create a "build" directory, cd into it, call +The fifth step is to create a "build" directory, cd into it, call ../src/configure, and bootstrap the compiler and libraries selected. This is in debian/rules2. -The seventh step is to call "make install" in the build directory: -this installs the compiler and libraries into debian/tmp +The sixth step is to call "make install" in the build directory: this +installs the compiler and libraries into debian/tmp (i.e. debian/tmp/usr/bin/gcc, etc.) -The eighth step is to run the GCC test suite. This actually takes at +The seventh step is to run the GCC test suite (this actually takes at least as much time as bootstrapping, and you can disable it by setting -WITHOUT_CHECK to "yes" in the environment. +WITHOUT_CHECK to "yes" in the environment). -The ninth step is to build the binary packages, i.e. the .debs. This +The eighth step is to build the binary packages, i.e. the .debs. This is done by a set of language- and architecture-dependent Makefile snippets in the debian/rules.d/ directory, which move files from the debian/tmp tree to the debian/ trees. * Making your own packages -In this example, we will build our own gnat-x.y package. +In this example, we will build our own gnat-4.3 package. + +1) Create a .orig.tar.gz tarball containing a single, empty directory. -1) Install gcc-x.y-source, which contains the real sources: +$ mkdir gnat-4.3-4.3-20070609.orig +$ tar czf gnat-4.3_4.3-20070609.orig.tar.gz gnat-4.3-4.3-20070609.orig -# aptitude install gcc-x.y-source +2) Install gcc-4.3-source, which contains the real sources: -2) Create a build directory: +# apt-get install gcc-4.3-source -$ mkdir gnat-x.y-x.y.z; cd gnat-x.y-x.y.z +3) Create a build directory: -3) Checkout from Subversion: +$ mkdir gnat-4.3-4.3-20070609; cd gnat-4.3-4.3-20070609 -$ svn checkout svn://svn.debian.org/gcccvs/branches/sid/gcc-x.y/debian +4) Checkout from Subversion: -4) Edit the debian/changelog file, adding a new entry at the top that - starts with "gnat-x.y". +$ svn checkout svn://svn.debian.org/gcccvs/branches/sid/gcc-4.3/debian -5) Generate the debian/control file, adjusted for gnat: +5) Edit the debian/changelog file, adding a new entry at the top that + starts with "gnat-4.3" instead of "gcc-4.3". + +6) Generate the debian/control file, adjusted for gnat: $ debian/rules control -8) Build: +7) Build: -$ dpkg-buildpackage +$ dpkg-buildpackage -rfakeroot * Hints @@ -156,7 +136,7 @@ 2) As your regular user, create the working directory in the tmpfs -$ cp --archive ~/src/debian/gcc-x.y-x.y.z ~/src/debian/ram +$ cp --archive ~/src/debian/gcc-4.3-4.3-20070901 ~/src/debian/ram 3) Build in there. On my dual-core, 2 GHz amd64, it takes 34 minutes to build gnat, and the tmpfs takes 992 MiB of physical RAM but @@ -182,15 +162,76 @@ -process. It uses quilt but the necessary debian/patches/series is not -part of the packaging scripts; instead, "debian/rules patch" generates -this file by looking at debian/control (which is itself generated!), -debian/changelog and other files. Then it applies all the patches. -At this point, you can use quilt as usual: +process. The patches are shell scripts located in debian/patches. +The file debian/rules.defs selects the language front-ends and +libraries to build. Then, based on that, debian/rules.patch selects +which patches to apply and in which order, then applies them and +produces a file listing the applied patches in order in +stamps/02-patch-stamp. -$ cd ~/src/debian/gcc-x.y -$ export QUILT_PATCHES=$PWD/debian/patches -$ quilt series +There is currently no tool to help modify patches; you have to do it +by hand. Here is one possible way to do it: + +1) Apply all patches up to and EXCLUDING the patch you intend to + modify, in order. + +2) Make a deep copy of the src directory, e.g. + $ cp --archive src src.bak + +3) Apply the patch you intend to modify. -If you add new patches, remember to add them to the version control -system too. +4) Open the .dpatch file in your editor and remove the entire patch + section; leave alone the shell script part at the top. + +5) Change the files you want in the src directory. After making + changes, you can experiment with + $ make -C build -jK + (where K is the number of processor threads you have) + +6) $ diff -rNu src.bak src >> debian/patches/.dpatch + +7) Apply all remaining patches, to see if your change broke any of + them. + +8) $ svn commit debian/patches/.dpatch + +If you want to add a new patch, the procedure is similar. You must +first choose where in the list of patches you want to insert your new +patch. Then, apply all patches up to that point and start editing. +Do not forget to add a reference to your patch at the proper place in +debian/rules.patch. + +** Patching GCC with Quilt + +The above method uses an entire copy of the source tree, which is +currently 474 megabytes in size. If you are in a one-gigabyte ram +disk (see Hints above), this may be a problem. One solution to this +problem is to use quilt, which will only keep copies of the files +touched by patches, not all files. It also automates the updating of +a patch after you change the sources. + +Quilt however does not take into account the selection of patches made +in debian/rules.defs; instead it has a static list of patches. After +calling "debian/rules patch", you can generate such a list like this: + +$ egrep '^[^ ]+:' stamps/02-patch-stamp | \ + sed 's!:!.dpatch -p0!' > debian/patches/series + +Unfortunately, not all patches are applied with -p0; you must then +edit debian/patches/series by hand to replace -p0 with -p1 for a few +patches. + +Once you have your debian/patches/series: + +$ debian/rules unpatch +$ export QUILT_PATCHES=$PWD/debian/patches +$ cd src +$ quilt push -a (or quilt push ) +edit files at will; quilt add to add a new file to the patch +$ make -C ../build +$ quilt refresh +$ quilt push -a # check that no patch is broken +$ quilt pop -a +$ cd .. +$ debian/rules clean build +$ svn commit -- -Ludovic Brenta, 2012-04-02. +Ludovic Brenta, 2007-12-05. diff -u gcc-4.8-4.8.2/debian/changelog gcc-4.8-4.8.2/debian/changelog --- gcc-4.8-4.8.2/debian/changelog +++ gcc-4.8-4.8.2/debian/changelog @@ -1,337 +1,8 @@ -gcc-4.8 (4.8.2-19ubuntu1ppa3~precise1) precise; urgency=medium +gcc-4.8 (4.8.2-7ubuntu1~saucy1) saucy; urgency=low - * Attempt to backport 4.8.2 to precise + * PPA upload for saucy. - -- Tony Kelman Tue, 19 Aug 2014 23:00:00 -0700 - -gcc-4.8 (4.8.2-19ubuntu1) trusty; urgency=medium - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - Don't build the libgcc packages, now built from gcc-4.9. - - -- Matthias Klose Fri, 04 Apr 2014 19:36:41 +0200 - -gcc-4.8 (4.8.2-19) unstable; urgency=medium - - * Update to SVN 20140404 (r209122) from the gcc-4_8-branch. - - Fix PR rtl-optimization/60700 (wrong code on x86), - PR rtl-optimization/57637 (wrong code on ARM in SPEC2000), - PR target/60039 (SH), PR ada/60703. - - [ Matthias Klose ] - * Include include and include-fixed header files into the stage1 - gcc-4.8 package. - * Explicitly configure with --disable-multilib on sparc64 when no - multilibs are requested (Helmut Grohne). Closes: #743342. - * Fix PR target/60034 (AArch64), taken from the trunk. LP: #1270789. - * Update ada-ppc64.diff from the gnat-4.9 package, fixing the gnat build - on powerpc. - * Fix PR target/60609 (ARM), proposed patch (Charles Baylis). LP: #1295653. - * Build libphobos for armel and armhf. - * Include the gnu triplet prefixed gcov and gcc-{ar,nm,ranlib} binaries. - * Stop building ppc64el from the ibm branch, now integrated in the fsf - branch. - - [ Iain Buclaw ] - * Update the GDC frontend (20140401). - - -- Matthias Klose Fri, 04 Apr 2014 19:32:58 +0200 - -gcc-4.8 (4.8.2-17ubuntu2) trusty; urgency=medium - - * Update to SVN 20140329 (r208938) from the gcc-4_8-branch. - - Fix PR libstdc++/60658 (std::atomic is unexpectedly not lock-free), - PR libstdc++/59548 (abort in debug mode), - PR rtl-optimization/60601 (ice), PR tree-optimization/60429 (wrong code - building Qt with -O3), PR rtl-optimization/60452 (wrong code with -O1 - and large offsets in the frame), - PR ipa/60419 (ice-on-valid-code with -O3, LP: #1286343), - PR fortran/60522 (ice-on-valid-code), PR fortran/60576 (wrong code), - PR fortran/60677 (wrong code). - * Don't ignore DEB_CROSS_NO_BIARCH=yes ignored for DEB_TARGET_ARCH=x32. - (Helmut Grohne). Closes: #742358. - * debian/patches/ada-ppc64.diff: Fix for ppc64el (Ulrich Weigand). - * Avoid clobbering stack pointer via P8 fusion peephole. fixing Ada build - on ppc64el (Ulrich Weigand). - * Fix cross building targeting x32 (Helmut Grohne). Closes: #742539. - - -- Matthias Klose Sat, 29 Mar 2014 16:32:05 +0100 - -gcc-4.8 (4.8.2-17ubuntu1) trusty; urgency=medium - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - -- Matthias Klose Fri, 21 Mar 2014 17:46:46 +0100 - -gcc-4.8 (4.8.2-17) unstable; urgency=medium - - * Update to SVN 20140320 (r208738) from the gcc-4_8-branch. - * Update the Linaro support to the 4.8-2014.03 release. - * Update the ibm branch to SVN 20140320 (r208622). - * Fix PR target/58595, ARM TLS handling. Taken from the trunk. - * Create a dummy arm-acle-intrinsics.texi exists for AArch64 builds - (Wookey). Closes: #742165. - - -- Matthias Klose Fri, 21 Mar 2014 10:47:08 +0100 - -gcc-4.8 (4.8.2-16ubuntu6) trusty; urgency=medium - - * Update to SVN 20140306 (r208384) from the gcc-4_8-branch. - * Update the ibm branch to SVN 20140306 (r208322). - * Fix PR target/58595, ARM TLS handling. Taken from the trunk. - - -- Matthias Klose Thu, 06 Mar 2014 15:30:27 +0100 - -gcc-4.8 (4.8.2-16ubuntu5) trusty; urgency=medium - - * Update to SVN 20140303 (r208303) from the gcc-4_8-branch. - * Update the ibm branch to SVN 20140304 (r208291). - - -- Matthias Klose Tue, 04 Mar 2014 10:28:21 +0100 - -gcc-4.8 (4.8.2-16ubuntu4) trusty; urgency=medium - - * Update to SVN 20140226 (r208166) from the gcc-4_8-branch. - * Update the ibm branch to SVN 20140226 (r208166). - - -- Matthias Klose Wed, 26 Feb 2014 08:53:56 +0100 - -gcc-4.8 (4.8.2-16ubuntu3) trusty; urgency=medium - - * Update the ibm branch to SVN 20140224 (r208054). - * Re-add gcc-4.8 dependency on libgcc-4.8-dev. LP: #1283850. - - -- Matthias Klose Mon, 24 Feb 2014 11:40:55 +0100 - -gcc-4.8 (4.8.2-16ubuntu2) trusty; urgency=medium - - * Update to SVN 20140221 (r208010) from the gcc-4_8-branch. - * Update the ibm branch to SVN 20140221 (r207920). - * Enable SSP by default on AArch64. - * Build libgcc packages for cross builds in trusty. - - -- Matthias Klose Fri, 21 Feb 2014 19:42:07 +0100 - -gcc-4.8 (4.8.2-16ubuntu1) trusty; urgency=medium - - * Stop building the libgcc1 packages, now built by gccgo-4.9. - - -- Matthias Klose Tue, 18 Feb 2014 12:17:00 +0100 - -gcc-4.8 (4.8.2-16) unstable; urgency=medium - - * Update to SVN 20140217 (r207828) from the gcc-4_8-branch. - * Update the ibm branch to SVN 20140211 (r207700). - * Update the Linaro support to the 4.8-2014.02 release. - * Fix gij wrapper script on hppa. Closes: #739224. - - -- Matthias Klose Mon, 17 Feb 2014 21:46:34 +0100 - -gcc-4.8 (4.8.2-15ubuntu3) trusty; urgency=medium - - * Only build using the ibm branch on ppc64el. - - -- Matthias Klose Wed, 12 Feb 2014 00:16:44 +0100 - -gcc-4.8 (4.8.2-15ubuntu2) trusty; urgency=medium - - * Update to SVN 20140211 (r207700) from the gcc-4_8-branch. - * Update the ibm branch to SVN 20140211 (r207700). - - -- Matthias Klose Tue, 11 Feb 2014 23:41:13 +0100 - -gcc-4.8 (4.8.2-15ubuntu1) trusty; urgency=medium - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - -- Matthias Klose Sun, 09 Feb 2014 12:36:11 +0100 - -gcc-4.8 (4.8.2-15) unstable; urgency=medium - - * Update to SVN 20140209 (r207641) from the gcc-4_8-branch. - - Fix inconsistent install paths between gccgo and go tool. LP: #1271340. - * Update the ibm branch to SVN 20140207 (r207580). - * armhf: Fix ffi_call_VFP with no VFP arguments (Will Newton). - * Apply proposed patch for PR target/59799, allow passing arrays in - registers on AArch64 (Michael Hudson). - * gcc-4.8-base: Update gcc-4.7-base breaks for updates from wheezy. - Closes: #736607. - - -- Matthias Klose Sun, 09 Feb 2014 11:18:55 +0100 - -gcc-4.8 (4.8.2-14ubuntu4) trusty; urgency=medium - - * Re-upload with the testsuite disabled (hangs on the AArch64 buildds). - - -- Matthias Klose Sat, 25 Jan 2014 00:24:02 +0100 - -gcc-4.8 (4.8.2-14ubuntu3) trusty; urgency=medium - - * Update to SVN 20140124 (r207027) from the gcc-4_8-branch. - - Fix inconsistent install paths between gccgo and go tool. LP: #1271340. - * armhf: Fix ffi_call_VFP with no VFP arguments (Will Newton). - * Apply proposed patch for PR target/59799, allow passing arrays in - registers on AArch64 (Michael Hudson). - - -- Matthias Klose Fri, 24 Jan 2014 14:03:17 +0100 - -gcc-4.8 (4.8.2-14ubuntu2) trusty; urgency=medium - - * Update to SVN 20140117 (r206726) from the gcc-4_8-branch. - * Update the ibm branch to SVN 20140117 (r206670). - - -- Matthias Klose Fri, 17 Jan 2014 19:58:09 +0100 - -gcc-4.8 (4.8.2-14ubuntu1) trusty; urgency=medium - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - -- Matthias Klose Wed, 15 Jan 2014 15:44:15 +0100 - -gcc-4.8 (4.8.2-14) unstable; urgency=medium - - * Update to SVN 20140115 (r206629) from the gcc-4_8-branch. - * Fix call frame information in ffi_closure_SYSV on AArch64. - * Update powerpcspe patches (Roland Stigge). Closes: #735316. - - -- Matthias Klose Wed, 15 Jan 2014 14:12:09 +0100 - -gcc-4.8 (4.8.2-13ubuntu1) trusty; urgency=medium - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - -- Matthias Klose Sun, 12 Jan 2014 14:16:19 +0100 - -gcc-4.8 (4.8.2-13) unstable; urgency=medium - - * Update to SVN 20140112 (r206564) from the gcc-4_8-branch. - - Fix miscompilation due to wrong RTL-optimization (see - PR rtl-optimization/59137). Closes: #716635. - - [ Aurelien Jarno ] - * Reenable the testsuite on mips. - - [ Matthias Klose ] - * Add libgcc, libstdc++, libgfortran symbols files for ppc64el. - * Update libitm symbols for non-default multilibs. - * Add libgcc, libstdc++, libgfortran symbols files for arm64. - * Fix PR target/59588 (AArch64), backport proposed patch. LP: #1263576. - * Fix PR target/59744 (AArch64), taken from the trunk. LP: #1267761. - - -- Matthias Klose Sun, 12 Jan 2014 14:14:42 +0100 - -gcc-4.8 (4.8.2-12ubuntu2) trusty; urgency=medium - - * Remove gnat build dependency. - - -- Matthias Klose Mon, 06 Jan 2014 03:00:48 +0100 - -gcc-4.8 (4.8.2-12ubuntu1) trusty; urgency=medium - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - -- Matthias Klose Mon, 06 Jan 2014 02:47:29 +0100 - -gcc-4.8 (4.8.2-12) unstable; urgency=medium - - * Update to SVN 20140106 (r206351) from the gcc-4_8-branch. - * Only apply m68k specific backports when targeting m68k. - - -- Matthias Klose Mon, 06 Jan 2014 02:35:00 +0100 - -gcc-4.8 (4.8.2-11) unstable; urgency=low - - * Update to SVN 20131230 (r206241) from the gcc-4_8-branch. - * Don't build x32 multilibs for wheezy backports. - * Set the goarch to arm64 for aarch64-linux-gnu. - * Fix statically linked gccgo binaries on AArch64 (Michael Hudson). - LP: #1261604. - * Merge accumulated Ada changes from gnat-4.8. - * Update gnat build dependencies when not built from a separate source. - * Default to -mieee on alpha again (Michael Cree). Closes: #733291. - * Prepare gnat package for cross builds. - - -- Matthias Klose Mon, 30 Dec 2013 08:52:29 +0100 - -gcc-4.8 (4.8.2-10ubuntu2) trusty; urgency=low - - * Update to SVN 20131220 (r206145) from the gcc-4_8-branch. - * Set the goarch to arm64 for aarch64-linux-gnu. - * Fix statically linked gccgo binaries on AArch64 (Michael Hudson). - LP: #1261604. - * Merge accumulated Ada changes from gnat-4.8. - * Update gnat build dependencies when not built from a separate source. - - -- Matthias Klose Fri, 20 Dec 2013 18:24:08 +0100 - -gcc-4.8 (4.8.2-10ubuntu1) trusty; urgency=low - - * Merge with Debian; remaining changes: - - Build from the upstream source. - * Re-enable running the testsuite. - - -- Matthias Klose Fri, 13 Dec 2013 01:22:20 +0100 - -gcc-4.8 (4.8.2-10) unstable; urgency=low - - * Update to SVN 20131213 (r205948) from the gcc-4_8-branch. - * Add missing commit in libjava for gcc-linaro. - - -- Matthias Klose Fri, 13 Dec 2013 01:01:47 +0100 - -gcc-4.8 (4.8.2-9ubuntu2) trusty; urgency=low - - * Add missing commit in libjava for gcc-linaro. - - -- Matthias Klose Thu, 12 Dec 2013 16:54:27 +0100 - -gcc-4.8 (4.8.2-9ubuntu1) trusty; urgency=low - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - -- Matthias Klose Thu, 12 Dec 2013 12:31:04 +0100 - -gcc-4.8 (4.8.2-9) unstable; urgency=low - - * Update to SVN 20131212 (r205924) from the gcc-4_8-branch. - - [ Matthias Klose ] - * Fix libitm symbols files for ppc64. - * Update libatomic symbol file for arm64 and ppc64. - * libgcj-dev: Drop dependencies on gcj-jre-lib and gcj-jdk. - * Fix permissions of some override files. - * Let cross compilers conflict with gcc-multilib (providing - /usr/include/asm for the non-default multilib). - * Configure --with-long-double-128 on powerpcspe (Roland Stigge). - Closes: #731941. - * Update the Linaro support to the 4.8-2013.12 release. - * Update the ibm branch to 20131212. - - [ Aurelien Jarno ] - * patches/note-gnu-stack.diff: restore and rebase lost parts. - - -- Matthias Klose Thu, 12 Dec 2013 12:34:55 +0100 - -gcc-4.8 (4.8.2-8ubuntu1) trusty; urgency=low - - * Merge with Debian; remaining changes: - - Build from the upstream source. - - -- Matthias Klose Wed, 04 Dec 2013 01:22:24 +0100 - -gcc-4.8 (4.8.2-8) unstable; urgency=medium - - * Update to SVN 20131203 (r205647) from the gcc-4_8-branch. - * Fix PR libgcc/57363, taken from the trunk. - - -- Matthias Klose Wed, 04 Dec 2013 01:21:10 +0100 + -- Matthias Klose Fri, 29 Nov 2013 20:45:51 +0100 gcc-4.8 (4.8.2-7ubuntu1) trusty; urgency=low diff -u gcc-4.8-4.8.2/debian/control gcc-4.8-4.8.2/debian/control --- gcc-4.8-4.8.2/debian/control +++ gcc-4.8-4.8.2/debian/control @@ -4,18 +4,18 @@ Maintainer: Ubuntu Core developers XSBC-Original-Maintainer: Debian GCC Maintainers Uploaders: Matthias Klose -Standards-Version: 3.9.5 +Standards-Version: 3.9.4 Build-Depends: debhelper (>= 5.0.62), g++-multilib [amd64 armel armhf i386 kfreebsd-amd64 mips mips64 mips64el mipsel mipsn32 mipsn32el powerpc ppc64 s390 s390x sparc sparc64 x32], - libc6.1-dev (>= 2.13-0ubuntu6) [alpha ia64] | libc0.3-dev (>= 2.13-0ubuntu6) [hurd-i386] | libc0.1-dev (>= 2.13-0ubuntu6) [kfreebsd-i386 kfreebsd-amd64] | libc6-dev (>= 2.13-0ubuntu6), libc6-dev (>= 2.13-31) [armel armhf], libc6-dev-amd64 [i386 x32], libc6-dev-sparc64 [sparc], libc6-dev-sparc [sparc64], libc6-dev-s390 [s390x], libc6-dev-s390x [s390], libc6-dev-i386 [amd64 x32], libc6-dev-powerpc [ppc64], libc6-dev-ppc64 [powerpc], libc0.1-dev-i386 [kfreebsd-amd64], lib32gcc1 [amd64 ppc64 kfreebsd-amd64 mipsn32 mipsn32el mips64 mips64el s390x sparc64 x32], libn32gcc1 [mips mipsel mips64 mips64el], lib64gcc1 [i386 mips mipsel mipsn32 mipsn32el powerpc sparc s390 x32], libc6-dev-mips64 [mips mipsel mipsn32 mipsn32el], libc6-dev-mipsn32 [mips mipsel mips64 mips64el], libc6-dev-mips32 [mipsn32 mipsn32el mips64 mips64el], libc6-dev-armhf [armel], libhfgcc1 [armel], libc6-dev-armel [armhf], libsfgcc1 [armhf], libc6.1-dbg [alpha ia64] | libc0.3-dbg [hurd-i386] | libc0.1-dbg [kfreebsd-i386 kfreebsd-amd64] | libc6-dbg, + libc6.1-dev (>= 2.13-0ubuntu6) [alpha ia64] | libc0.3-dev (>= 2.13-0ubuntu6) [hurd-i386] | libc0.1-dev (>= 2.13-0ubuntu6) [kfreebsd-i386 kfreebsd-amd64] | libc6-dev (>= 2.13-0ubuntu6), libc6-dev (>= 2.13-31) [armel armhf], libc6-dev-amd64 [i386 x32], libc6-dev-sparc64 [sparc], libc6-dev-sparc [sparc64], libc6-dev-s390 [s390x], libc6-dev-s390x [s390], libc6-dev-i386 [amd64 x32], libc6-dev-powerpc [ppc64], libc6-dev-ppc64 [powerpc], libc0.1-dev-i386 [kfreebsd-amd64], lib32gcc1 [amd64 ppc64 kfreebsd-amd64 mipsn32 mipsn32el mips64 mips64el s390x sparc64 x32], libn32gcc1 [mips mipsel mips64 mips64el], lib64gcc1 [i386 mips mipsel mipsn32 mipsn32el powerpc sparc s390 x32], libc6-dev-mips64 [mips mipsel mipsn32 mipsn32el], libc6-dev-mipsn32 [mips mipsel mips64 mips64el], libc6-dev-mips32 [mipsn32 mipsn32el mips64 mips64el], libc6-dev-x32 [amd64 i386], libx32gcc1 [amd64 i386], libc6-dev-armhf [armel], libhfgcc1 [armel], libc6-dev-armel [armhf], libsfgcc1 [armhf], libc6.1-dbg [alpha ia64] | libc0.3-dbg [hurd-i386] | libc0.1-dbg [kfreebsd-i386 kfreebsd-amd64] | libc6-dbg, kfreebsd-kernel-headers (>= 0.84) [kfreebsd-any], m4, libtool, autoconf2.64, libunwind7-dev (>= 0.98.5-6) [ia64], libatomic-ops-dev [ia64], zlib1g-dev, gawk, lzma, xz-utils, patchutils, - binutils (>= 2.22) | binutils-multiarch (>= 2.22), binutils-hppa64 (>= 2.22) [hppa], + binutils (>= 2.23.52) | binutils-multiarch (>= 2.23.52), binutils-hppa64 (>= 2.23.52) [hppa], gperf (>= 3.0.1), bison (>= 1:2.3), flex, gettext, texinfo (>= 4.3), locales, sharutils, procps, zlib1g-dev, libantlr-java, python, libffi-dev, fastjar, libmagic-dev, libecj-java (>= 3.3.0-2), zip, libasound2-dev [ !hurd-any !kfreebsd-any], libxtst-dev, libxt-dev, libgtk2.0-dev (>= 2.4.4-2), libart-2.0-dev, libcairo2-dev, g++-4.8 [armel armhf], netbase, - libcloog-ppl-dev, libmpc-dev (>= 1.0), libmpfr-dev (>= 3.0.0-9~), libgmp-dev (>= 2:5.0.1~), + libcloog-isl-dev (>= 0.18), libmpc-dev (>= 1.0), libmpfr-dev (>= 3.0.0-9~), libgmp-dev (>= 2:5.0.1~), dejagnu [!m68k !hurd-amd64 !hurd-i386 !hurd-alpha], autogen, realpath (>= 1.9.12), chrpath, lsb-release, quilt Build-Depends-Indep: doxygen (>= 1.7.2), graphviz (>= 2.2), ghostscript, texlive-latex-base, xsltproc, libxml2-utils, docbook-xsl-ns, Homepage: http://gcc.gnu.org/ @@ -29,11 +29,57 @@ Priority: required Depends: ${misc:Depends} Replaces: ${base:Replaces} -Breaks: gcc-4.4-base (<< 4.4.7), gcj-4.4-base (<< 4.4.6-9~), gnat-4.4-base (<< 4.4.6-3~), gcj-4.6-base (<< 4.6.1-4~), gnat-4.6 (<< 4.6.1-5~), gcc-4.7-base (<< 4.7.3), dehydra (<= 0.9.hg20110609-2) +Breaks: gcc-4.4-base (<< 4.4.7), gcj-4.4-base (<< 4.4.6-9~), gnat-4.4-base (<< 4.4.6-3~), gcj-4.6-base (<< 4.6.1-4~), gnat-4.6 (<< 4.6.1-5~), dehydra (<= 0.9.hg20110609-2) Description: GCC, the GNU Compiler Collection (base package) This package contains files common to all languages and libraries contained in the GNU Compiler Collection (GCC). +Package: libgcc1 +Architecture: any +Section: libs +Priority: required +Depends: gcc-4.8-base (= ${gcc:Version}), ${shlibs:Depends}, ${misc:Depends} +Multi-Arch: same +Pre-Depends: multiarch-support +Breaks: ${multiarch:breaks} +Provides: libgcc1-armel [armel], libgcc1-armhf [armhf] +Description: GCC support library + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: libgcc1-dbg +Architecture: any +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), libgcc1 (= ${gcc:EpochVersion}), ${misc:Depends} +Multi-Arch: same +Provides: libgcc1-dbg-armel [armel], libgcc1-dbg-armhf [armhf] +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + +Package: libgcc2 +Architecture: m68k +Section: libs +Priority: required +Depends: gcc-4.8-base (= ${gcc:Version}), ${shlibs:Depends}, ${misc:Depends} +Multi-Arch: same +Pre-Depends: multiarch-support +Breaks: ${multiarch:breaks} +Description: GCC support library + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: libgcc2-dbg +Architecture: m68k +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), libgcc2 (= ${gcc:Version}), ${misc:Depends} +Multi-Arch: same +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + Package: libgcc-4.8-dev Architecture: any Section: libdevel @@ -45,6 +91,47 @@ This package contains the headers and static library files necessary for building C programs which use libgcc, libgomp, libquadmath, libssp or libitm. +Package: libgcc4 +Architecture: hppa +Multi-Arch: same +Pre-Depends: multiarch-support +Breaks: ${multiarch:breaks} +Section: libs +Priority: required +Depends: gcc-4.8-base (= ${gcc:Version}), ${shlibs:Depends}, ${misc:Depends} +Description: GCC support library + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: libgcc4-dbg +Architecture: hppa +Multi-Arch: same +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), libgcc4 (= ${gcc:Version}), ${misc:Depends} +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + +Package: lib64gcc1 +Architecture: i386 powerpc sparc s390 mips mipsel mipsn32 mipsn32el x32 +Section: libs +Priority: optional +Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${misc:Depends} +Conflicts: libgcc1 (<= 1:3.3-0pre9) +Description: GCC support library (64bit) + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: lib64gcc1-dbg +Architecture: i386 powerpc sparc s390 mips mipsel mipsn32 mipsn32el x32 +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), lib64gcc1 (= ${gcc:EpochVersion}), ${misc:Depends} +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + Package: lib64gcc-4.8-dev Architecture: i386 powerpc sparc s390 mips mipsel mipsn32 mipsn32el x32 Section: libdevel @@ -55,6 +142,25 @@ This package contains the headers and static library files necessary for building C programs which use libgcc, libgomp, libquadmath, libssp or libitm. +Package: lib32gcc1 +Architecture: amd64 ppc64 kfreebsd-amd64 s390x sparc64 x32 mipsn32 mipsn32el mips64 mips64el +Section: libs +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${misc:Depends} +Conflicts: ${confl:lib32} +Description: GCC support library (32 bit Version) + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: lib32gcc1-dbg +Architecture: amd64 ppc64 kfreebsd-amd64 s390x sparc64 x32 mipsn32 mipsn32el mips64 mips64el +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), lib32gcc1 (= ${gcc:EpochVersion}), ${misc:Depends} +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + Package: lib32gcc-4.8-dev Architecture: amd64 ppc64 kfreebsd-amd64 s390x sparc64 x32 mipsn32 mipsn32el mips64 mips64el Section: libdevel @@ -65,6 +171,26 @@ This package contains the headers and static library files necessary for building C programs which use libgcc, libgomp, libquadmath, libssp or libitm. +Package: libhfgcc1 +Architecture: armel +Section: libs +Priority: optional +Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${misc:Depends} +Conflicts: libgcc1-armhf [armel] +Description: GCC support library (hard float ABI) + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: libhfgcc1-dbg +Architecture: armel +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), libhfgcc1 (= ${gcc:EpochVersion}), ${misc:Depends} +Conflicts: libgcc1-dbg-armhf [armel] +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + Package: libhfgcc-4.8-dev Architecture: armel Section: libdevel @@ -75,6 +201,26 @@ This package contains the headers and static library files necessary for building C programs which use libgcc, libgomp, libquadmath, libssp or libitm. +Package: libsfgcc1 +Architecture: armhf +Section: libs +Priority: optional +Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${misc:Depends} +Conflicts: libgcc1-armel [armhf] +Description: GCC support library (soft float ABI) + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: libsfgcc1-dbg +Architecture: armhf +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), libsfgcc1 (= ${gcc:EpochVersion}), ${misc:Depends} +Conflicts: libgcc1-dbg-armel [armhf] +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + Package: libsfgcc-4.8-dev Architecture: armhf Section: libdevel @@ -85,6 +231,25 @@ This package contains the headers and static library files necessary for building C programs which use libgcc, libgomp, libquadmath, libssp or libitm. +Package: libn32gcc1 +Architecture: mips mipsel mips64 mips64el +Section: libs +Priority: optional +Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${misc:Depends} +Conflicts: libgcc1 (<= 1:3.3-0pre9) +Description: GCC support library (n32) + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: libn32gcc1-dbg +Architecture: mips mipsel mips64 mips64el +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), libn32gcc1 (= ${gcc:EpochVersion}), ${misc:Depends} +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + Package: libn32gcc-4.8-dev Architecture: mips mipsel mips64 mips64el Section: libdevel @@ -95,6 +260,24 @@ This package contains the headers and static library files necessary for building C programs which use libgcc, libgomp, libquadmath, libssp or libitm. +Package: libx32gcc1 +Architecture: amd64 i386 +Section: libs +Priority: optional +Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${misc:Depends} +Description: GCC support library (x32) + Shared version of the support library, a library of internal subroutines + that GCC uses to overcome shortcomings of particular machines, or + special needs for some languages. + +Package: libx32gcc1-dbg +Architecture: amd64 i386 +Section: debug +Priority: extra +Depends: gcc-4.8-base (= ${gcc:Version}), libx32gcc1 (= ${gcc:EpochVersion}), ${misc:Depends} +Description: GCC support library (debug symbols) + Debug symbols for the GCC support library. + Package: libx32gcc-4.8-dev Architecture: amd64 i386 Section: libdevel @@ -646,7 +829,7 @@ Package: lib32asan0 Section: libs Architecture: amd64 ppc64 kfreebsd-amd64 s390x sparc64 x32 mipsn32 mipsn32el mips64 mips64el -Priority: optional +Priority: extra Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${shlibs:Depends}, ${misc:Depends} Conflicts: ${confl:lib32} Description: AddressSanitizer -- a fast memory error detector (32bit) @@ -665,7 +848,7 @@ Package: lib64asan0 Section: libs Architecture: i386 powerpc sparc s390 mips mipsel mipsn32 mipsn32el x32 -Priority: optional +Priority: extra Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${shlibs:Depends}, ${misc:Depends} Description: AddressSanitizer -- a fast memory error detector (64bit) AddressSanitizer (ASan) is a fast memory error detector. It finds @@ -701,7 +884,7 @@ Package: libx32asan0 Section: libs Architecture: amd64 i386 -Priority: optional +Priority: extra Depends: gcc-4.8-base (= ${gcc:Version}), ${dep:libcbiarch}, ${shlibs:Depends}, ${misc:Depends} Description: AddressSanitizer -- a fast memory error detector (x32) AddressSanitizer (ASan) is a fast memory error detector. It finds @@ -1106,7 +1289,7 @@ Section: debug Architecture: amd64 i386 Priority: extra -Depends: gcc-4.8-base (= ${gcc:Version}), libx32objc4 (= ${gcc:Version}), ${misc:Depends} +Depends: gcc-4.8-base (= ${gcc:Version}), libx32objc4 (= ${gcc:Version}), libx32gcc1-dbg (>= ${gcc:EpochVersion}), ${misc:Depends} Description: Runtime library for GNU Objective-C applications (x32 debug symbols) Library needed for GNU ObjC applications linked against the shared library. @@ -1621,7 +1804,7 @@ Architecture: any Multi-Arch: same Priority: optional -Depends: gcc-4.8-base (= ${gcc:Version}), libgcj14-awt (= ${gcj:Version}), libgcj-bc, ${pkg:gcjgtk}, ${pkg:gcjqt}, zlib1g-dev, ${shlibs:Depends}, ${misc:Depends} +Depends: gcc-4.8-base (= ${gcc:Version}), gcj-4.8-jdk (= ${gcj:Version}), gcj-4.8-jre-lib (>= ${gcj:SoftVersion}), libgcj14-awt (= ${gcj:Version}), libgcj-bc, ${pkg:gcjgtk}, ${pkg:gcjqt}, zlib1g-dev, ${shlibs:Depends}, ${misc:Depends} Suggests: libgcj-doc Description: Java development headers for use with gcj These are the development headers that go along with the gcj front end @@ -1720,7 +1903,7 @@ Architecture: amd64 i386 Section: libs Priority: optional -Depends: gcc-4.8-base (= ${gcc:Version}), ${shlibs:Depends}, ${misc:Depends} +Depends: gcc-4.8-base (= ${gcc:Version}), libx32gcc1 (>= ${gcc:Version}), ${shlibs:Depends}, ${misc:Depends} Description: GNU Standard C++ Library v3 (x32) This package contains an additional runtime library for C++ programs built with the GNU compiler. @@ -1885,7 +2068,7 @@ Architecture: amd64 i386 Section: debug Priority: extra -Depends: gcc-4.8-base (= ${gcc:Version}), libx32stdc++6 (>= ${gcc:Version}), libstdc++-4.8-dev (= ${gcc:Version}), ${shlibs:Depends}, ${misc:Depends} +Depends: gcc-4.8-base (= ${gcc:Version}), libx32stdc++6 (>= ${gcc:Version}), libstdc++-4.8-dev (= ${gcc:Version}), libx32gcc1-dbg (>= ${gcc:EpochVersion}), ${shlibs:Depends}, ${misc:Depends} Conflicts: libx32stdc++6-dbg, libx32stdc++6-4.6-dbg, libx32stdc++6-4.7-dbg Description: GNU Standard C++ Library v3 (debugging files) This package contains the shared library of libstdc++ compiled with @@ -1964,12 +2147,11 @@ This compiler supports D language version 2. Package: libphobos-4.8-dev -Architecture: armel armhf amd64 i386 x32 kfreebsd-amd64 kfreebsd-i386 +Architecture: amd64 i386 x32 kfreebsd-amd64 kfreebsd-i386 Section: libdevel Priority: optional Depends: gcc-4.8-base (= ${gcc:Version}), zlib1g-dev, ${shlibs:Depends}, ${misc:Depends} Provides: libphobos-dev -Replaces: gdc-4.8 (<< 4.8.2-19) Description: Phobos D standard library This is the Phobos standard library that comes with the D2 compiler. . @@ -1977,7 +2159,7 @@ Package: libphobos-4.8-dbg Section: debug -Architecture: armel armhf amd64 i386 x32 kfreebsd-amd64 kfreebsd-i386 +Architecture: amd64 i386 x32 kfreebsd-amd64 kfreebsd-i386 Priority: extra Depends: gcc-4.8-base (= ${gcc:Version}), libphobos-4.8-dev (= ${gdc:Version}), ${misc:Depends} Provides: libphobos-dbg diff -u gcc-4.8-4.8.2/debian/control.m4 gcc-4.8-4.8.2/debian/control.m4 --- gcc-4.8-4.8.2/debian/control.m4 +++ gcc-4.8-4.8.2/debian/control.m4 @@ -51,7 +51,7 @@ ', `dnl Uploaders: Matthias Klose ')dnl SRCNAME -Standards-Version: 3.9.5 +Standards-Version: 3.9.4 ifdef(`TARGET',`dnl cross Build-Depends: debhelper (>= 5.0.62), LIBC_BUILD_DEP, LIBC_BIARCH_BUILD_DEP @@ -136,7 +136,7 @@ Priority: PRI(required) Depends: ${misc:Depends} Replaces: ${base:Replaces} -Breaks: gcc-4.4-base (<< 4.4.7), gcj-4.4-base (<< 4.4.6-9~), gnat-4.4-base (<< 4.4.6-3~), gcj-4.6-base (<< 4.6.1-4~), gnat-4.6 (<< 4.6.1-5~), gcc-4.7-base (<< 4.7.3), dehydra (<= 0.9.hg20110609-2) +Breaks: gcc-4.4-base (<< 4.4.7), gcj-4.4-base (<< 4.4.6-9~), gnat-4.4-base (<< 4.4.6-3~), gcj-4.6-base (<< 4.6.1-4~), gnat-4.6 (<< 4.6.1-5~), dehydra (<= 0.9.hg20110609-2) BUILT_USING`'dnl Description: GCC, the GNU Compiler Collection (base package) This package contains files common to all languages and libraries @@ -204,7 +204,7 @@ ')`'dnl java ifenabled(`ada',` -Package: gnat`'PV-base`'TS +Package: gnat`'PV-base Architecture: any Section: libs Priority: PRI(optional) @@ -702,12 +702,10 @@ Priority: ifdef(`TARGET',`extra',`PRI(optional)') Depends: cpp`'PV`'TS (= ${gcc:Version}),ifenabled(`gccbase',` BASEDEP,') binutils`'TS (>= ${binutils:Version}), - libdevdep(gcc`'PV-dev`',), ${shlibs:Depends}, ${misc:Depends} + depifenabled(`libgcc',`libdevdep(gcc`'PV-dev`',), ')${shlibs:Depends}, ${misc:Depends} Recommends: ${dep:libcdev} Suggests: ${gcc:multilib}, gcc`'PV-doc (>= ${gcc:SoftVersion}), gcc`'PV-locales (>= ${gcc:SoftVersion}), libdbgdep(gcc`'GCC_SO-dbg,,>=,${libgcc:Version}), libdbgdep(gomp`'GOMP_SO-dbg,), libdbgdep(itm`'ITM_SO-dbg,), libdbgdep(atomic`'ATOMIC_SO-dbg,), libdbgdep(asan`'ASAN_SO-dbg,), libdbgdep(tsan`'TSAN_SO-dbg,), libdbgdep(backtrace`'BTRACE_SO-dbg,), libdbgdep(quadmath`'QMATH_SO-dbg,), ${dep:libcloog}, ${dep:gold} Provides: c-compiler`'TS -ifdef(`TARGET',`Conflicts: gcc-multilib -')`'dnl BUILT_USING`'dnl Description: GNU C compiler`'ifdef(`TARGET)',` (cross compiler for TARGET architecture)', `') This is the GNU C compiler, a fairly portable optimizing compiler for C. @@ -1483,7 +1481,7 @@ Package: lib32asan`'ASAN_SO`'LS Section: ifdef(`TARGET',`devel',`libs') Architecture: ifdef(`TARGET',`CROSS_ARCH',`biarch32_archs') -Priority: ifdef(`TARGET',`extra',`PRI(optional)') +Priority: ifdef(`TARGET',`extra',`PRI(extra)') Depends: BASEDEP, ${dep:libcbiarch}, ${shlibs:Depends}, ${misc:Depends} Conflicts: ${confl:lib32} BUILT_USING`'dnl @@ -1504,7 +1502,7 @@ Package: lib64asan`'ASAN_SO`'LS Section: ifdef(`TARGET',`devel',`libs') Architecture: ifdef(`TARGET',`CROSS_ARCH',`biarch64_archs') -Priority: ifdef(`TARGET',`extra',`PRI(optional)') +Priority: ifdef(`TARGET',`extra',`PRI(extra)') Depends: BASEDEP, ${dep:libcbiarch}, ${shlibs:Depends}, ${misc:Depends} BUILT_USING`'dnl Description: AddressSanitizer -- a fast memory error detector (64bit) @@ -1545,7 +1543,7 @@ Package: libx32asan`'ASAN_SO`'LS Section: ifdef(`TARGET',`devel',`libs') Architecture: ifdef(`TARGET',`CROSS_ARCH',`biarchx32_archs') -Priority: ifdef(`TARGET',`extra',`PRI(optional)') +Priority: ifdef(`TARGET',`extra',`PRI(extra)') Depends: BASEDEP, ${dep:libcbiarch}, ${shlibs:Depends}, ${misc:Depends} BUILT_USING`'dnl Description: AddressSanitizer -- a fast memory error detector (x32) @@ -3093,7 +3091,7 @@ ifdef(`MULTIARCH', `Multi-Arch: same ')`'dnl Priority: PRI(optional) -Depends: BASEDEP, libdep(gcj`'LIBGCJ_EXT-awt,,=,${gcj:Version}), libgcj-bc`'LS, ${pkg:gcjgtk}, ${pkg:gcjqt}, zlib1g-dev, ${shlibs:Depends}, ${misc:Depends} +Depends: BASEDEP, gcj`'PV-jdk`'TS (= ${gcj:Version}), gcj`'PV-jre-lib`'TS (>= ${gcj:SoftVersion}), libdep(gcj`'LIBGCJ_EXT-awt,,=,${gcj:Version}), libgcj-bc`'LS, ${pkg:gcjgtk}, ${pkg:gcjqt}, zlib1g-dev, ${shlibs:Depends}, ${misc:Depends} Suggests: libgcj-doc BUILT_USING`'dnl Description: Java development headers for use with gcj @@ -3643,12 +3641,12 @@ ')`'dnl c++ ifenabled(`ada',` -Package: gnat`'-GNAT_V`'TS +Package: gnat`'-GNAT_V Architecture: any -Priority: ifdef(`TARGET',`extra',`PRI(optional)') +Priority: PRI(optional) ifdef(`MULTIARCH', `Pre-Depends: multiarch-support ')`'dnl -Depends: BASEDEP, gcc`'PV`'TS (>= ${gcc:SoftVersion}), ${dep:libgnat}, ${dep:libcdev}, ${shlibs:Depends}, ${misc:Depends} +Depends: BASEDEP, gcc`'PV (>= ${gcc:SoftVersion}), ${dep:libgnat}, ${dep:libcdev}, ${shlibs:Depends}, ${misc:Depends} Suggests: gnat`'PV-doc, ada-reference-manual-html, ada-reference-manual-info, ada-reference-manual-pdf, ada-reference-manual-text, gnat`'-GNAT_V-sjlj Conflicts: gnat (<< 4.1), gnat-3.1, gnat-3.2, gnat-3.3, gnat-3.4, gnat-3.5, gnat-4.0, gnat-4.1, gnat-4.2, gnat-4.3, gnat-4.4, gnat-4.6 BUILT_USING`'dnl @@ -3659,12 +3657,12 @@ This package provides the compiler, tools and runtime library that handles exceptions using the default zero-cost mechanism. -Package: gnat`'-GNAT_V-sjlj`'TS +Package: gnat`'-GNAT_V-sjlj Architecture: any Priority: extra ifdef(`MULTIARCH', `Pre-Depends: multiarch-support ')`'dnl -Depends: BASEDEP, gnat`'-GNAT_V`'TS (= ${gnat:Version}), ${misc:Depends} +Depends: BASEDEP, gnat`'-GNAT_V (= ${gnat:Version}), ${misc:Depends} BUILT_USING`'dnl Description: GNU Ada compiler (setjump/longjump runtime library) GNAT is a compiler for the Ada programming language. It produces optimized @@ -3675,9 +3673,9 @@ only). You can install it to supplement the normal compiler. ifenabled(`libgnat',` -Package: libgnat`'-GNAT_V`'LS -Section: ifdef(`TARGET',`devel',`libs') -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Package: libgnat`'-GNAT_V +Section: libs +Architecture: any ifdef(`TARGET',`dnl',ifdef(`MULTIARCH', `Multi-Arch: same Pre-Depends: multiarch-support '))`'dnl @@ -3693,14 +3691,14 @@ . This package contains the runtime shared library. -Package: libgnat`'-GNAT_V-dbg`'LS +Package: libgnat`'-GNAT_V-dbg Section: debug -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Architecture: any ifdef(`TARGET',`dnl',ifdef(`MULTIARCH', `Multi-Arch: same Pre-Depends: multiarch-support '))`'dnl Priority: extra -Depends: BASEDEP, libgnat`'-GNAT_V`'LS (= ${gnat:Version}), ${misc:Depends} +Depends: BASEDEP, libgnat`'-GNAT_V (= ${gnat:Version}), ${misc:Depends} BUILT_USING`'dnl Description: runtime for applications compiled with GNAT (debugging symbols) GNAT is a compiler for the Ada programming language. It produces optimized @@ -3711,12 +3709,12 @@ . This package contains the debugging symbols. -Package: libgnatvsn`'GNAT_V-dev`'LS +Package: libgnatvsn`'GNAT_V-dev Section: libdevel -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Architecture: any Priority: extra -Depends: BASEDEP, gnat`'PV`'LS (= ${gnat:Version}), - libgnatvsn`'GNAT_V`'LS (= ${gnat:Version}), ${misc:Depends} +Depends: BASEDEP, gnat`'PV (= ${gnat:Version}), + libgnatvsn`'GNAT_V (= ${gnat:Version}), ${misc:Depends} Conflicts: libgnatvsn-dev (<< `'GNAT_V), libgnatvsn4.1-dev, libgnatvsn4.3-dev, libgnatvsn4.4-dev, libgnatvsn4.5-dev, libgnatvsn4.6-dev BUILT_USING`'dnl Description: GNU Ada compiler selected components (development files) @@ -3729,14 +3727,14 @@ . This package contains the development files and static library. -Package: libgnatvsn`'GNAT_V`'LS -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Package: libgnatvsn`'GNAT_V +Architecture: any ifdef(`TARGET',`dnl',ifdef(`MULTIARCH', `Multi-Arch: same Pre-Depends: multiarch-support '))`'dnl Priority: PRI(optional) -Section: ifdef(`TARGET',`devel',`libs') -Depends: BASEDEP, libgnat`'-GNAT_V`'LS (= ${gnat:Version}), ${misc:Depends} +Section: libs +Depends: BASEDEP, libgnat`'-GNAT_V (= ${gnat:Version}), ${misc:Depends} BUILT_USING`'dnl Description: GNU Ada compiler selected components (shared library) GNAT is a compiler for the Ada programming language. It produces optimized @@ -3748,14 +3746,14 @@ . This package contains the runtime shared library. -Package: libgnatvsn`'GNAT_V-dbg`'LS -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Package: libgnatvsn`'GNAT_V-dbg +Architecture: any ifdef(`TARGET',`dnl',ifdef(`MULTIARCH', `Multi-Arch: same Pre-Depends: multiarch-support '))`'dnl Priority: extra Section: debug -Depends: BASEDEP, libgnatvsn`'GNAT_V`'LS (= ${gnat:Version}), ${misc:Depends} +Depends: BASEDEP, libgnatvsn`'GNAT_V (= ${gnat:Version}), ${misc:Depends} Suggests: gnat BUILT_USING`'dnl Description: GNU Ada compiler selected components (debugging symbols) @@ -3768,13 +3766,12 @@ . This package contains the debugging symbols. -Package: libgnatprj`'GNAT_V-dev`'LS +Package: libgnatprj`'GNAT_V-dev Section: libdevel -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Architecture: any Priority: extra -Depends: BASEDEP, gnat`'PV`'TS (= ${gnat:Version}), - libgnatprj`'GNAT_V`'LS (= ${gnat:Version}), - libgnatvsn`'GNAT_V-dev`'LS (= ${gnat:Version}), ${misc:Depends} +Depends: BASEDEP, gnat`'PV (= ${gnat:Version}), + libgnatprj`'GNAT_V (= ${gnat:Version}), libgnatvsn`'GNAT_V-dev (= ${gnat:Version}), ${misc:Depends} Conflicts: libgnatprj-dev (<< `'GNAT_V), libgnatprj4.1-dev, libgnatprj4.3-dev, libgnatprj4.4-dev, libgnatprj4.5-dev, libgnatprj4.6-dev BUILT_USING`'dnl Description: GNU Ada compiler Project Manager (development files) @@ -3790,14 +3787,14 @@ . This package contains the development files and static library. -Package: libgnatprj`'GNAT_V`'LS -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Package: libgnatprj`'GNAT_V +Architecture: any ifdef(`TARGET',`dnl',ifdef(`MULTIARCH', `Multi-Arch: same Pre-Depends: multiarch-support '))`'dnl Priority: PRI(optional) -Section: ifdef(`TARGET',`devel',`libs') -Depends: BASEDEP, libgnat`'-GNAT_V`'LS (= ${gnat:Version}), libgnatvsn`'GNAT_V`'LS (= ${gnat:Version}), ${misc:Depends} +Section: libs +Depends: BASEDEP, libgnat`'-GNAT_V (= ${gnat:Version}), libgnatvsn`'GNAT_V (= ${gnat:Version}), ${misc:Depends} BUILT_USING`'dnl Description: GNU Ada compiler Project Manager (shared library) GNAT is a compiler for the Ada programming language. It produces optimized @@ -3812,14 +3809,14 @@ . This package contains the runtime shared library. -Package: libgnatprj`'GNAT_V-dbg`'LS -Architecture: ifdef(`TARGET',`CROSS_ARCH',`any') +Package: libgnatprj`'GNAT_V-dbg +Architecture: any ifdef(`TARGET',`dnl',ifdef(`MULTIARCH', `Multi-Arch: same Pre-Depends: multiarch-support '))`'dnl Priority: extra Section: debug -Depends: BASEDEP, libgnatprj`'GNAT_V`'LS (= ${gnat:Version}), ${misc:Depends} +Depends: BASEDEP, libgnatprj`'GNAT_V (= ${gnat:Version}), ${misc:Depends} Suggests: gnat BUILT_USING`'dnl Description: GNU Ada compiler Project Manager (debugging symbols) @@ -3894,7 +3891,6 @@ Priority: PRI(optional) Depends: BASEDEP, zlib1g-dev, ${shlibs:Depends}, ${misc:Depends} Provides: libphobos-dev -Replaces: gdc`'PV`'TS (<< 4.8.2-19) BUILT_USING`'dnl Description: Phobos D standard library This is the Phobos standard library that comes with the D2 compiler. reverted: --- gcc-4.8-4.8.2/debian/cpp-4.8-powerpc64le-linux-gnu.preinst +++ gcc-4.8-4.8.2.orig/debian/cpp-4.8-powerpc64le-linux-gnu.preinst @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -if [ "$1" = "upgrade" ] || [ "$1" = "configure" ]; then - update-alternatives --quiet --remove powerpc64le-linux-gnu-cpp /usr/bin/powerpc64le-linux-gnu-cpp-4.8 -fi - -#DEBHELPER# - -exit 0 reverted: --- gcc-4.8-4.8.2/debian/g++-4.8-powerpc64le-linux-gnu.preinst +++ gcc-4.8-4.8.2.orig/debian/g++-4.8-powerpc64le-linux-gnu.preinst @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -if [ "$1" = "upgrade" ] || [ "$1" = "configure" ]; then - update-alternatives --quiet --remove powerpc64le-linux-gnu-g++ /usr/bin/powerpc64le-linux-gnu-g++-4.8 -fi - -#DEBHELPER# - -exit 0 reverted: --- gcc-4.8-4.8.2/debian/gcc-4.8-powerpc64le-linux-gnu.preinst +++ gcc-4.8-4.8.2.orig/debian/gcc-4.8-powerpc64le-linux-gnu.preinst @@ -1,12 +0,0 @@ -#!/bin/sh - -set -e - -if [ "$1" = "upgrade" ] || [ "$1" = "configure" ]; then - update-alternatives --quiet --remove powerpc64le-linux-gnu-gcc /usr/bin/powerpc64le-linux-gnu-gcc-4.8 - update-alternatives --quiet --remove powerpc64le-linux-gnu-gcov /usr/bin/powerpc64le-linux-gnu-gcov-4.8 -fi - -#DEBHELPER# - -exit 0 reverted: --- gcc-4.8-4.8.2/debian/gfortran-4.8-powerpc64le-linux-gnu.preinst +++ gcc-4.8-4.8.2.orig/debian/gfortran-4.8-powerpc64le-linux-gnu.preinst @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -if [ "$1" = "upgrade" ] || [ "$1" = "configure" ]; then - update-alternatives --quiet --remove powerpc64le-linux-gnu-gfortran /usr/bin/powerpc64le-linux-gnu-gfortran-4.8 -fi - -#DEBHELPER# - -exit 0 diff -u gcc-4.8-4.8.2/debian/gij-hppa gcc-4.8-4.8.2/debian/gij-hppa --- gcc-4.8-4.8.2/debian/gij-hppa +++ gcc-4.8-4.8.2/debian/gij-hppa @@ -10 +10,11 @@ -exec $prctl /usr/bin/gij-4.8.bin "$@" +exec $prctl /usr/bin/gij-4.4.bin "$@" +#! /bin/sh + +prctl= + +case "$(prctl --unaligned=)" in *signal) + echo >&2 "$(basename $0): ignore unaligned memory accesses" + prctl="prctl --unaligned=default" +esac + +exec $prctl /usr/bin/gij-4.4.bin "$@" diff -u gcc-4.8-4.8.2/debian/lib32itm1.symbols gcc-4.8-4.8.2/debian/lib32itm1.symbols --- gcc-4.8-4.8.2/debian/lib32itm1.symbols +++ gcc-4.8-4.8.2/debian/lib32itm1.symbols @@ -4 +3,0 @@ -(arch=amd64 i386 x32)#include "libitm1.symbols.x86" diff -u gcc-4.8-4.8.2/debian/lib64itm1.symbols gcc-4.8-4.8.2/debian/lib64itm1.symbols --- gcc-4.8-4.8.2/debian/lib64itm1.symbols +++ gcc-4.8-4.8.2/debian/lib64itm1.symbols @@ -4 +3,0 @@ -(arch=amd64 i386 x32)#include "libitm1.symbols.x86" diff -u gcc-4.8-4.8.2/debian/libatomic1.symbols gcc-4.8-4.8.2/debian/libatomic1.symbols --- gcc-4.8-4.8.2/debian/libatomic1.symbols +++ gcc-4.8-4.8.2/debian/libatomic1.symbols @@ -3 +3 @@ -(arch=arm64 alpha amd64 ia64 ppc64 ppc64el s390x sparc64 x32 kfreebsd-amd64)#include "libatomic1.symbols.64" +(arch=aarch64 alpha amd64 ia64 ppc64 s390x sparc64 x32 kfreebsd-amd64)#include "libatomic1.symbols.64" reverted: --- gcc-4.8-4.8.2/debian/libgcc1.symbols.arm64 +++ gcc-4.8-4.8.2.orig/debian/libgcc1.symbols.arm64 @@ -1,134 +0,0 @@ -libgcc_s.so.1 libgcc1 #MINVER# - GCC_3.0@GCC_3.0 1:4.7 - GCC_3.3.1@GCC_3.3.1 1:4.7 - GCC_3.3@GCC_3.3 1:4.7 - GCC_3.4.2@GCC_3.4.2 1:4.7 - GCC_3.4.4@GCC_3.4.4 1:4.7 - GCC_3.4@GCC_3.4 1:4.7 - GCC_4.0.0@GCC_4.0.0 1:4.7 - GCC_4.2.0@GCC_4.2.0 1:4.7 - GCC_4.3.0@GCC_4.3.0 1:4.7 - GCC_4.5.0@GCC_4.5.0 1:4.7 - GCC_4.7.0@GCC_4.7.0 1:4.7 - GLIBC_2.0@GLIBC_2.0 1:4.7 - _Unwind_Backtrace@GCC_3.3 1:4.7 - _Unwind_DeleteException@GCC_3.0 1:4.7 - _Unwind_FindEnclosingFunction@GCC_3.3 1:4.7 - _Unwind_Find_FDE@GCC_3.0 1:4.7 - _Unwind_ForcedUnwind@GCC_3.0 1:4.7 - _Unwind_GetCFA@GCC_3.3 1:4.7 - _Unwind_GetDataRelBase@GCC_3.0 1:4.7 - _Unwind_GetGR@GCC_3.0 1:4.7 - _Unwind_GetIP@GCC_3.0 1:4.7 - _Unwind_GetIPInfo@GCC_4.2.0 1:4.7 - _Unwind_GetLanguageSpecificData@GCC_3.0 1:4.7 - _Unwind_GetRegionStart@GCC_3.0 1:4.7 - _Unwind_GetTextRelBase@GCC_3.0 1:4.7 - _Unwind_RaiseException@GCC_3.0 1:4.7 - _Unwind_Resume@GCC_3.0 1:4.7 - _Unwind_Resume_or_Rethrow@GCC_3.3 1:4.7 - _Unwind_SetGR@GCC_3.0 1:4.7 - _Unwind_SetIP@GCC_3.0 1:4.7 - __absvdi2@GCC_3.0 1:4.7 - __absvsi2@GCC_3.0 1:4.7 - __absvti2@GCC_3.4.4 1:4.7 - __addtf3@GCC_3.0 1:4.7 - __addvdi3@GCC_3.0 1:4.7 - __addvsi3@GCC_3.0 1:4.7 - __addvti3@GCC_3.4.4 1:4.7 - __ashlti3@GCC_3.0 1:4.7 - __ashrti3@GCC_3.0 1:4.7 - __bswapdi2@GCC_4.3.0 1:4.7 - __bswapsi2@GCC_4.3.0 1:4.7 - __clear_cache@GCC_3.0 1:4.7 - __clrsbdi2@GCC_4.7.0 1:4.7 - __clrsbti2@GCC_4.7.0 1:4.7 - __clzdi2@GCC_3.4 1:4.7 - __clzti2@GCC_3.4 1:4.7 - __cmpti2@GCC_3.0 1:4.7 - __ctzdi2@GCC_3.4 1:4.7 - __ctzti2@GCC_3.4 1:4.7 - __deregister_frame@GLIBC_2.0 1:4.7 - __deregister_frame_info@GLIBC_2.0 1:4.7 - __deregister_frame_info_bases@GCC_3.0 1:4.7 - __divdc3@GCC_4.0.0 1:4.7 - __divsc3@GCC_4.0.0 1:4.7 - __divtc3@GCC_4.0.0 1:4.7 - __divtf3@GCC_3.0 1:4.7 - __divti3@GCC_3.0 1:4.7 - __emutls_get_address@GCC_4.3.0 1:4.7 - __emutls_register_common@GCC_4.3.0 1:4.7 - __enable_execute_stack@GCC_3.4.2 1:4.7 - __eqtf2@GCC_3.0 1:4.7 - __extenddftf2@GCC_3.0 1:4.7 - __extendsftf2@GCC_3.0 1:4.7 - __ffsdi2@GCC_3.0 1:4.7 - __ffsti2@GCC_3.0 1:4.7 - __fixdfti@GCC_3.0 1:4.7 - __fixsfti@GCC_3.0 1:4.7 - __fixtfdi@GCC_3.0 1:4.7 - __fixtfsi@GCC_3.0 1:4.7 - __fixtfti@GCC_3.0 1:4.7 - __fixunsdfdi@GCC_3.0 1:4.7 - __fixunsdfti@GCC_3.0 1:4.7 - __fixunssfdi@GCC_3.0 1:4.7 - __fixunssfti@GCC_3.0 1:4.7 - __fixunstfdi@GCC_3.0 1:4.7 - __fixunstfsi@GCC_3.0 1:4.7 - __fixunstfti@GCC_3.0 1:4.7 - __floatditf@GCC_3.0 1:4.7 - __floatsitf@GCC_3.0 1:4.7 - __floattidf@GCC_3.0 1:4.7 - __floattisf@GCC_3.0 1:4.7 - __floattitf@GCC_3.0 1:4.7 - __floatunditf@GCC_4.2.0 1:4.7 - __floatunsitf@GCC_4.2.0 1:4.7 - __floatuntidf@GCC_4.2.0 1:4.7 - __floatuntisf@GCC_4.2.0 1:4.7 - __floatuntitf@GCC_4.2.0 1:4.7 - __frame_state_for@GLIBC_2.0 1:4.7 - __gcc_personality_v0@GCC_3.3.1 1:4.7 - __getf2@GCC_3.0 1:4.7 - __gttf2@GCC_3.0 1:4.7 - __letf2@GCC_3.0 1:4.7 - __lshrti3@GCC_3.0 1:4.7 - __lttf2@GCC_3.0 1:4.7 - __modti3@GCC_3.0 1:4.7 - __muldc3@GCC_4.0.0 1:4.7 - __mulsc3@GCC_4.0.0 1:4.7 - __multc3@GCC_4.0.0 1:4.7 - __multf3@GCC_3.0 1:4.7 - __multi3@GCC_3.0 1:4.7 - __mulvdi3@GCC_3.0 1:4.7 - __mulvsi3@GCC_3.0 1:4.7 - __mulvti3@GCC_3.4.4 1:4.7 - __negtf2@GCC_3.0 1:4.7 - __negti2@GCC_3.0 1:4.7 - __negvdi2@GCC_3.0 1:4.7 - __negvsi2@GCC_3.0 1:4.7 - __negvti2@GCC_3.4.4 1:4.7 - __netf2@GCC_3.0 1:4.7 - __paritydi2@GCC_3.4 1:4.7 - __parityti2@GCC_3.4 1:4.7 - __popcountdi2@GCC_3.4 1:4.7 - __popcountti2@GCC_3.4 1:4.7 - __powidf2@GCC_4.0.0 1:4.7 - __powisf2@GCC_4.0.0 1:4.7 - __powitf2@GCC_4.0.0 1:4.7 - __register_frame@GLIBC_2.0 1:4.7 - __register_frame_info@GLIBC_2.0 1:4.7 - __register_frame_info_bases@GCC_3.0 1:4.7 - __register_frame_info_table@GLIBC_2.0 1:4.7 - __register_frame_info_table_bases@GCC_3.0 1:4.7 - __register_frame_table@GLIBC_2.0 1:4.7 - __subtf3@GCC_3.0 1:4.7 - __subvdi3@GCC_3.0 1:4.7 - __subvsi3@GCC_3.0 1:4.7 - __subvti3@GCC_3.4.4 1:4.7 - __trunctfdf2@GCC_3.0 1:4.7 - __trunctfsf2@GCC_3.0 1:4.7 - __ucmpti2@GCC_3.0 1:4.7 - __udivmodti4@GCC_3.0 1:4.7 - __udivti3@GCC_3.0 1:4.7 - __umodti3@GCC_3.0 1:4.7 - __unordtf2@GCC_4.5.0 1:4.7 reverted: --- gcc-4.8-4.8.2/debian/libgcc1.symbols.ppc64el +++ gcc-4.8-4.8.2.orig/debian/libgcc1.symbols.ppc64el @@ -1,130 +0,0 @@ -libgcc_s.so.1 libgcc1 #MINVER# - GCC_3.0@GCC_3.0 1:4.1.1 - GCC_3.3.1@GCC_3.3.1 1:4.1.1 - GCC_3.3@GCC_3.3 1:4.1.1 - GCC_3.4.2@GCC_3.4.2 1:4.1.1 - GCC_3.4.4@GCC_3.4.4 1:4.1.1 - GCC_3.4@GCC_3.4 1:4.1.1 - GCC_4.0.0@GCC_4.0.0 1:4.1.1 - GCC_4.2.0@GCC_4.2.0 1:4.1.1 - GCC_4.3.0@GCC_4.3.0 1:4.3 - GCC_4.7.0@GCC_4.7.0 1:4.7 - GLIBC_2.0@GLIBC_2.0 1:4.1.1 - _Unwind_Backtrace@GCC_3.3 1:4.1.1 - _Unwind_DeleteException@GCC_3.0 1:4.1.1 - _Unwind_FindEnclosingFunction@GCC_3.3 1:4.1.1 - _Unwind_Find_FDE@GCC_3.0 1:4.1.1 - _Unwind_ForcedUnwind@GCC_3.0 1:4.1.1 - _Unwind_GetCFA@GCC_3.3 1:4.1.1 - _Unwind_GetDataRelBase@GCC_3.0 1:4.1.1 - _Unwind_GetGR@GCC_3.0 1:4.1.1 - _Unwind_GetIP@GCC_3.0 1:4.1.1 - _Unwind_GetIPInfo@GCC_4.2.0 1:4.1.1 - _Unwind_GetLanguageSpecificData@GCC_3.0 1:4.1.1 - _Unwind_GetRegionStart@GCC_3.0 1:4.1.1 - _Unwind_GetTextRelBase@GCC_3.0 1:4.1.1 - _Unwind_RaiseException@GCC_3.0 1:4.1.1 - _Unwind_Resume@GCC_3.0 1:4.1.1 - _Unwind_Resume_or_Rethrow@GCC_3.3 1:4.1.1 - _Unwind_SetGR@GCC_3.0 1:4.1.1 - _Unwind_SetIP@GCC_3.0 1:4.1.1 - __absvdi2@GCC_3.0 1:4.1.1 - __absvsi2@GCC_3.0 1:4.1.1 - __absvti2@GCC_3.4.4 1:4.1.1 - __addvdi3@GCC_3.0 1:4.1.1 - __addvsi3@GCC_3.0 1:4.1.1 - __addvti3@GCC_3.4.4 1:4.1.1 - __ashlti3@GCC_3.0 1:4.1.1 - __ashrti3@GCC_3.0 1:4.1.1 - __bswapdi2@GCC_4.3.0 1:4.3 - __bswapsi2@GCC_4.3.0 1:4.3 - __clear_cache@GCC_3.0 1:4.1.1 - __clrsbdi2@GCC_4.7.0 1:4.7 - __clrsbti2@GCC_4.7.0 1:4.7 - __clzdi2@GCC_3.4 1:4.1.1 - __clzti2@GCC_3.4 1:4.1.1 - __cmpti2@GCC_3.0 1:4.1.1 - __ctzdi2@GCC_3.4 1:4.1.1 - __ctzti2@GCC_3.4 1:4.1.1 - __deregister_frame@GLIBC_2.0 1:4.1.1 - __deregister_frame_info@GLIBC_2.0 1:4.1.1 - __deregister_frame_info_bases@GCC_3.0 1:4.1.1 - __divdc3@GCC_4.0.0 1:4.1.1 - __divsc3@GCC_4.0.0 1:4.1.1 - __divtc3@GCC_4.0.0 1:4.1.1 - __divti3@GCC_3.0 1:4.1.1 - __emutls_get_address@GCC_4.3.0 1:4.3 - __emutls_register_common@GCC_4.3.0 1:4.3 - __enable_execute_stack@GCC_3.4.2 1:4.1.1 - __ffsdi2@GCC_3.0 1:4.1.1 - __ffsti2@GCC_3.0 1:4.1.1 - __fixdfdi@GCC_3.0 1:4.1.1 - __fixdfti@GCC_3.0 1:4.1.1 - __fixsfdi@GCC_3.0 1:4.1.1 - __fixsfti@GCC_3.0 1:4.1.1 - __fixtfdi@GCC_3.0 1:4.1.1 - __fixtfti@GCC_3.0 1:4.1.1 - __fixunsdfdi@GCC_3.0 1:4.1.1 - __fixunsdfsi@GCC_3.0 1:4.1.1 - __fixunsdfti@GCC_3.0 1:4.1.1 - __fixunssfdi@GCC_3.0 1:4.1.1 - __fixunssfsi@GCC_3.0 1:4.1.1 - __fixunssfti@GCC_3.0 1:4.1.1 - __fixunstfdi@GCC_3.0 1:4.1.1 - __fixunstfti@GCC_3.0 1:4.1.1 - __floatdidf@GCC_3.0 1:4.1.1 - __floatdisf@GCC_3.0 1:4.1.1 - __floatditf@GCC_3.0 1:4.1.1 - __floattidf@GCC_3.0 1:4.1.1 - __floattisf@GCC_3.0 1:4.1.1 - __floattitf@GCC_3.0 1:4.1.1 - __floatundidf@GCC_4.2.0 1:4.2.1 - __floatundisf@GCC_4.2.0 1:4.2.1 - __floatunditf@GCC_4.2.0 1:4.2.1 - __floatuntidf@GCC_4.2.0 1:4.2.1 - __floatuntisf@GCC_4.2.0 1:4.2.1 - __floatuntitf@GCC_4.2.0 1:4.2.1 - __frame_state_for@GLIBC_2.0 1:4.1.1 - __gcc_personality_v0@GCC_3.3.1 1:4.1.1 - __gcc_qadd@GCC_3.4.4 1:4.1.1 - __gcc_qdiv@GCC_3.4.4 1:4.1.1 - __gcc_qmul@GCC_3.4.4 1:4.1.1 - __gcc_qsub@GCC_3.4.4 1:4.1.1 - __lshrti3@GCC_3.0 1:4.1.1 - __modti3@GCC_3.0 1:4.1.1 - __muldc3@GCC_4.0.0 1:4.1.1 - __mulsc3@GCC_4.0.0 1:4.1.1 - __multc3@GCC_4.0.0 1:4.1.1 - __multi3@GCC_3.0 1:4.1.1 - __mulvdi3@GCC_3.0 1:4.1.1 - __mulvsi3@GCC_3.0 1:4.1.1 - __mulvti3@GCC_3.4.4 1:4.1.1 - __negti2@GCC_3.0 1:4.1.1 - __negvdi2@GCC_3.0 1:4.1.1 - __negvsi2@GCC_3.0 1:4.1.1 - __negvti2@GCC_3.4.4 1:4.1.1 - __paritydi2@GCC_3.4 1:4.1.1 - __parityti2@GCC_3.4 1:4.1.1 - __popcountdi2@GCC_3.4 1:4.1.1 - __popcountti2@GCC_3.4 1:4.1.1 - __powidf2@GCC_4.0.0 1:4.1.1 - __powisf2@GCC_4.0.0 1:4.1.1 - __powitf2@GCC_4.0.0 1:4.1.1 - __register_frame@GLIBC_2.0 1:4.1.1 - __register_frame_info@GLIBC_2.0 1:4.1.1 - __register_frame_info_bases@GCC_3.0 1:4.1.1 - __register_frame_info_table@GLIBC_2.0 1:4.1.1 - __register_frame_info_table_bases@GCC_3.0 1:4.1.1 - __register_frame_table@GLIBC_2.0 1:4.1.1 - __subvdi3@GCC_3.0 1:4.1.1 - __subvsi3@GCC_3.0 1:4.1.1 - __subvti3@GCC_3.4.4 1:4.1.1 - __trampoline_setup@GCC_3.4.2 1:4.8 - __ucmpti2@GCC_3.0 1:4.1.1 - __udivmodti4@GCC_3.0 1:4.1.1 - __udivti3@GCC_3.0 1:4.1.1 - __umodti3@GCC_3.0 1:4.1.1 - _xlqadd@GCC_3.4 1:4.1.1 - _xlqdiv@GCC_3.4 1:4.1.1 - _xlqmul@GCC_3.4 1:4.1.1 - _xlqsub@GCC_3.4 1:4.1.1 reverted: --- gcc-4.8-4.8.2/debian/libgfortran3.symbols.arm64 +++ gcc-4.8-4.8.2.orig/debian/libgfortran3.symbols.arm64 @@ -1,5 +0,0 @@ -libgfortran.so.3 libgfortran3 #MINVER# -#include "libgfortran3.symbols.common" -#include "libgfortran3.symbols.64" -#include "libgfortran3.symbols.16.powerpc" -#include "libgfortran3.symbols.16.powerpc64" reverted: --- gcc-4.8-4.8.2/debian/libgfortran3.symbols.ppc64el +++ gcc-4.8-4.8.2.orig/debian/libgfortran3.symbols.ppc64el @@ -1,5 +0,0 @@ -libgfortran.so.3 libgfortran3 #MINVER# -#include "libgfortran3.symbols.common" -#include "libgfortran3.symbols.16.powerpc" -#include "libgfortran3.symbols.16.powerpc64" -#include "libgfortran3.symbols.64" diff -u gcc-4.8-4.8.2/debian/libitm1.symbols gcc-4.8-4.8.2/debian/libitm1.symbols --- gcc-4.8-4.8.2/debian/libitm1.symbols +++ gcc-4.8-4.8.2/debian/libitm1.symbols @@ -3,3 +3,2 @@ -(arch=amd64 i386 x32)#include "libitm1.symbols.x86" -(arch=!alpha !amd64 !ia64 !ppc64 !ppc64el !s390x !sparc64 !kfreebsd-amd64)#include "libitm1.symbols.32bit" -(arch=alpha amd64 ia64 ppc64 ppc64el s390x sparc64 kfreebsd-amd64)#include "libitm1.symbols.64bit" +(arch=!alpha !amd64 !ia64 !ppc64 !s390x !sparc64 !kfreebsd-amd64)#include "libitm1.symbols.32bit" +(arch=alpha amd64 ia64 ppc64 s390x sparc64 kfreebsd-amd64)#include "libitm1.symbols.64bit" diff -u gcc-4.8-4.8.2/debian/libitm1.symbols.common gcc-4.8-4.8.2/debian/libitm1.symbols.common --- gcc-4.8-4.8.2/debian/libitm1.symbols.common +++ gcc-4.8-4.8.2/debian/libitm1.symbols.common @@ -6,6 +6,9 @@ _ITM_LD@LIBITM_1.0 4.7 _ITM_LE@LIBITM_1.0 4.7 _ITM_LF@LIBITM_1.0 4.7 + _ITM_LM128@LIBITM_1.0 4.7 + _ITM_LM256@LIBITM_1.0 4.7 + _ITM_LM64@LIBITM_1.0 4.7 _ITM_LU1@LIBITM_1.0 4.7 _ITM_LU2@LIBITM_1.0 4.7 _ITM_LU4@LIBITM_1.0 4.7 @@ -16,6 +19,9 @@ _ITM_RD@LIBITM_1.0 4.7 _ITM_RE@LIBITM_1.0 4.7 _ITM_RF@LIBITM_1.0 4.7 + _ITM_RM128@LIBITM_1.0 4.7 + _ITM_RM256@LIBITM_1.0 4.7 + _ITM_RM64@LIBITM_1.0 4.7 _ITM_RU1@LIBITM_1.0 4.7 _ITM_RU2@LIBITM_1.0 4.7 _ITM_RU4@LIBITM_1.0 4.7 @@ -26,6 +32,9 @@ _ITM_RaRD@LIBITM_1.0 4.7 _ITM_RaRE@LIBITM_1.0 4.7 _ITM_RaRF@LIBITM_1.0 4.7 + _ITM_RaRM128@LIBITM_1.0 4.7 + _ITM_RaRM256@LIBITM_1.0 4.7 + _ITM_RaRM64@LIBITM_1.0 4.7 _ITM_RaRU1@LIBITM_1.0 4.7 _ITM_RaRU2@LIBITM_1.0 4.7 _ITM_RaRU4@LIBITM_1.0 4.7 @@ -36,6 +45,9 @@ _ITM_RaWD@LIBITM_1.0 4.7 _ITM_RaWE@LIBITM_1.0 4.7 _ITM_RaWF@LIBITM_1.0 4.7 + _ITM_RaWM128@LIBITM_1.0 4.7 + _ITM_RaWM256@LIBITM_1.0 4.7 + _ITM_RaWM64@LIBITM_1.0 4.7 _ITM_RaWU1@LIBITM_1.0 4.7 _ITM_RaWU2@LIBITM_1.0 4.7 _ITM_RaWU4@LIBITM_1.0 4.7 @@ -46,6 +58,9 @@ _ITM_RfWD@LIBITM_1.0 4.7 _ITM_RfWE@LIBITM_1.0 4.7 _ITM_RfWF@LIBITM_1.0 4.7 + _ITM_RfWM128@LIBITM_1.0 4.7 + _ITM_RfWM256@LIBITM_1.0 4.7 + _ITM_RfWM64@LIBITM_1.0 4.7 _ITM_RfWU1@LIBITM_1.0 4.7 _ITM_RfWU2@LIBITM_1.0 4.7 _ITM_RfWU4@LIBITM_1.0 4.7 @@ -56,6 +71,9 @@ _ITM_WD@LIBITM_1.0 4.7 _ITM_WE@LIBITM_1.0 4.7 _ITM_WF@LIBITM_1.0 4.7 + _ITM_WM128@LIBITM_1.0 4.7 + _ITM_WM256@LIBITM_1.0 4.7 + _ITM_WM64@LIBITM_1.0 4.7 _ITM_WU1@LIBITM_1.0 4.7 _ITM_WU2@LIBITM_1.0 4.7 _ITM_WU4@LIBITM_1.0 4.7 @@ -66,6 +84,9 @@ _ITM_WaRD@LIBITM_1.0 4.7 _ITM_WaRE@LIBITM_1.0 4.7 _ITM_WaRF@LIBITM_1.0 4.7 + _ITM_WaRM128@LIBITM_1.0 4.7 + _ITM_WaRM256@LIBITM_1.0 4.7 + _ITM_WaRM64@LIBITM_1.0 4.7 _ITM_WaRU1@LIBITM_1.0 4.7 _ITM_WaRU2@LIBITM_1.0 4.7 _ITM_WaRU4@LIBITM_1.0 4.7 @@ -76,6 +97,9 @@ _ITM_WaWD@LIBITM_1.0 4.7 _ITM_WaWE@LIBITM_1.0 4.7 _ITM_WaWF@LIBITM_1.0 4.7 + _ITM_WaWM128@LIBITM_1.0 4.7 + _ITM_WaWM256@LIBITM_1.0 4.7 + _ITM_WaWM64@LIBITM_1.0 4.7 _ITM_WaWU1@LIBITM_1.0 4.7 _ITM_WaWU2@LIBITM_1.0 4.7 _ITM_WaWU4@LIBITM_1.0 4.7 reverted: --- gcc-4.8-4.8.2/debian/libitm1.symbols.x86 +++ gcc-4.8-4.8.2.orig/debian/libitm1.symbols.x86 @@ -1,24 +0,0 @@ - _ITM_LM128@LIBITM_1.0 4.7 - _ITM_LM256@LIBITM_1.0 4.7 - _ITM_LM64@LIBITM_1.0 4.7 - _ITM_RM128@LIBITM_1.0 4.7 - _ITM_RM256@LIBITM_1.0 4.7 - _ITM_RM64@LIBITM_1.0 4.7 - _ITM_RaRM128@LIBITM_1.0 4.7 - _ITM_RaRM256@LIBITM_1.0 4.7 - _ITM_RaRM64@LIBITM_1.0 4.7 - _ITM_RaWM128@LIBITM_1.0 4.7 - _ITM_RaWM256@LIBITM_1.0 4.7 - _ITM_RaWM64@LIBITM_1.0 4.7 - _ITM_RfWM128@LIBITM_1.0 4.7 - _ITM_RfWM256@LIBITM_1.0 4.7 - _ITM_RfWM64@LIBITM_1.0 4.7 - _ITM_WM128@LIBITM_1.0 4.7 - _ITM_WM256@LIBITM_1.0 4.7 - _ITM_WM64@LIBITM_1.0 4.7 - _ITM_WaRM128@LIBITM_1.0 4.7 - _ITM_WaRM256@LIBITM_1.0 4.7 - _ITM_WaRM64@LIBITM_1.0 4.7 - _ITM_WaWM128@LIBITM_1.0 4.7 - _ITM_WaWM256@LIBITM_1.0 4.7 - _ITM_WaWM64@LIBITM_1.0 4.7 diff -u gcc-4.8-4.8.2/debian/libstdc++6.symbols.64bit gcc-4.8-4.8.2/debian/libstdc++6.symbols.64bit --- gcc-4.8-4.8.2/debian/libstdc++6.symbols.64bit +++ gcc-4.8-4.8.2/debian/libstdc++6.symbols.64bit @@ -326,7 +326,7 @@ _ZNSt14collate_bynameIcEC2EPKcm@GLIBCXX_3.4 4.1.1 _ZNSt14collate_bynameIwEC1EPKcm@GLIBCXX_3.4 4.1.1 _ZNSt14collate_bynameIwEC2EPKcm@GLIBCXX_3.4 4.1.1 - (arch=!alpha !powerpc !ppc64 !ppc64el !s390 !s390x)_ZNSt14numeric_limitsIeE12max_digits10E@GLIBCXX_3.4.14 4.5.0 + (arch=!alpha !powerpc !ppc64 !s390 !s390x)_ZNSt14numeric_limitsIeE12max_digits10E@GLIBCXX_3.4.14 4.5.0 _ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@GLIBCXX_3.4 4.1.1 _ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_gbumpEl@GLIBCXX_3.4.16 4.6.0 _ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_pbumpEl@GLIBCXX_3.4.16 4.6.0 reverted: --- gcc-4.8-4.8.2/debian/libstdc++6.symbols.arm64 +++ gcc-4.8-4.8.2.orig/debian/libstdc++6.symbols.arm64 @@ -1,9 +0,0 @@ -libstdc++.so.6 libstdc++6 #MINVER# -#include "libstdc++6.symbols.64bit" -#include "libstdc++6.symbols.128bit" -#include "libstdc++6.symbols.excprop" - __gxx_personality_v0@CXXABI_1.3 4.1.1 - _ZNKSt3tr14hashIeEclEe@GLIBCXX_3.4.10 4.3.0 - _ZNKSt4hashIeEclEe@GLIBCXX_3.4.10 4.3.0 - _ZN9__gnu_cxx12__atomic_addEPVii@GLIBCXX_3.4 4.1.1 - _ZN9__gnu_cxx18__exchange_and_addEPVii@GLIBCXX_3.4 4.1.1 reverted: --- gcc-4.8-4.8.2/debian/libstdc++6.symbols.ppc64el +++ gcc-4.8-4.8.2.orig/debian/libstdc++6.symbols.ppc64el @@ -1,10 +0,0 @@ -libstdc++.so.6 libstdc++6 #MINVER# -#include "libstdc++6.symbols.64bit" -#include "libstdc++6.symbols.128bit" -#include "libstdc++6.symbols.excprop" - _ZN9__gnu_cxx12__atomic_addEPVii@GLIBCXX_3.4 4.1.1 - _ZN9__gnu_cxx18__exchange_and_addEPVii@GLIBCXX_3.4 4.1.1 -#include "libstdc++6.symbols.glibcxxmath" -#include "libstdc++6.symbols.ldbl.64bit" - _ZNKSt3tr14hashIeEclEe@GLIBCXX_3.4.10 4.3.0~rc2 - _ZNKSt4hashIeEclEe@GLIBCXX_3.4.10 4.3.0~rc2 reverted: --- gcc-4.8-4.8.2/debian/patches/aarch64-abi-fix.diff +++ gcc-4.8-4.8.2.orig/debian/patches/aarch64-abi-fix.diff @@ -1,16 +0,0 @@ -# DP: Proposed patch for PR /59799, allow passing arrays in registers on AArch64. - ---- a/src/gcc/config/aarch64/aarch64.c -+++ b/src/gcc/config/aarch64/aarch64.c -@@ -987,10 +987,7 @@ aarch64_pass_by_reference (cumulative_args_t pcum ATTRIBUTE_UNUSED, - - if (type) - { -- /* Arrays always passed by reference. */ -- if (TREE_CODE (type) == ARRAY_TYPE) -- return true; -- /* Other aggregates based on their size. */ -+ /* Aggregates based on their size. */ - if (AGGREGATE_TYPE_P (type)) - size = int_size_in_bytes (type); - } reverted: --- gcc-4.8-4.8.2/debian/patches/aarch64-call-frame-info.diff +++ gcc-4.8-4.8.2.orig/debian/patches/aarch64-call-frame-info.diff @@ -1,33 +0,0 @@ -# DP: Fix call frame information in ffi_closure_SYSV on AArch64. - -diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S -index 1022454..ecf6371 100644 ---- a/src/libffi/src/aarch64/sysv.S -+++ b/src/libffi/src/aarch64/sysv.S -@@ -231,13 +231,13 @@ ffi_closure_SYSV: - cfi_rel_offset (x30, 8) - - mov x29, sp -+ cfi_def_cfa_register (x29) - - sub sp, sp, #ffi_closure_SYSV_FS -- cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) - - stp x21, x22, [x29, #-16] -- cfi_rel_offset (x21, 0) -- cfi_rel_offset (x22, 8) -+ cfi_rel_offset (x21, -16) -+ cfi_rel_offset (x22, -8) - - /* Load x21 with &call_context. */ - mov x21, sp -@@ -295,7 +295,7 @@ ffi_closure_SYSV: - cfi_restore (x22) - - mov sp, x29 -- cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS) -+ cfi_def_cfa_register (sp) - - ldp x29, x30, [sp], #16 - cfi_adjust_cfa_offset (-16) - diff -u gcc-4.8-4.8.2/debian/patches/ada-acats.diff gcc-4.8-4.8.2/debian/patches/ada-acats.diff --- gcc-4.8-4.8.2/debian/patches/ada-acats.diff +++ gcc-4.8-4.8.2/debian/patches/ada-acats.diff @@ -78,30 +78,35 @@ =================================================================== --- a/src/gcc/testsuite/ada/acats/run_all.sh +++ b/src/gcc/testsuite/ada/acats/run_all.sh -@@ -12,6 +12,11 @@ +@@ -12,6 +12,10 @@ gccflags="-O2" gnatflags="-gnatws" -+SHARED_RTS=`cd $GNATTOOLS/../gcc/ada/rts-shared-zcx; ${PWDCMD-pwd}` -+RTS=`cd $GNATTOOLS/../gcc/ada/rts-static-zcx; ${PWDCMD-pwd}` -+LD_LIBRARY_PATH=$SHARED_RTS:$LIBGNATVSN:$LIBGNATPRJ ++RTS=`cd $GNATTOOLS/../gcc/ada/rts-shared-zcx; ${PWDCMD-pwd}` ++LD_LIBRARY_PATH=$RTS:$LIBGNATVSN:$LIBGNATPRJ +export LD_LIBRARY_PATH + target_run () { eval $EXPECT -f $testdir/run_test.exp $* } -@@ -48,12 +53,15 @@ +@@ -48,15 +52,25 @@ fi target_gnatchop () { - gnatchop --GCC="$GCC_DRIVER" $* ++ display ADA_INCLUDE_PATH=$GNATTOOLS/../../src/gcc/ada $GNATTOOLS/gnatchop --GCC="$GCC_DRIVER" $* + ADA_INCLUDE_PATH=$GNATTOOLS/../../src/gcc/ada $GNATTOOLS/gnatchop --GCC="$GCC_DRIVER" $* } target_gnatmake () { - echo gnatmake --GCC=\"$GCC\" $gnatflags $gccflags $* -largs $EXTERNAL_OBJECTS --GCC=\"$GCC\" - gnatmake --GCC="$GCC" $gnatflags $gccflags $* -largs $EXTERNAL_OBJECTS --GCC="$GCC" ++ RTS="$GNATTOOLS/../gcc/ada/rts-shared-zcx" + EXTERNAL_OBJECTS="$EXTERNAL_OBJECTS $RTS/adaint.o $RTS/sysdep.o $RTS/init.o $RTS/raise-gcc.o" ++ display $GNATTOOLS/gnatmake -I- -I$RTS -I. \ ++ --GCC=\"$GCC\" --GNATBIND="$GNATTOOLS/gnatbind" \ ++ --GNATLINK="$GNATTOOLS/gnatlink" $gnatflags $gccflags $* \ ++ -bargs -static -largs $EXTERNAL_OBJECTS --GCC=\"$GCC -I- -I$RTS -I.\" + $GNATTOOLS/gnatmake -I- -I$RTS -I. \ + --GCC="$GCC" --GNATBIND="$GNATTOOLS/gnatbind" \ + --GNATLINK="$GNATTOOLS/gnatlink" $gnatflags $gccflags $* \ @@ -109,7 +114,11 @@ } target_gcc () { -@@ -86,8 +94,8 @@ ++ display $GCC $gccflags $* + $GCC $gccflags $* + } + +@@ -86,8 +100,8 @@ display `$GCC -v 2>&1` display host=`gcc -dumpmachine` display target=$target @@ -124,7 +133,7 @@ =================================================================== --- a/src/gcc/testsuite/lib/gnat.exp +++ b/src/gcc/testsuite/lib/gnat.exp -@@ -88,18 +88,24 @@ +@@ -89,18 +89,24 @@ global GNAT_UNDER_TEST global TOOL_EXECUTABLE global gnat_target_current diff -u gcc-4.8-4.8.2/debian/patches/ada-default-project-path.diff gcc-4.8-4.8.2/debian/patches/ada-default-project-path.diff --- gcc-4.8-4.8.2/debian/patches/ada-default-project-path.diff +++ gcc-4.8-4.8.2/debian/patches/ada-default-project-path.diff @@ -26,7 +26,7 @@ with Opt; with Osint; use Osint; with Output; use Output; -@@ -1889,6 +1888,7 @@ +@@ -1884,6 +1883,7 @@ (Self : in out Project_Search_Path; Target_Name : String) is @@ -34,7 +34,7 @@ Add_Default_Dir : Boolean := True; First : Positive; Last : Positive; -@@ -2023,59 +2023,8 @@ +@@ -2018,59 +2018,10 @@ -- Set the initial value of Current_Project_Path @@ -92,7 +92,9 @@ - Free (Prefix); - end; + if Add_Default_Dir and Sdefault.Search_Dir_Prefix /= null then -+ Add_Str_To_Name_Buffer (Path_Separator & Sdefault.Search_Dir_Prefix.all); ++ Self.Path := ++ new String'(Name_Buffer (1 .. Name_Len) & Path_Separator & ++ Sdefault.Search_Dir_Prefix.all); end if; Self.Path := new String'(Name_Buffer (1 .. Name_Len)); diff -u gcc-4.8-4.8.2/debian/patches/ada-kfreebsd.diff gcc-4.8-4.8.2/debian/patches/ada-kfreebsd.diff --- gcc-4.8-4.8.2/debian/patches/ada-kfreebsd.diff +++ gcc-4.8-4.8.2/debian/patches/ada-kfreebsd.diff @@ -1,7 +1,5 @@ -# DP: add support for GNU/kFreeBSD. +# DP: Fix gnat build failure on kfreebsd. -Index: b/src/gcc/ada/terminals.c -=================================================================== --- a/src/gcc/ada/terminals.c +++ b/src/gcc/ada/terminals.c @@ -987,6 +987,7 @@ @@ -15,323 +12,0 @@ -Index: b/src/gcc/ada/s-osinte-kfreebsd-gnu.adb -=================================================================== ---- /dev/null -+++ b/src/gcc/ada/s-osinte-kfreebsd-gnu.adb -@@ -0,0 +1,158 @@ -+------------------------------------------------------------------------------ -+-- -- -+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- -+-- -- -+-- S Y S T E M . O S _ I N T E R F A C E -- -+-- -- -+-- B o d y -- -+-- -- -+-- Copyright (C) 1991-1994, Florida State University -- -+-- Copyright (C) 1995-2006, AdaCore -- -+-- -- -+-- GNARL is free software; you can redistribute it and/or modify it under -- -+-- terms of the GNU General Public License as published by the Free Soft- -- -+-- ware Foundation; either version 2, or (at your option) any later ver- -- -+-- sion. GNARL is distributed in the hope that it will be useful, but WITH- -- -+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -+-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- -+-- for more details. You should have received a copy of the GNU General -- -+-- Public License distributed with GNARL; see file COPYING. If not, write -- -+-- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- -+-- Boston, MA 02110-1301, USA. -- -+-- -- -+-- As a special exception, if other files instantiate generics from this -- -+-- unit, or you link this unit with other files to produce an executable, -- -+-- this unit 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 Public License. -- -+-- -- -+-- GNARL was developed by the GNARL team at Florida State University. -- -+-- Extensive contributions were provided by Ada Core Technologies, Inc. -- -+-- -- -+------------------------------------------------------------------------------ -+ -+-- This is the GNU/kFreeBSD version of this package. -+ -+pragma Polling (Off); -+-- Turn off polling, we do not want ATC polling to take place during -+-- tasking operations. It causes infinite loops and other problems. -+ -+-- This package encapsulates all direct interfaces to OS services -+-- that are needed by children of System. -+ -+package body System.OS_Interface is -+ -+ -------------------- -+ -- Get_Stack_Base -- -+ -------------------- -+ -+ function Get_Stack_Base (thread : pthread_t) return Address is -+ pragma Warnings (Off, thread); -+ -+ begin -+ return Null_Address; -+ end Get_Stack_Base; -+ -+ ------------------ -+ -- pthread_init -- -+ ------------------ -+ -+ procedure pthread_init is -+ begin -+ null; -+ end pthread_init; -+ -+ ----------------------------------- -+ -- pthread_mutexattr_setprotocol -- -+ ----------------------------------- -+ -+ function pthread_mutexattr_setprotocol -+ (attr : access pthread_mutexattr_t; -+ protocol : int) return int is -+ pragma Unreferenced (attr, protocol); -+ begin -+ return 0; -+ end pthread_mutexattr_setprotocol; -+ -+ ----------------------------------- -+ -- pthread_mutexattr_getprotocol -- -+ ----------------------------------- -+ -+ function pthread_mutexattr_getprotocol -+ (attr : access pthread_mutexattr_t; -+ protocol : access int) return int is -+ pragma Unreferenced (attr, protocol); -+ begin -+ return 0; -+ end pthread_mutexattr_getprotocol; -+ -+ -------------------------------------- -+ -- pthread_mutexattr_setprioceiling -- -+ -------------------------------------- -+ -+ function pthread_mutexattr_setprioceiling -+ (attr : access pthread_mutexattr_t; -+ prioceiling : int) return int is -+ pragma Unreferenced (attr, prioceiling); -+ begin -+ return 0; -+ end pthread_mutexattr_setprioceiling; -+ -+ -------------------------------------- -+ -- pthread_mutexattr_getprioceiling -- -+ -------------------------------------- -+ -+ function pthread_mutexattr_getprioceiling -+ (attr : access pthread_mutexattr_t; -+ prioceiling : access int) return int is -+ pragma Unreferenced (attr, prioceiling); -+ begin -+ return 0; -+ end pthread_mutexattr_getprioceiling; -+ -+ ----------------- -+ -- To_Duration -- -+ ----------------- -+ -+ function To_Duration (TS : timespec) return Duration is -+ begin -+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9; -+ end To_Duration; -+ -+ ------------------------ -+ -- To_Target_Priority -- -+ ------------------------ -+ -+ function To_Target_Priority -+ (Prio : System.Any_Priority) return Interfaces.C.int -+ is -+ begin -+ return Interfaces.C.int (Prio); -+ end To_Target_Priority; -+ -+ ----------------- -+ -- To_Timespec -- -+ ----------------- -+ -+ function To_Timespec (D : Duration) return timespec is -+ S : time_t; -+ F : Duration; -+ -+ begin -+ S := time_t (Long_Long_Integer (D)); -+ F := D - Duration (S); -+ -+ -- If F has negative value due to a round-up, adjust for positive F -+ -- value. -+ -+ if F < 0.0 then -+ S := S - 1; -+ F := F + 1.0; -+ end if; -+ -+ return timespec'(tv_sec => S, -+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9))); -+ end To_Timespec; -+ -+end System.OS_Interface; -Index: b/src/gcc/ada/gcc-interface/Makefile.in -=================================================================== ---- a/src/gcc/ada/gcc-interface/Makefile.in -+++ b/src/gcc/ada/gcc-interface/Makefile.in -@@ -1194,7 +1194,7 @@ - a-intnam.ads +# @@ -228,7 +228,6 @@ + @srcdir@/../gcc/ada/gnatvsn.ads | \ + sed -e 's/.*"\(.*\)".*/\1/')) +GCC:=../gcc/xgcc -B../gcc/ -+GPP := ../gcc/xg++ -B../gcc/ +LIBGNAT_JUST_BUILT := -nostdinc -I../gcc/ada/rts +LIBGNATVSN := -I../libgnatvsn +CFLAGS := -g -O2 @@ -266,19 +265,14 @@ +OBJECTS := $(patsubst %.ads,%.o,$(SOURCES:.adb=.o)) + +# Add some object files compiled from C sources. prefix.o requires -+# some objects from libiberty and from gcc. -+OBJECTS += common-targhooks.o errors.o hooks.o link.o prefix.o targetm.o ++# some objects from libiberty. ++OBJECTS += concat.o link.o prefix.o xexit.o xmalloc.o xstrdup.o + -+# These object files have already been built, both PIC and non-PIC. -+# prefix.o depends on them. -+LIBIBERTY_OBJECTS := concat.o filename_cmp.o safe-ctype.o xexit.o xmalloc.o xstrdup.o -+ -+vpath %.c @srcdir@ @srcdir@/../gcc @srcdir@/../gcc/common @srcdir@/../gcc/ada ++vpath %.c @srcdir@/../gcc/ada + +libgnatprj.so.$(LIB_VERSION): $(addprefix obj-shared/,$(OBJECTS)) + : # Make libgnatprj.so -+ $(GCC) -o $@ -shared -fPIC -Wl,--soname,$@ -Wl,--no-allow-shlib-undefined \ -+ $^ $(addprefix ../libiberty/pic/,$(LIBIBERTY_OBJECTS)) \ ++ $(GCC) -o $@ -shared -fPIC -Wl,--soname,$@ $^ \ + -L../gcc/ada/rts -lgnat-$(LIB_VERSION) \ + -L../libgnatvsn -lgnatvsn + $(LN_S) -f libgnatprj.so.$(LIB_VERSION) libgnatprj.so @@ -295,21 +289,23 @@ + $(GCC) -c -fPIC $(ADAFLAGS) $(LIBGNAT_JUST_BUILT) $(LIBGNATVSN) $< -o $@ + +obj-shared/%.o: %.c -+ $(GPP) -c -fPIC $(CFLAGS) -DHAVE_CONFIG_H -pedantic \ -+ -I@srcdir@/../gcc -I@srcdir@/../include -I@srcdir@/../libcpp/include -I../gcc \ -+ $< -o $@ ++ $(GCC) -c -fPIC $(CFLAGS) -I@srcdir@/../gcc $< -o $@ + +obj-shared/prefix.o: @srcdir@/../gcc/prefix.c -+ $(GPP) -c -fPIC $(CFLAGS) -DPREFIX=\"@prefix@\" -DBASEVER=\"$(BASEVER)\" \ ++ $(GCC) -c -fPIC $(CFLAGS) -DPREFIX=\"@prefix@\" -DBASEVER=\"$(BASEVER)\" \ + -I@srcdir@/../gcc -I@srcdir@/../include -I../gcc -I@srcdir@/../libcpp/include \ + $< -o $@ + ++obj-shared/%.o: @srcdir@/../libiberty/%.c ++ $(GCC) -c -fPIC $(CFLAGS) \ ++ -I@srcdir@/../libiberty -I@srcdir@/../include $< -o $@ ++ +obj-shared: + -mkdir $@ + +libgnatprj.a: $(addprefix obj-static/,$(OBJECTS)) + : # Make libgnatprj.a -+ ar rc $@ $^ $(addprefix ../libiberty/,$(LIBIBERTY_OBJECTS)) ++ ar rc $@ $^ + ranlib $@ + +$(addprefix obj-static/,$(OBJECTS)): | stamp-libgnatprj-sources obj-static @@ -321,15 +317,17 @@ + $(GCC) -c $(ADAFLAGS) $(LIBGNAT_JUST_BUILT) $(LIBGNATVSN) $< -o $@ + +obj-static/%.o: %.c -+ $(GPP) -c $(CFLAGS) -DHAVE_CONFIG_H -pedantic \ -+ -I@srcdir@/../gcc -I@srcdir@/../include -I@srcdir@/../libcpp/include -I../gcc \ -+ $< -o $@ ++ $(GCC) -c $(CFLAGS) -I@srcdir@/../gcc $< -o $@ + +obj-static/prefix.o: @srcdir@/../gcc/prefix.c -+ $(GPP) -c $(CFLAGS) -DPREFIX=\"@prefix@\" -DBASEVER=\"$(BASEVER)\" \ ++ $(GCC) -c $(CFLAGS) -DPREFIX=\"@prefix@\" -DBASEVER=\"$(BASEVER)\" \ + -I@srcdir@/../gcc -I@srcdir@/../include -I../gcc -I@srcdir@/../libcpp/include \ + $< -o $@ + ++obj-static/%.o: @srcdir@/../libiberty/%.c ++ $(GCC) -c -fPIC $(CFLAGS) \ ++ -I@srcdir@/../libiberty -I@srcdir@/../include $< -o $@ ++ +obj-static: + -mkdir $@ + @@ -381,18 +379,6 @@ +.PHONY: clean +clean: + rm -rf *.ali obj-static obj-shared libgnatprj* *.adb *.ads stamp* -Index: b/src/libgnatprj/targetm.c -=================================================================== ---- /dev/null -+++ b/src/libgnatprj/targetm.c -@@ -0,0 +1,7 @@ -+#include "config.h" -+#include "system.h" -+#include "coretypes.h" -+#include "common/common-target.h" -+#include "common/common-target-def.h" -+ -+struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; Index: b/src/Makefile.def =================================================================== --- a/src/Makefile.def diff -u gcc-4.8-4.8.2/debian/patches/ada-libgnatvsn.diff gcc-4.8-4.8.2/debian/patches/ada-libgnatvsn.diff --- gcc-4.8-4.8.2/debian/patches/ada-libgnatvsn.diff +++ gcc-4.8-4.8.2/debian/patches/ada-libgnatvsn.diff @@ -12,7 +12,7 @@ =================================================================== --- a/src/gnattools/Makefile.in +++ b/src/gnattools/Makefile.in -@@ -41,10 +41,11 @@ +@@ -39,10 +39,11 @@ CFLAGS=-O2 -Wall INCLUDES = -I@srcdir@/../gcc/ada -I@srcdir@/../gcc ADA_CFLAGS=-O2 -gnatn @@ -24,9 +24,9 @@ SHARED_ADA_LIBS := -L../gcc/ada/rts -lgnat-$(LIB_VERSION) +SHARED_ADA_LIBS += -L../libgnatvsn -lgnatvsn STATIC_ADA_LIBS := ../gcc/ada/rts/libgnat.a - STATIC_GCC_LIBS := ../gcc/libcommon-target.a ../gcc/libcommon.a ../libcpp/libcpp.a \ - ../libbacktrace/.libs/libbacktrace.a ../libiberty/libiberty.a -@@ -73,49 +74,27 @@ + STATIC_GCC_LIBS := ../gcc/libcommon-target.a ../gcc/libcommon.a ../libcpp/libcpp.a ../libiberty/libiberty.a + +@@ -70,49 +71,27 @@ # Since we don't have gnatmake, we must specify the full list of # object files necessary to build gnatmake and gnatlink. # TODO: remove from these lists the objects that are part of @@ -78,7 +78,7 @@ err_vars.o \ errout.o \ erroutc.o \ -@@ -123,12 +102,7 @@ +@@ -120,12 +99,7 @@ fmap.o \ fname-sf.o \ fname-uf.o \ @@ -91,7 +91,7 @@ make.o \ makeusg.o \ makeutl.o \ -@@ -138,12 +112,8 @@ +@@ -135,12 +109,8 @@ mlib-tgt-specific.o \ mlib-utl.o \ mlib.o \ @@ -104,7 +104,7 @@ prj-attr-pm.o \ prj-attr.o \ prj-com.o \ -@@ -163,47 +133,60 @@ +@@ -160,48 +130,60 @@ prj.o \ restrict.o \ rident.o \ @@ -170,7 +170,7 @@ -# accessed using the vpath directive. +BODIES := $(foreach f,$(OBJECTS),$(wildcard $(patsubst %.o,@srcdir@/../gcc/ada/%.adb,$(f)))) +SPECS := $(foreach f,$(OBJECTS),$(wildcard $(patsubst %.o,@srcdir@/../gcc/ada/%.ads,$(f)))) -+ + +$(notdir $(SPECS) $(BODIES)): stamp-gnattools-sources stamp-gnattools-sources: @@ -182,7 +182,7 @@ $(foreach PAIR,$(TOOLS_TARGET_PAIRS), \ rm -f $(word 1,$(subst <, ,$(PAIR)));\ $(LN_S) @srcdir@/../gcc/ada/$(word 2,$(subst <, ,$(PAIR))) \ -@@ -211,6 +194,7 @@ +@@ -209,6 +191,7 @@ touch $@ gnattools-native: ../gcc/ada/rts/libgnat-$(LIB_VERSION).so @@ -190,7 +190,7 @@ gnattools-native: stamp-gnattools-sources gnattools-native: $(TOOLS) -@@ -218,13 +202,13 @@ +@@ -216,13 +199,13 @@ vpath %.c @srcdir@/../gcc/ada:@srcdir@/../gcc vpath %.h @srcdir@/../gcc/ada @@ -207,7 +207,7 @@ gnatlink: $(GNATLINK_OBJS) b_gnatl.o link.o $(GCC) -o $@ $^ $(SHARED_ADA_LIBS) $(STATIC_GCC_LIBS) -@@ -235,7 +219,9 @@ +@@ -233,7 +216,9 @@ # gnatmake gnatmake-static: $(GNATMAKE_OBJS) b_gnatm.o link.o @@ -218,7 +218,7 @@ gnatmake: $(GNATMAKE_OBJS) b_gnatm.o link.o $(GCC) -o $@ $(ADA_CFLAGS) $^ $(SHARED_ADA_LIBS) $(STATIC_GCC_LIBS) -@@ -245,6 +231,7 @@ +@@ -243,6 +228,7 @@ # Other tools gnatkr: @@ -226,7 +226,7 @@ ./gnatmake-static -c -b $@ $(ADA_CFLAGS) $(ADA_INCLUDES) \ --GCC="$(GCC)" \ --GNATBIND=../gcc/gnatbind -@@ -256,6 +243,7 @@ +@@ -254,6 +240,7 @@ gnatbind gnatchop gnatclean gnatcmd gnatfind gnatls gnatname gnatprep gnatxref: \ link.o @@ -234,7 +234,7 @@ ./gnatmake-static -c -b $@ $(ADA_CFLAGS) $(ADA_INCLUDES) \ --GCC="$(GCC)" \ --GNATBIND=../gcc/gnatbind -@@ -268,11 +256,6 @@ +@@ -266,11 +253,6 @@ sdefault.adb: stamp-gnattools-sources @@ -246,7 +246,7 @@ %.o: %.adb $(GCC) -c -o $@ $< $(ADA_CFLAGS) $(ADA_INCLUDES) -@@ -323,13 +306,15 @@ +@@ -321,13 +303,15 @@ .PHONY: install install-strip install-info install-pdf install-html # Cleaning rules. @@ -1163,7 +1163,7 @@ .PHONY: configure-gnattools maybe-configure-gnattools maybe-configure-gnattools: @if gcc-bootstrap -@@ -41482,6 +41856,361 @@ +@@ -41492,6 +41866,361 @@ @@ -1525,7 +1525,7 @@ .PHONY: configure-target-libgomp maybe-configure-target-libgomp maybe-configure-target-libgomp: @if gcc-bootstrap -@@ -45535,6 +46264,7 @@ +@@ -45545,6 +46274,7 @@ configure-target-boehm-gc: stage_last configure-target-rda: stage_last configure-target-libada: stage_last @@ -1533,7 +1533,7 @@ configure-stage1-target-libgomp: maybe-all-stage1-gcc configure-stage2-target-libgomp: maybe-all-stage2-gcc configure-stage3-target-libgomp: maybe-all-stage3-gcc -@@ -45566,6 +46296,7 @@ +@@ -45576,6 +46306,7 @@ configure-target-boehm-gc: maybe-all-gcc configure-target-rda: maybe-all-gcc configure-target-libada: maybe-all-gcc @@ -1541,7 +1541,7 @@ configure-target-libgomp: maybe-all-gcc configure-target-libitm: maybe-all-gcc configure-target-libatomic: maybe-all-gcc -@@ -45859,6 +46590,8 @@ +@@ -45869,6 +46600,8 @@ all-stagefeedback-libcpp: maybe-all-stagefeedback-intl all-fixincludes: maybe-all-libiberty all-gnattools: maybe-all-libada @@ -1550,7 +1550,7 @@ all-lto-plugin: maybe-all-libiberty all-stage1-lto-plugin: maybe-all-stage1-libiberty -@@ -46394,6 +47127,7 @@ +@@ -46370,6 +47103,7 @@ configure-target-boehm-gc: maybe-all-target-libgcc configure-target-rda: maybe-all-target-libgcc configure-target-libada: maybe-all-target-libgcc @@ -1558,7 +1558,7 @@ configure-target-libgomp: maybe-all-target-libgcc configure-target-libitm: maybe-all-target-libgcc configure-target-libatomic: maybe-all-target-libgcc -@@ -46438,6 +47172,8 @@ +@@ -46414,6 +47148,8 @@ configure-target-libada: maybe-all-target-newlib maybe-all-target-libgloss @@ -1610,7 +1610,7 @@ =================================================================== --- a/src/gcc/ada/gcc-interface/config-lang.in +++ b/src/gcc/ada/gcc-interface/config-lang.in -@@ -34,8 +34,8 @@ +@@ -36,8 +36,8 @@ outputs="ada/gcc-interface/Makefile ada/Makefile" diff -u gcc-4.8-4.8.2/debian/patches/ada-link-lib.diff gcc-4.8-4.8.2/debian/patches/ada-link-lib.diff --- gcc-4.8-4.8.2/debian/patches/ada-link-lib.diff +++ gcc-4.8-4.8.2/debian/patches/ada-link-lib.diff @@ -15,7 +15,7 @@ =================================================================== --- a/src/gcc/ada/gcc-interface/config-lang.in +++ b/src/gcc/ada/gcc-interface/config-lang.in -@@ -35,7 +35,7 @@ +@@ -37,7 +37,7 @@ outputs="ada/gcc-interface/Makefile ada/Makefile" target_libs="target-libada" @@ -109,7 +109,7 @@ # Make arch match the current multilib so that the RTS selection code # picks up the right files. For a given target this must be coherent -@@ -1376,6 +1348,11 @@ +@@ -1365,6 +1337,11 @@ LIBRARY_VERSION := $(LIB_VERSION) endif @@ -121,7 +121,7 @@ # HP/PA HP-UX 10 ifeq ($(strip $(filter-out hppa% hp hpux10%,$(targ))),) LIBGNAT_TARGET_PAIRS = \ -@@ -2381,151 +2358,6 @@ +@@ -2362,153 +2339,6 @@ $(patsubst %$(objext),%.adb,$(GNATRTL_OBJS)), \ $(ADA_EXCLUDE_SRCS)) @@ -143,7 +143,7 @@ - "GNATLINK=$(GNATLINK)" \ - "GNATBIND=$(GNATBIND)" - --GCC_LINK=$(CC) $(GCC_LINK_FLAGS) $(ADA_INCLUDES) $(LDFLAGS) +-GCC_LINK=$(CC) $(GCC_LINK_FLAGS) $(ADA_INCLUDES) - -# Build directory for the tools. Let's copy the target-dependent -# sources using the same mechanism as for gnatlib. The other sources are @@ -265,15 +265,17 @@ - -# Likewise for the tools -../../gnatmake$(exeext): $(P) b_gnatm.o link.o targext.o $(GNATMAKE_OBJS) -- +$(GCC_LINK) $(ALL_CFLAGS) -o $@ b_gnatm.o $(GNATMAKE_OBJS) $(TOOLS_LIBS) +- $(GCC_LINK) $(ALL_CFLAGS) $(LDFLAGS) -o $@ b_gnatm.o $(GNATMAKE_OBJS) \ +- $(TOOLS_LIBS) - -../../gnatlink$(exeext): $(P) b_gnatl.o link.o targext.o $(GNATLINK_OBJS) -- +$(GCC_LINK) $(ALL_CFLAGS) -o $@ b_gnatl.o $(GNATLINK_OBJS) $(TOOLS_LIBS) +- $(GCC_LINK) $(ALL_CFLAGS) $(LDFLAGS) -o $@ b_gnatl.o $(GNATLINK_OBJS) \ +- $(TOOLS_LIBS) - ../stamp-gnatlib-$(RTSDIR): @if [ ! -f stamp-gnatlib-$(RTSDIR) ] ; \ then \ -@@ -2562,14 +2394,10 @@ +@@ -2545,14 +2375,10 @@ # Also install the .dSYM directories if they exist (these directories # contain the debug information for the shared libraries on darwin) for file in gnat gnarl; do \ @@ -290,7 +292,7 @@ if [ -d $(RTSDIR)/lib$${file}$(hyphen)$(LIBRARY_VERSION)$(soext).dSYM ]; then \ $(CP) -r $(RTSDIR)/lib$${file}$(hyphen)$(LIBRARY_VERSION)$(soext).dSYM \ $(DESTDIR)$(ADA_RTL_OBJ_DIR); \ -@@ -2582,19 +2410,7 @@ +@@ -2565,19 +2391,7 @@ cd $(DESTDIR)$(ADA_INCLUDE_DIR); $(CHMOD) a-wx *.adb cd $(DESTDIR)$(ADA_INCLUDE_DIR); $(CHMOD) a-wx *.ads @@ -311,7 +313,7 @@ $(RMDIR) $(RTSDIR) $(MKDIR) $(RTSDIR) $(CHMOD) u+w $(RTSDIR) -@@ -2659,7 +2475,7 @@ +@@ -2642,7 +2456,7 @@ # Example: cd $(RTSDIR); ar rc libfoo.a $(LONG_LIST_OF_OBJS) # is guaranteed to overflow the buffer. @@ -320,7 +322,7 @@ # C files $(MAKE) -C $(RTSDIR) \ CC="`echo \"$(GCC_FOR_TARGET)\" \ -@@ -2696,32 +2512,47 @@ +@@ -2679,32 +2493,47 @@ # Warning: this target assumes that LIBRARY_VERSION has been set correctly. gnatlib-shared-default: @@ -384,7 +386,7 @@ gnatlib-shared-dual: $(MAKE) $(FLAGS_TO_PASS) \ -@@ -2730,17 +2561,15 @@ +@@ -2713,17 +2542,15 @@ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \ MULTISUBDIR="$(MULTISUBDIR)" \ THREAD_KIND="$(THREAD_KIND)" \ @@ -405,7 +407,7 @@ gnatlib-shared-dual-win32: $(MAKE) $(FLAGS_TO_PASS) \ -@@ -2750,17 +2579,15 @@ +@@ -2733,17 +2560,15 @@ PICFLAG_FOR_TARGET="$(PICFLAG_FOR_TARGET)" \ MULTISUBDIR="$(MULTISUBDIR)" \ THREAD_KIND="$(THREAD_KIND)" \ @@ -426,7 +428,7 @@ # ??? we need to add the option to support auto-import of arrays/records to # the GNATLIBFLAGS when this will be supported by GNAT. At this point we will -@@ -2898,28 +2725,6 @@ +@@ -2881,28 +2706,6 @@ THREAD_KIND="$(THREAD_KIND)" \ PICFLAG_FOR_TARGET="$(PICFLAG_FOR_TARGET)" gnatlib @@ -469,7 +471,7 @@ # Standard autoconf-set variables. SHELL = @SHELL@ srcdir = @srcdir@ -@@ -35,103 +38,19 @@ +@@ -33,86 +36,19 @@ LN_S=@LN_S@ target_noncanonical=@target_noncanonical@ @@ -524,7 +526,6 @@ -TOOLS_FLAGS_TO_PASS_RE= \ - "CC=../../xgcc -B../../" \ - "CFLAGS=$(CFLAGS)" \ -- "LDFLAGS=$(LDFLAGS)" \ - "ADAFLAGS=$(ADAFLAGS)" \ - "ADA_CFLAGS=$(ADA_CFLAGS)" \ - "INCLUDES=$(INCLUDES_FOR_SUBDIR)" \ @@ -538,22 +539,6 @@ - "TOOLSCASE=cross" - -# Variables for gnattools, cross --ifeq ($(build), $(host)) -- GNATMAKE_FOR_HOST=gnatmake -- GNATLINK_FOR_HOST=gnatlink -- GNATBIND_FOR_HOST=gnatbind -- GNATLS_FOR_HOST=gnatls --else -- GNATMAKE_FOR_HOST=$(host_alias)-gnatmake -- GNATLINK_FOR_HOST=$(host_alias)-gnatlink -- GNATBIND_FOR_HOST=$(host_alias)-gnatbind -- GNATLS_FOR_HOST=$(host_alias)-gnatls --endif -- --# Put the host RTS dir first in the PATH to hide the default runtime --# files that are among the sources --RTS_DIR:=$(strip $(subst \,/,$(shell $(GNATLS_FOR_HOST) -v | grep adalib ))) -- -TOOLS_FLAGS_TO_PASS_CROSS= \ - "CC=$(CC)" \ - "CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \ @@ -565,9 +550,9 @@ - "exeext=$(exeext)" \ - "fsrcdir=$(fsrcdir)" \ - "srcdir=$(fsrcdir)" \ -- "GNATMAKE=$(GNATMAKE_FOR_HOST)" \ -- "GNATLINK=$(GNATLINK_FOR_HOST)" \ -- "GNATBIND=$(GNATBIND_FOR_HOST)" \ +- "GNATMAKE=gnatmake" \ +- "GNATLINK=gnatlink" \ +- "GNATBIND=gnatbind" \ - "TOOLSCASE=cross" \ - "LIBGNAT=" +CFLAGS=-O2 -Wall @@ -586,7 +571,7 @@ # File lists # ---------- -@@ -140,116 +59,228 @@ +@@ -121,121 +57,229 @@ EXTRA_GNATTOOLS = @EXTRA_GNATTOOLS@ TOOLS_TARGET_PAIRS = @TOOLS_TARGET_PAIRS@ @@ -745,6 +730,7 @@ -# accessed using the vpath directive in ada/Makefile.in +# accessed using the vpath directive. + ++ +stamp-gnattools-sources: + $(LN_S) ../gcc/ada/sdefault.adb ../gcc/ada/snames.ads ../gcc/ada/snames.adb . + $(foreach PAIR,$(TOOLS_TARGET_PAIRS), \ @@ -859,6 +845,11 @@ - $(MAKE) -C $(GCC_DIR)/ada/tools -f ../Makefile \ - $(TOOLS_FLAGS_TO_PASS_NATIVE) common-tools - +-# For cross builds of gnattools, +-# put the host RTS dir first in the PATH to hide the default runtime +-# files that are among the sources +-# FIXME: This should be done in configure. +-RTS_DIR:=$(strip $(subst \,/,$(shell gnatls -v | grep adalib ))) -gnattools-cross: $(GCC_DIR)/stamp-tools - # gnattools1-re - $(MAKE) -C $(GCC_DIR)/ada/tools -f ../Makefile \ @@ -916,7 +907,7 @@ # Other # ----- -@@ -279,6 +310,7 @@ +@@ -265,6 +309,7 @@ # Installation rules. install: @@ -924,7 +915,7 @@ install-strip: install -@@ -292,8 +324,10 @@ +@@ -278,8 +323,10 @@ # Cleaning rules. mostlyclean: @@ -939,7 +930,7 @@ =================================================================== --- a/src/libada/Makefile.in +++ b/src/libada/Makefile.in -@@ -64,7 +64,7 @@ +@@ -58,7 +58,7 @@ -fexceptions -DIN_RTS @have_getipinfo@ host_subdir = @host_subdir@ @@ -1662,7 +1653,7 @@ @endif gnattools -@@ -40970,13 +41211,8 @@ +@@ -40980,13 +41221,8 @@ @if target-libada maybe-check-target-libada: check-target-libada @@ -1677,7 +1668,7 @@ @endif target-libada -@@ -40985,13 +41221,8 @@ +@@ -40995,13 +41231,8 @@ @if target-libada maybe-install-target-libada: install-target-libada @@ -1693,7 +1684,7 @@ @endif target-libada -@@ -41000,13 +41231,8 @@ +@@ -41010,13 +41241,8 @@ @if target-libada maybe-install-strip-target-libada: install-strip-target-libada @@ -1709,7 +1700,7 @@ @endif target-libada -@@ -41017,24 +41243,8 @@ +@@ -41027,24 +41253,8 @@ @if target-libada maybe-info-target-libada: info-target-libada @@ -1736,7 +1727,7 @@ @endif target-libada -@@ -41043,24 +41253,8 @@ +@@ -41053,24 +41263,8 @@ @if target-libada maybe-dvi-target-libada: dvi-target-libada @@ -1763,7 +1754,7 @@ @endif target-libada -@@ -41095,24 +41289,8 @@ +@@ -41105,24 +41299,8 @@ @if target-libada maybe-html-target-libada: html-target-libada @@ -1790,7 +1781,7 @@ @endif target-libada -@@ -41121,24 +41299,8 @@ +@@ -41131,24 +41309,8 @@ @if target-libada maybe-TAGS-target-libada: TAGS-target-libada @@ -1817,7 +1808,7 @@ @endif target-libada -@@ -41147,25 +41309,8 @@ +@@ -41157,25 +41319,8 @@ @if target-libada maybe-install-info-target-libada: install-info-target-libada @@ -1845,7 +1836,7 @@ @endif target-libada -@@ -41228,24 +41373,8 @@ +@@ -41238,24 +41383,8 @@ @if target-libada maybe-installcheck-target-libada: installcheck-target-libada @@ -1872,7 +1863,7 @@ @endif target-libada -@@ -45729,7 +45858,7 @@ +@@ -45739,7 +45868,7 @@ all-stageprofile-libcpp: maybe-all-stageprofile-intl all-stagefeedback-libcpp: maybe-all-stagefeedback-intl all-fixincludes: maybe-all-libiberty reverted: --- gcc-4.8-4.8.2/debian/patches/ada-ppc64.diff +++ gcc-4.8-4.8.2.orig/debian/patches/ada-ppc64.diff @@ -1,24 +0,0 @@ -# Fix 32/64 bit detection, broken due to the fact Debian installs -# 64-bit libraries in lib and not lib64. Fix based on the s390/s390x -# detection. - ---- a/src/gcc/ada/gcc-interface/Makefile.in -+++ b/src/gcc/ada/gcc-interface/Makefile.in -@@ -1858,9 +1858,14 @@ - LIBGNAT_TARGET_PAIRS_64 = \ - system.ads&2 exit 1 -@@ -3289,6 +3297,9 @@ +@@ -3269,6 +3277,9 @@ "" \ | arm | thumb ) #OK @@ -39,7 +39,7 @@ =================================================================== --- a/src/gcc/config/arm/linux-eabi.h +++ b/src/gcc/config/arm/linux-eabi.h -@@ -43,7 +43,21 @@ +@@ -34,7 +34,21 @@ target hardware. If you override this to use the hard-float ABI then change the setting of GLIBC_DYNAMIC_LINKER_DEFAULT as well. */ #undef TARGET_DEFAULT_FLOAT_ABI @@ -61,7 +61,7 @@ /* We default to the "aapcs-linux" ABI so that enums are int-sized by default. */ -@@ -86,6 +100,28 @@ +@@ -77,6 +91,28 @@ %{mfloat-abi=soft*:" GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "} \ %{!mfloat-abi=*:" GLIBC_DYNAMIC_LINKER_DEFAULT "}" diff -u gcc-4.8-4.8.2/debian/patches/arm-sanitizer.diff gcc-4.8-4.8.2/debian/patches/arm-sanitizer.diff --- gcc-4.8-4.8.2/debian/patches/arm-sanitizer.diff +++ gcc-4.8-4.8.2/debian/patches/arm-sanitizer.diff @@ -42,10 +42,8 @@ * g++.dg/asan/deep-thread-stack-1.C: Likewise. * g++.dg/asan/large-func-test-1.C: Likewise. -Index: b/src/libsanitizer/configure.tgt -=================================================================== ---- a/src/libsanitizer/configure.tgt -+++ b/src/libsanitizer/configure.tgt +--- a/src/libsanitizer/configure.tgt (revision 200266) ++++ b/src/libsanitizer/configure.tgt (revision 200267) @@ -29,6 +29,8 @@ ;; sparc*-*-linux*) @@ -55,11 +53,9 @@ x86_64-*-darwin[1]* | i?86-*-darwin[1]*) TSAN_SUPPORTED=no ;; -Index: b/src/gcc/testsuite/lib/target-supports.exp -=================================================================== ---- a/src/gcc/testsuite/lib/target-supports.exp -+++ b/src/gcc/testsuite/lib/target-supports.exp -@@ -4591,6 +4591,33 @@ +--- a/src/gcc/testsuite/lib/target-supports.exp (revision 200266) ++++ b/src/gcc/testsuite/lib/target-supports.exp (revision 200267) +@@ -4668,6 +4668,33 @@ return 0 } @@ -93,10 +89,8 @@ # Return 1 if the target is a VxWorks kernel. proc check_effective_target_vxworks_kernel { } { -Index: b/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C -=================================================================== ---- a/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C -+++ b/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C +--- a/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C (revision 200266) ++++ b/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C (revision 200267) @@ -37,9 +37,9 @@ // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow on address\[^\n\r]*" } @@ -110,10 +104,8 @@ +// { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } // { dg-output " #0( 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } -Index: b/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C -=================================================================== ---- a/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C -+++ b/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C +--- a/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C (revision 200266) ++++ b/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C (revision 200267) @@ -45,9 +45,9 @@ } @@ -127,10 +119,8 @@ // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } -Index: b/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c -=================================================================== ---- a/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c +--- a/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c (revision 200266) ++++ b/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c (revision 200267) @@ -15,7 +15,7 @@ /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ @@ -141,10 +131,8 @@ +/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ -Index: b/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c -=================================================================== ---- a/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c +--- a/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c (revision 200266) ++++ b/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c (revision 200267) @@ -2,6 +2,7 @@ /* { dg-do run { target setrlimit } } */ @@ -153,20 +141,16 @@ /* { dg-shouldfail "asan" } */ #include -Index: b/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c -=================================================================== ---- a/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c +--- a/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c (revision 200266) ++++ b/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c (revision 200267) @@ -19,4 +19,4 @@ /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame
" } */ +/* { dg-output "\[^\n\r]*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame
" } */ -Index: b/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c -=================================================================== ---- a/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c +--- a/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c (revision 200266) ++++ b/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c (revision 200267) @@ -11,12 +11,12 @@ /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free on address\[^\n\r]*" } */ @@ -184,10 +168,8 @@ +/* { dg-output "\[^\n\r]*previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ -Index: b/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c -=================================================================== ---- a/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c +--- a/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c (revision 200266) ++++ b/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c (revision 200267) @@ -3,6 +3,7 @@ /* { dg-do run { target { *-*-linux* } } } */ @@ -196,10 +178,8 @@ /* { dg-options "-D_GNU_SOURCE" } */ #include -Index: b/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c -=================================================================== ---- a/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c +--- a/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c (revision 200266) ++++ b/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c (revision 200267) @@ -25,7 +25,7 @@ /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ @@ -210,10 +190,8 @@ +/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ -Index: b/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c -=================================================================== ---- a/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c +--- a/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c (revision 200266) ++++ b/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c (revision 200267) @@ -18,6 +18,6 @@ /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */ @@ -222,11 +200,9 @@ +/* { dg-output "\[^\n\r]*AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ -Index: b/src/gcc/config/arm/arm.c -=================================================================== ---- a/src/gcc/config/arm/arm.c -+++ b/src/gcc/config/arm/arm.c -@@ -280,6 +280,7 @@ +--- a/src/gcc/config/arm/arm.c (revision 200266) ++++ b/src/gcc/config/arm/arm.c (revision 200267) +@@ -281,6 +281,7 @@ static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, bool op0_preserve_value); @@ -234,7 +210,7 @@ /* Table of machine attributes. */ static const struct attribute_spec arm_attribute_table[] = -@@ -649,6 +650,9 @@ +@@ -657,6 +658,9 @@ #define TARGET_CANONICALIZE_COMPARISON \ arm_canonicalize_comparison @@ -244,7 +220,7 @@ struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ -@@ -27450,4 +27454,12 @@ +@@ -28276,4 +28280,12 @@ } @@ -257,10 +233,8 @@ +} + #include "gt-arm.h" -Index: b/src/gcc/config/arm/linux-eabi.h -=================================================================== ---- a/src/gcc/config/arm/linux-eabi.h -+++ b/src/gcc/config/arm/linux-eabi.h +--- a/src/gcc/config/arm/linux-eabi.h (revision 200266) ++++ b/src/gcc/config/arm/linux-eabi.h (revision 200267) @@ -84,10 +84,14 @@ LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) diff -u gcc-4.8-4.8.2/debian/patches/config-ml.diff gcc-4.8-4.8.2/debian/patches/config-ml.diff --- gcc-4.8-4.8.2/debian/patches/config-ml.diff +++ gcc-4.8-4.8.2/debian/patches/config-ml.diff @@ -3,8 +3,8 @@ Index: b/src/config-ml.in =================================================================== ---- a/src/config-ml.in -+++ b/src/config-ml.in +--- a/src/config-ml.in 2013-05-11 20:45:43.490271752 +0000 ++++ b/src/config-ml.in 2013-05-11 20:45:43.414271243 +0000 @@ -467,6 +467,25 @@ ;; esac @@ -91,9 +91,9 @@ exit 1 Index: b/src/libstdc++-v3/include/Makefile.am =================================================================== ---- a/src/libstdc++-v3/include/Makefile.am -+++ b/src/libstdc++-v3/include/Makefile.am -@@ -826,8 +826,9 @@ +--- a/src/libstdc++-v3/include/Makefile.am 2013-05-11 20:45:43.490271752 +0000 ++++ b/src/libstdc++-v3/include/Makefile.am 2013-05-11 20:47:20.646921114 +0000 +@@ -825,8 +825,9 @@ endif host_srcdir = ${glibcxx_srcdir}/$(OS_INC_SRCDIR) @@ -105,7 +105,7 @@ host_headers = \ ${host_srcdir}/ctype_base.h \ ${host_srcdir}/ctype_inline.h \ -@@ -1048,6 +1049,7 @@ +@@ -1047,6 +1048,7 @@ stamp-${host_alias}: @-mkdir -p ${host_builddir} @-mkdir -p ${host_builddir}/../ext @@ -115,8 +115,8 @@ # Host includes static. Index: b/src/libstdc++-v3/include/Makefile.in =================================================================== ---- a/src/libstdc++-v3/include/Makefile.in -+++ b/src/libstdc++-v3/include/Makefile.in +--- a/src/libstdc++-v3/include/Makefile.in 2013-05-11 20:45:43.490271752 +0000 ++++ b/src/libstdc++-v3/include/Makefile.in 2013-05-11 20:47:36.843028205 +0000 @@ -202,6 +202,7 @@ check_msgfmt = @check_msgfmt@ datadir = @datadir@ @@ -125,7 +125,7 @@ docdir = @docdir@ dvidir = @dvidir@ enable_shared = @enable_shared@ -@@ -1081,8 +1082,8 @@ +@@ -1080,8 +1081,8 @@ # For --enable-cheaders=c_std @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@c_compatibility_headers_extra = ${c_compatibility_headers} host_srcdir = ${glibcxx_srcdir}/$(OS_INC_SRCDIR) @@ -136,7 +136,7 @@ host_headers = \ ${host_srcdir}/ctype_base.h \ ${host_srcdir}/ctype_inline.h \ -@@ -1461,6 +1462,7 @@ +@@ -1460,6 +1461,7 @@ stamp-${host_alias}: @-mkdir -p ${host_builddir} @-mkdir -p ${host_builddir}/../ext @@ -146,8 +146,8 @@ # Host includes static. Index: b/src/libstdc++-v3/configure.ac =================================================================== ---- a/src/libstdc++-v3/configure.ac -+++ b/src/libstdc++-v3/configure.ac +--- a/src/libstdc++-v3/configure.ac 2013-05-11 20:45:43.490271752 +0000 ++++ b/src/libstdc++-v3/configure.ac 2013-05-11 20:45:43.490271752 +0000 @@ -461,6 +461,16 @@ multilib_arg= fi diff -u gcc-4.8-4.8.2/debian/patches/disable-gdc-tests.diff gcc-4.8-4.8.2/debian/patches/disable-gdc-tests.diff --- gcc-4.8-4.8.2/debian/patches/disable-gdc-tests.diff +++ gcc-4.8-4.8.2/debian/patches/disable-gdc-tests.diff @@ -1,5 +1,3 @@ -# DP: Disable D tests, hang on many buildds - --- a/src/gcc/d/Make-lang.in +++ b/src/gcc/d/Make-lang.in @@ -358,8 +358,8 @@ reverted: --- gcc-4.8-4.8.2/debian/patches/fix-ffi_call_VFP-with-no-VFP-argument.diff +++ gcc-4.8-4.8.2.orig/debian/patches/fix-ffi_call_VFP-with-no-VFP-argument.diff @@ -1,12 +0,0 @@ -# DP: armhf: Fix ffi_call_VFP with no VFP arguments. - ---- a/src/libffi/src/arm/sysv.S -+++ b/src/libffi/src/arm/sysv.S -@@ -368,6 +368,7 @@ ARM_FUNC_START ffi_call_VFP - - @ Load VFP register args if needed - cmp r0, #0 -+ mov ip, fp - beq LSYM(Lbase_args) - - @ Load only d0 if possible diff -u gcc-4.8-4.8.2/debian/patches/gcc-auto-build.diff gcc-4.8-4.8.2/debian/patches/gcc-auto-build.diff --- gcc-4.8-4.8.2/debian/patches/gcc-auto-build.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-auto-build.diff @@ -1,13 +1,13 @@ # DP: Fix cross building a native compiler. ---- a/src/gcc/configure.ac -+++ b/src/gcc/configure.ac -@@ -1516,7 +1516,7 @@ - /* | [A-Za-z]:[\\/]* ) realsrcdir=${srcdir};; +--- a/src/gcc/configure.ac~ 2013-06-11 18:34:36.757067080 +0200 ++++ b/src/gcc/configure.ac 2013-06-11 22:51:47.340892778 +0200 +@@ -1519,7 +1519,7 @@ *) realsrcdir=../${srcdir};; esac + saved_CFLAGS="${CFLAGS}" - CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \ + CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD} -DGENERATOR_FILE" \ - LDFLAGS="${LDFLAGS_FOR_BUILD}" GMPINC="" \ + LDFLAGS="${LDFLAGS_FOR_BUILD}" \ ${realsrcdir}/configure \ --enable-languages=${enable_languages-all} \ diff -u gcc-4.8-4.8.2/debian/patches/gcc-base-version.diff gcc-4.8-4.8.2/debian/patches/gcc-base-version.diff --- gcc-4.8-4.8.2/debian/patches/gcc-base-version.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-base-version.diff @@ -114,7 +114,7 @@ > tmp-gcov-iov.h $(SHELL) $(srcdir)/../move-if-change tmp-gcov-iov.h gcov-iov.h $(STAMP) s-iov -@@ -4281,8 +4283,8 @@ +@@ -4302,8 +4304,8 @@ TEXI_CPPINT_FILES = cppinternals.texi gcc-common.texi gcc-vers.texi # gcc-vers.texi is generated from the version files. @@ -125,7 +125,7 @@ if [ "$(DEVPHASE_c)" = "experimental" ]; \ then echo "@set DEVELOPMENT"; \ else echo "@clear DEVELOPMENT"; \ -@@ -4660,9 +4662,11 @@ +@@ -4701,9 +4703,11 @@ install-driver: installdirs xgcc$(exeext) -rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) -$(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) reverted: --- gcc-4.8-4.8.2/debian/patches/gcc-dfsg-linaro-doc.diff +++ gcc-4.8-4.8.2.orig/debian/patches/gcc-dfsg-linaro-doc.diff @@ -1,6 +0,0 @@ -Index: gcc-4.8-4.8.2/src/gcc/doc/arm-acle-intrinsics.texi -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gcc-4.8-4.8.2/src/gcc/doc/arm-acle-intrinsics.texi 2014-03-18 18:42:11.027303768 +0000 -@@ -0,0 +1 @@ -+@c This file is empty because the original one has a non DFSG free license (GFDL) diff -u gcc-4.8-4.8.2/debian/patches/gcc-hash-style-gnu.diff gcc-4.8-4.8.2/debian/patches/gcc-hash-style-gnu.diff --- gcc-4.8-4.8.2/debian/patches/gcc-hash-style-gnu.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-hash-style-gnu.diff @@ -158,8 +158,8 @@ =================================================================== --- a/src/gcc/config/aarch64/aarch64-linux.h +++ b/src/gcc/config/aarch64/aarch64-linux.h -@@ -26,6 +26,7 @@ - #define CPP_SPEC "%{pthread:-D_REENTRANT}" +@@ -24,6 +24,7 @@ + #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-aarch64.so.1" #define LINUX_TARGET_LINK_SPEC "%{h*} \ + --hash-style=gnu \ diff -u gcc-4.8-4.8.2/debian/patches/gcc-ice-apport.diff gcc-4.8-4.8.2/debian/patches/gcc-ice-apport.diff --- gcc-4.8-4.8.2/debian/patches/gcc-ice-apport.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-ice-apport.diff @@ -5,7 +5,7 @@ =================================================================== --- a/src/gcc/gcc.c +++ b/src/gcc/gcc.c -@@ -6256,6 +6256,16 @@ +@@ -6254,6 +6254,16 @@ fnotice (stderr, "Preprocessed source stored into %s file," " please attach this to your bugreport.\n", temp_filenames[attempt * 2]); diff -u gcc-4.8-4.8.2/debian/patches/gcc-ice-hack.diff gcc-4.8-4.8.2/debian/patches/gcc-ice-hack.diff --- gcc-4.8-4.8.2/debian/patches/gcc-ice-hack.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-ice-hack.diff @@ -36,7 +36,7 @@ static const char *getenv_spec_function (int, const char **); static const char *if_exists_spec_function (int, const char **); -@@ -2773,7 +2776,7 @@ +@@ -2771,7 +2774,7 @@ } } @@ -45,7 +45,7 @@ free (CONST_CAST (char *, string)); } -@@ -2826,6 +2829,16 @@ +@@ -2824,6 +2827,16 @@ else if (WIFEXITED (status) && WEXITSTATUS (status) >= MIN_FATAL_STATUS) { @@ -62,7 +62,7 @@ if (WEXITSTATUS (status) > greatest_status) greatest_status = WEXITSTATUS (status); ret_code = -1; -@@ -2883,6 +2896,9 @@ +@@ -2881,6 +2894,9 @@ } } @@ -72,7 +72,7 @@ return ret_code; } } -@@ -6036,6 +6052,227 @@ +@@ -6034,6 +6050,227 @@ switches[switchnum].validated = true; } diff -u gcc-4.8-4.8.2/debian/patches/gcc-linaro-doc.diff gcc-4.8-4.8.2/debian/patches/gcc-linaro-doc.diff --- gcc-4.8-4.8.2/debian/patches/gcc-linaro-doc.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-linaro-doc.diff @@ -1,97 +1,8 @@ -# DP: Changes for the Linaro 4.8-2014.03 release (documentation). +# DP: Changes for the Linaro 4.8-2013.11 release (documentation). -Index: b/src/gcc/doc/extend.texi -=================================================================== ---- a/src/gcc/doc/extend.texi -+++ b/src/gcc/doc/extend.texi -@@ -8781,6 +8781,7 @@ - * Alpha Built-in Functions:: - * ARM iWMMXt Built-in Functions:: - * ARM NEON Intrinsics:: -+* ARM ACLE Intrinsics:: - * AVR Built-in Functions:: - * Blackfin Built-in Functions:: - * FR-V Built-in Functions:: -@@ -9046,6 +9047,14 @@ - - @include arm-neon-intrinsics.texi - -+@node ARM ACLE Intrinsics -+@subsection ARM ACLE Intrinsics -+ -+These built-in intrinsics for the ARMv8-A CRC32 extension are available when -+the @option{-march=armv8-a+crc} switch is used: -+ -+@include arm-acle-intrinsics.texi -+ - @node AVR Built-in Functions - @subsection AVR Built-in Functions - -Index: b/src/gcc/doc/arm-acle-intrinsics.texi -=================================================================== ---- /dev/null -+++ b/src/gcc/doc/arm-acle-intrinsics.texi -@@ -0,0 +1,55 @@ -+@c Copyright (C) 2013-2014 Free Software Foundation, Inc. -+@c This is part of the GCC manual. -+@c For copying conditions, see the file gcc.texi. -+ -+@subsubsection CRC32 intrinsics -+ -+@itemize @bullet -+@item uint32_t __crc32b (uint32_t, uint8_t) -+@*@emph{Form of expected instruction(s):} @code{crc32b @var{r0}, @var{r0}, @var{r0}} -+@end itemize -+ -+ -+@itemize @bullet -+@item uint32_t __crc32h (uint32_t, uint16_t) -+@*@emph{Form of expected instruction(s):} @code{crc32h @var{r0}, @var{r0}, @var{r0}} -+@end itemize -+ -+ -+@itemize @bullet -+@item uint32_t __crc32w (uint32_t, uint32_t) -+@*@emph{Form of expected instruction(s):} @code{crc32w @var{r0}, @var{r0}, @var{r0}} -+@end itemize -+ -+ -+@itemize @bullet -+@item uint32_t __crc32d (uint32_t, uint64_t) -+@*@emph{Form of expected instruction(s):} Two @code{crc32w @var{r0}, @var{r0}, @var{r0}} -+instructions for AArch32. One @code{crc32w @var{w0}, @var{w0}, @var{x0}} instruction for -+AArch64. -+@end itemize -+ -+@itemize @bullet -+@item uint32_t __crc32cb (uint32_t, uint8_t) -+@*@emph{Form of expected instruction(s):} @code{crc32cb @var{r0}, @var{r0}, @var{r0}} -+@end itemize -+ -+ -+@itemize @bullet -+@item uint32_t __crc32ch (uint32_t, uint16_t) -+@*@emph{Form of expected instruction(s):} @code{crc32ch @var{r0}, @var{r0}, @var{r0}} -+@end itemize -+ -+ -+@itemize @bullet -+@item uint32_t __crc32cw (uint32_t, uint32_t) -+@*@emph{Form of expected instruction(s):} @code{crc32cw @var{r0}, @var{r0}, @var{r0}} -+@end itemize -+ -+ -+@itemize @bullet -+@item uint32_t __crc32cd (uint32_t, uint64_t) -+@*@emph{Form of expected instruction(s):} Two @code{crc32cw @var{r0}, @var{r0}, @var{r0}} -+instructions for AArch32. One @code{crc32cw @var{w0}, @var{w0}, @var{x0}} instruction for -+AArch64. -+@end itemize -Index: b/src/gcc/doc/tm.texi -=================================================================== --- a/src/gcc/doc/tm.texi +++ b/src/gcc/doc/tm.texi -@@ -10926,8 +10926,16 @@ +@@ -10926,10 +10926,18 @@ @samp{TARGET_INIT_BUILTINS}. @var{fndecl} is the declaration of the built-in function. @var{n_args} is the number of arguments passed to the function; the arguments themselves are pointed to by @var{argp}. @@ -100,18 +11,18 @@ +The result is another tree, valid for both GIMPLE and GENERIC, +containing a simplified expression for the call's result. If +@var{ignore} is true the value will be ignored. -+@end deftypefn -+ + @end deftypefn + +@deftypefn {Target Hook} bool TARGET_GIMPLE_FOLD_BUILTIN (gimple_stmt_iterator *@var{gsi}) +Fold a call to a machine specific built-in function that was set up +by @samp{TARGET_INIT_BUILTINS}. @var{gsi} points to the gimple +statement holding the function call. Returns true if any change +was made to the GIMPLE stream. - @end deftypefn - ++@end deftypefn ++ @deftypefn {Target Hook} int TARGET_COMPARE_VERSION_PRIORITY (tree @var{decl1}, tree @var{decl2}) -Index: b/src/gcc/doc/tm.texi.in -=================================================================== + This hook is used to compare the target attributes in two functions to + determine which function's features get higher priority. This is used --- a/src/gcc/doc/tm.texi.in +++ b/src/gcc/doc/tm.texi.in @@ -10772,10 +10772,13 @@ @@ -130,19 +41,8 @@ @hook TARGET_COMPARE_VERSION_PRIORITY This hook is used to compare the target attributes in two functions to determine which function's features get higher priority. This is used -Index: b/src/gcc/doc/invoke.texi -=================================================================== --- a/src/gcc/doc/invoke.texi +++ b/src/gcc/doc/invoke.texi -@@ -418,7 +418,7 @@ - -ftree-parallelize-loops=@var{n} -ftree-pre -ftree-partial-pre -ftree-pta @gol - -ftree-reassoc -ftree-sink -ftree-slsr -ftree-sra @gol - -ftree-switch-conversion -ftree-tail-merge @gol ---ftree-ter -ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol -+-ftree-ter -ftree-vectorize -ftree-vrp @gol - -funit-at-a-time -funroll-all-loops -funroll-loops @gol - -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol - -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol @@ -510,7 +510,9 @@ -mtp=@var{name} -mtls-dialect=@var{dialect} @gol -mword-relocations @gol @@ -154,69 +54,7 @@ @emph{AVR Options} @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol -@@ -6590,7 +6592,7 @@ - @option{-Os} disables the following optimization flags: - @gccoptlist{-falign-functions -falign-jumps -falign-loops @gol - -falign-labels -freorder-blocks -freorder-blocks-and-partition @gol ---fprefetch-loop-arrays -ftree-vect-loop-version} -+-fprefetch-loop-arrays} - - @item -Ofast - @opindex Ofast -@@ -7831,19 +7833,20 @@ - Perform basic block vectorization on trees. This flag is enabled by default at - @option{-O3} and when @option{-ftree-vectorize} is enabled. - --@item -ftree-vect-loop-version --@opindex ftree-vect-loop-version --Perform loop versioning when doing loop vectorization on trees. When a loop --appears to be vectorizable except that data alignment or data dependence cannot --be determined at compile time, then vectorized and non-vectorized versions of --the loop are generated along with run-time checks for alignment or dependence --to control which version is executed. This option is enabled by default --except at level @option{-Os} where it is disabled. -- --@item -fvect-cost-model -+@item -fvect-cost-model=@var{model} - @opindex fvect-cost-model --Enable cost model for vectorization. This option is enabled by default at --@option{-O3}. -+Alter the cost model used for vectorization. The @var{model} argument -+should be one of @code{unlimited}, @code{dynamic} or @code{cheap}. -+With the @code{unlimited} model the vectorized code-path is assumed -+to be profitable while with the @code{dynamic} model a runtime check -+will guard the vectorized code-path to enable it only for iteration -+counts that will likely execute faster than when executing the original -+scalar loop. The @code{cheap} model will disable vectorization of -+loops where doing so would be cost prohibitive for example due to -+required runtime checks for data dependence or alignment but otherwise -+is equal to the @code{dynamic} model. -+The default cost model depends on other optimization flags and is -+either @code{dynamic} or @code{cheap}. - - @item -ftree-vrp - @opindex ftree-vrp -@@ -9239,13 +9242,15 @@ - - @item vect-max-version-for-alignment-checks - The maximum number of run-time checks that can be performed when --doing loop versioning for alignment in the vectorizer. See option --@option{-ftree-vect-loop-version} for more information. -+doing loop versioning for alignment in the vectorizer. - - @item vect-max-version-for-alias-checks - The maximum number of run-time checks that can be performed when --doing loop versioning for alias in the vectorizer. See option --@option{-ftree-vect-loop-version} for more information. -+doing loop versioning for alias in the vectorizer. -+ -+@item vect-max-peeling-for-alignment -+The maximum number of loop peels to enhance access alignment -+for vectorizer. Value -1 means 'no limit'. - - @item max-iterations-to-track - The maximum number of iterations of a loop the brute-force algorithm -@@ -10966,6 +10971,8 @@ +@@ -10966,6 +10968,8 @@ the following: @table @samp @@ -225,7 +63,7 @@ @item crypto Enable Crypto extension. This implies Advanced SIMD is enabled. @item fp -@@ -11263,8 +11270,8 @@ +@@ -11263,8 +11267,8 @@ @samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp}, @samp{arm1156t2-s}, @samp{arm1156t2f-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s}, @samp{cortex-a5}, @samp{cortex-a7}, @samp{cortex-a8}, @samp{cortex-a9}, @@ -236,21 +74,7 @@ @samp{cortex-m1}, @samp{cortex-m0}, @samp{cortex-m0plus}, -@@ -11317,9 +11324,12 @@ - @samp{armv6}, @samp{armv6j}, - @samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, @samp{armv6-m}, - @samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m}, --@samp{armv8-a}, -+@samp{armv8-a}, @samp{armv8-a+crc}, - @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}. - -+@option{-march=armv8-a+crc} enables code generation for the ARMv8-A -+architecture together with the optional CRC32 extensions. -+ - @option{-march=native} causes the compiler to auto-detect the architecture - of the build computer. At present, this feature is only supported on - Linux, and not all architectures are recognized. If the auto-detect is -@@ -11527,6 +11537,17 @@ +@@ -11527,6 +11531,17 @@ preprocessor symbol @code{__ARM_FEATURE_UNALIGNED} will also be defined. @@ -268,159 +92,9 @@ @end table @node AVR Options -Index: b/src/gcc/doc/arm-neon-intrinsics.texi -=================================================================== --- a/src/gcc/doc/arm-neon-intrinsics.texi +++ b/src/gcc/doc/arm-neon-intrinsics.texi -@@ -4079,6 +4079,12 @@ - @subsubsection Vector shift right and insert - - @itemize @bullet -+@item poly64x1_t vsri_n_p64 (poly64x1_t, poly64x1_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vsri.64 @var{d0}, @var{d0}, #@var{0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x2_t vsri_n_u32 (uint32x2_t, uint32x2_t, const int) - @*@emph{Form of expected instruction(s):} @code{vsri.32 @var{d0}, @var{d0}, #@var{0}} - @end itemize -@@ -4139,6 +4145,12 @@ - - - @itemize @bullet -+@item poly64x2_t vsriq_n_p64 (poly64x2_t, poly64x2_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vsri.64 @var{q0}, @var{q0}, #@var{0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x4_t vsriq_n_u32 (uint32x4_t, uint32x4_t, const int) - @*@emph{Form of expected instruction(s):} @code{vsri.32 @var{q0}, @var{q0}, #@var{0}} - @end itemize -@@ -4203,6 +4215,12 @@ - @subsubsection Vector shift left and insert - - @itemize @bullet -+@item poly64x1_t vsli_n_p64 (poly64x1_t, poly64x1_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vsli.64 @var{d0}, @var{d0}, #@var{0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x2_t vsli_n_u32 (uint32x2_t, uint32x2_t, const int) - @*@emph{Form of expected instruction(s):} @code{vsli.32 @var{d0}, @var{d0}, #@var{0}} - @end itemize -@@ -4263,6 +4281,12 @@ - - - @itemize @bullet -+@item poly64x2_t vsliq_n_p64 (poly64x2_t, poly64x2_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vsli.64 @var{q0}, @var{q0}, #@var{0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x4_t vsliq_n_u32 (uint32x4_t, uint32x4_t, const int) - @*@emph{Form of expected instruction(s):} @code{vsli.32 @var{q0}, @var{q0}, #@var{0}} - @end itemize -@@ -5071,6 +5095,11 @@ - @subsubsection Create vector from literal bit pattern - - @itemize @bullet -+@item poly64x1_t vcreate_p64 (uint64_t) -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x2_t vcreate_u32 (uint64_t) - @end itemize - -@@ -5184,6 +5213,11 @@ - - - @itemize @bullet -+@item poly64x1_t vdup_n_p64 (poly64_t) -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1_t vdup_n_u64 (uint64_t) - @end itemize - -@@ -5194,6 +5228,11 @@ - - - @itemize @bullet -+@item poly64x2_t vdupq_n_p64 (poly64_t) -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x4_t vdupq_n_u32 (uint32_t) - @*@emph{Form of expected instruction(s):} @code{vdup.32 @var{q0}, @var{r0}} - @end itemize -@@ -5440,6 +5479,11 @@ - - - @itemize @bullet -+@item poly64x1_t vdup_lane_p64 (poly64x1_t, const int) -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1_t vdup_lane_u64 (uint64x1_t, const int) - @end itemize - -@@ -5504,6 +5548,11 @@ - - - @itemize @bullet -+@item poly64x2_t vdupq_lane_p64 (poly64x1_t, const int) -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x2_t vdupq_lane_u64 (uint64x1_t, const int) - @end itemize - -@@ -5518,6 +5567,11 @@ - @subsubsection Combining vectors - - @itemize @bullet -+@item poly64x2_t vcombine_p64 (poly64x1_t, poly64x1_t) -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x4_t vcombine_u32 (uint32x2_t, uint32x2_t) - @end itemize - -@@ -5577,6 +5631,11 @@ - @subsubsection Splitting vectors - - @itemize @bullet -+@item poly64x1_t vget_high_p64 (poly64x2_t) -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x2_t vget_high_u32 (uint32x4_t) - @end itemize - -@@ -5686,6 +5745,11 @@ - - - @itemize @bullet -+@item poly64x1_t vget_low_p64 (poly64x2_t) -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1_t vget_low_u64 (uint64x2_t) - @end itemize - -@@ -5748,6 +5812,18 @@ +@@ -5748,6 +5748,18 @@ @itemize @bullet @@ -439,2040 +113,6 @@ @item float32x2_t vcvt_n_f32_u32 (uint32x2_t, const int) @*@emph{Form of expected instruction(s):} @code{vcvt.f32.u32 @var{d0}, @var{d0}, #@var{0}} @end itemize -@@ -6806,6 +6882,12 @@ - @subsubsection Vector extract - - @itemize @bullet -+@item poly64x1_t vext_p64 (poly64x1_t, poly64x1_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vext.64 @var{d0}, @var{d0}, @var{d0}, #@var{0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x2_t vext_u32 (uint32x2_t, uint32x2_t, const int) - @*@emph{Form of expected instruction(s):} @code{vext.32 @var{d0}, @var{d0}, @var{d0}, #@var{0}} - @end itemize -@@ -6872,6 +6954,12 @@ - - - @itemize @bullet -+@item poly64x2_t vextq_p64 (poly64x2_t, poly64x2_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vext.64 @var{q0}, @var{q0}, @var{q0}, #@var{0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x4_t vextq_u32 (uint32x4_t, uint32x4_t, const int) - @*@emph{Form of expected instruction(s):} @code{vext.32 @var{q0}, @var{q0}, @var{q0}, #@var{0}} - @end itemize -@@ -7162,6 +7250,12 @@ - @subsubsection Bit selection - - @itemize @bullet -+@item poly64x1_t vbsl_p64 (uint64x1_t, poly64x1_t, poly64x1_t) -+@*@emph{Form of expected instruction(s):} @code{vbsl @var{d0}, @var{d0}, @var{d0}} @emph{or} @code{vbit @var{d0}, @var{d0}, @var{d0}} @emph{or} @code{vbif @var{d0}, @var{d0}, @var{d0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x2_t vbsl_u32 (uint32x2_t, uint32x2_t, uint32x2_t) - @*@emph{Form of expected instruction(s):} @code{vbsl @var{d0}, @var{d0}, @var{d0}} @emph{or} @code{vbit @var{d0}, @var{d0}, @var{d0}} @emph{or} @code{vbif @var{d0}, @var{d0}, @var{d0}} - @end itemize -@@ -7228,6 +7322,12 @@ - - - @itemize @bullet -+@item poly64x2_t vbslq_p64 (uint64x2_t, poly64x2_t, poly64x2_t) -+@*@emph{Form of expected instruction(s):} @code{vbsl @var{q0}, @var{q0}, @var{q0}} @emph{or} @code{vbit @var{q0}, @var{q0}, @var{q0}} @emph{or} @code{vbif @var{q0}, @var{q0}, @var{q0}} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x4_t vbslq_u32 (uint32x4_t, uint32x4_t, uint32x4_t) - @*@emph{Form of expected instruction(s):} @code{vbsl @var{q0}, @var{q0}, @var{q0}} @emph{or} @code{vbit @var{q0}, @var{q0}, @var{q0}} @emph{or} @code{vbif @var{q0}, @var{q0}, @var{q0}} - @end itemize -@@ -7634,6 +7734,12 @@ - @subsubsection Element/structure loads, VLD1 variants - - @itemize @bullet -+@item poly64x1_t vld1_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x2_t vld1_u32 (const uint32_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.32 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -7700,6 +7806,12 @@ - - - @itemize @bullet -+@item poly64x2_t vld1q_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint32x4_t vld1q_u32 (const uint32_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.32 @{@var{d0}, @var{d1}@}, [@var{r0}]} - @end itemize -@@ -7820,6 +7932,12 @@ - - - @itemize @bullet -+@item poly64x1_t vld1_lane_p64 (const poly64_t *, poly64x1_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1_t vld1_lane_u64 (const uint64_t *, uint64x1_t, const int) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -7886,6 +8004,12 @@ - - - @itemize @bullet -+@item poly64x2_t vld1q_lane_p64 (const poly64_t *, poly64x2_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x2_t vld1q_lane_u64 (const uint64_t *, uint64x2_t, const int) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -7952,6 +8076,12 @@ - - - @itemize @bullet -+@item poly64x1_t vld1_dup_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1_t vld1_dup_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -8018,6 +8148,12 @@ - - - @itemize @bullet -+@item poly64x2_t vld1q_dup_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x2_t vld1q_dup_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -8034,6 +8170,12 @@ - @subsubsection Element/structure stores, VST1 variants - - @itemize @bullet -+@item void vst1_p64 (poly64_t *, poly64x1_t) -+@*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item void vst1_u32 (uint32_t *, uint32x2_t) - @*@emph{Form of expected instruction(s):} @code{vst1.32 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -8100,6 +8242,12 @@ - - - @itemize @bullet -+@item void vst1q_p64 (poly64_t *, poly64x2_t) -+@*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item void vst1q_u32 (uint32_t *, uint32x4_t) - @*@emph{Form of expected instruction(s):} @code{vst1.32 @{@var{d0}, @var{d1}@}, [@var{r0}]} - @end itemize -@@ -8220,6 +8368,12 @@ - - - @itemize @bullet -+@item void vst1_lane_p64 (poly64_t *, poly64x1_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item void vst1_lane_s64 (int64_t *, int64x1_t, const int) - @*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -8286,6 +8440,12 @@ - - - @itemize @bullet -+@item void vst1q_lane_p64 (poly64_t *, poly64x2_t, const int) -+@*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item void vst1q_lane_s64 (int64_t *, int64x2_t, const int) - @*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}@}, [@var{r0}]} - @end itemize -@@ -8356,6 +8516,12 @@ - - - @itemize @bullet -+@item poly64x1x2_t vld2_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1x2_t vld2_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} - @end itemize -@@ -8566,6 +8732,12 @@ - - - @itemize @bullet -+@item poly64x1x2_t vld2_dup_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1x2_t vld2_dup_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} - @end itemize -@@ -8636,6 +8808,12 @@ - - - @itemize @bullet -+@item void vst2_p64 (poly64_t *, poly64x1x2_t) -+@*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item void vst2_u64 (uint64_t *, uint64x1x2_t) - @*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}, @var{d1}@}, [@var{r0}]} - @end itemize -@@ -8850,6 +9028,12 @@ - - - @itemize @bullet -+@item poly64x1x3_t vld3_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1x3_t vld3_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}@}, [@var{r0}]} - @end itemize -@@ -9060,6 +9244,12 @@ - - - @itemize @bullet -+@item poly64x1x3_t vld3_dup_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1x3_t vld3_dup_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}@}, [@var{r0}]} - @end itemize -@@ -9130,6 +9320,12 @@ - - - @itemize @bullet -+@item void vst3_p64 (poly64_t *, poly64x1x3_t) -+@*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item void vst3_u64 (uint64_t *, uint64x1x3_t) - @*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} - @end itemize -@@ -9344,6 +9540,12 @@ - - - @itemize @bullet -+@item poly64x1x4_t vld4_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1x4_t vld4_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} - @end itemize -@@ -9554,6 +9756,12 @@ - - - @itemize @bullet -+@item poly64x1x4_t vld4_dup_p64 (const poly64_t *) -+@*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item uint64x1x4_t vld4_dup_u64 (const uint64_t *) - @*@emph{Form of expected instruction(s):} @code{vld1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} - @end itemize -@@ -9624,6 +9832,12 @@ - - - @itemize @bullet -+@item void vst4_p64 (poly64_t *, poly64x1x4_t) -+@*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} -+@end itemize -+ -+ -+@itemize @bullet - @item void vst4_u64 (uint64_t *, uint64x1x4_t) - @*@emph{Form of expected instruction(s):} @code{vst1.64 @{@var{d0}, @var{d1}, @var{d2}, @var{d3}@}, [@var{r0}]} - @end itemize -@@ -10274,27 +10488,27 @@ - @subsubsection Reinterpret casts - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_u32 (uint32x2_t) -+@item poly8x8_t vreinterpret_p8_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_u16 (uint16x4_t) -+@item poly8x8_t vreinterpret_p8_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_u8 (uint8x8_t) -+@item poly8x8_t vreinterpret_p8_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_s32 (int32x2_t) -+@item poly8x8_t vreinterpret_p8_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_s16 (int16x4_t) -+@item poly8x8_t vreinterpret_p8_u64 (uint64x1_t) - @end itemize - - -@@ -10304,967 +10518,1292 @@ - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_u64 (uint64x1_t) -+@item poly8x8_t vreinterpret_p8_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_s64 (int64x1_t) -+@item poly8x8_t vreinterpret_p8_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_f32 (float32x2_t) -+@item poly8x8_t vreinterpret_p8_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item poly8x8_t vreinterpret_p8_p16 (poly16x4_t) -+@item poly8x8_t vreinterpret_p8_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_u32 (uint32x4_t) -+@item poly8x8_t vreinterpret_p8_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_u16 (uint16x8_t) -+@item poly16x4_t vreinterpret_p16_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_u8 (uint8x16_t) -+@item poly16x4_t vreinterpret_p16_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_s32 (int32x4_t) -+@item poly16x4_t vreinterpret_p16_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_s16 (int16x8_t) -+@item poly16x4_t vreinterpret_p16_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_s8 (int8x16_t) -+@item poly16x4_t vreinterpret_p16_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_u64 (uint64x2_t) -+@item poly16x4_t vreinterpret_p16_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_s64 (int64x2_t) -+@item poly16x4_t vreinterpret_p16_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_f32 (float32x4_t) -+@item poly16x4_t vreinterpret_p16_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item poly8x16_t vreinterpretq_p8_p16 (poly16x8_t) -+@item poly16x4_t vreinterpret_p16_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_u32 (uint32x2_t) -+@item poly16x4_t vreinterpret_p16_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_u16 (uint16x4_t) -+@item poly16x4_t vreinterpret_p16_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_u8 (uint8x8_t) -+@item float32x2_t vreinterpret_f32_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_s32 (int32x2_t) -+@item float32x2_t vreinterpret_f32_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_s16 (int16x4_t) -+@item float32x2_t vreinterpret_f32_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_s8 (int8x8_t) -+@item float32x2_t vreinterpret_f32_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_u64 (uint64x1_t) -+@item float32x2_t vreinterpret_f32_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_s64 (int64x1_t) -+@item float32x2_t vreinterpret_f32_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_f32 (float32x2_t) -+@item float32x2_t vreinterpret_f32_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item poly16x4_t vreinterpret_p16_p8 (poly8x8_t) -+@item float32x2_t vreinterpret_f32_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_u32 (uint32x4_t) -+@item float32x2_t vreinterpret_f32_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_u16 (uint16x8_t) -+@item float32x2_t vreinterpret_f32_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_u8 (uint8x16_t) -+@item float32x2_t vreinterpret_f32_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_s32 (int32x4_t) -+@item poly64x1_t vreinterpret_p64_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_s16 (int16x8_t) -+@item poly64x1_t vreinterpret_p64_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_s8 (int8x16_t) -+@item poly64x1_t vreinterpret_p64_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_u64 (uint64x2_t) -+@item poly64x1_t vreinterpret_p64_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_s64 (int64x2_t) -+@item poly64x1_t vreinterpret_p64_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_f32 (float32x4_t) -+@item poly64x1_t vreinterpret_p64_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item poly16x8_t vreinterpretq_p16_p8 (poly8x16_t) -+@item poly64x1_t vreinterpret_p64_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_u32 (uint32x2_t) -+@item poly64x1_t vreinterpret_p64_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_u16 (uint16x4_t) -+@item poly64x1_t vreinterpret_p64_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_u8 (uint8x8_t) -+@item poly64x1_t vreinterpret_p64_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_s32 (int32x2_t) -+@item poly64x1_t vreinterpret_p64_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_s16 (int16x4_t) -+@item int64x1_t vreinterpret_s64_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_s8 (int8x8_t) -+@item int64x1_t vreinterpret_s64_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_u64 (uint64x1_t) -+@item int64x1_t vreinterpret_s64_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_s64 (int64x1_t) -+@item int64x1_t vreinterpret_s64_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_p16 (poly16x4_t) -+@item int64x1_t vreinterpret_s64_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item float32x2_t vreinterpret_f32_p8 (poly8x8_t) -+@item int64x1_t vreinterpret_s64_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_u32 (uint32x4_t) -+@item int64x1_t vreinterpret_s64_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_u16 (uint16x8_t) -+@item int64x1_t vreinterpret_s64_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_u8 (uint8x16_t) -+@item int64x1_t vreinterpret_s64_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_s32 (int32x4_t) -+@item int64x1_t vreinterpret_s64_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_s16 (int16x8_t) -+@item int64x1_t vreinterpret_s64_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_s8 (int8x16_t) -+@item uint64x1_t vreinterpret_u64_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_u64 (uint64x2_t) -+@item uint64x1_t vreinterpret_u64_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_s64 (int64x2_t) -+@item uint64x1_t vreinterpret_u64_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_p16 (poly16x8_t) -+@item uint64x1_t vreinterpret_u64_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item float32x4_t vreinterpretq_f32_p8 (poly8x16_t) -+@item uint64x1_t vreinterpret_u64_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_u32 (uint32x2_t) -+@item uint64x1_t vreinterpret_u64_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_u16 (uint16x4_t) -+@item uint64x1_t vreinterpret_u64_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_u8 (uint8x8_t) -+@item uint64x1_t vreinterpret_u64_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_s32 (int32x2_t) -+@item uint64x1_t vreinterpret_u64_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_s16 (int16x4_t) -+@item uint64x1_t vreinterpret_u64_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_s8 (int8x8_t) -+@item uint64x1_t vreinterpret_u64_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_u64 (uint64x1_t) -+@item int8x8_t vreinterpret_s8_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_f32 (float32x2_t) -+@item int8x8_t vreinterpret_s8_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_p16 (poly16x4_t) -+@item int8x8_t vreinterpret_s8_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item int64x1_t vreinterpret_s64_p8 (poly8x8_t) -+@item int8x8_t vreinterpret_s8_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_u32 (uint32x4_t) -+@item int8x8_t vreinterpret_s8_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_u16 (uint16x8_t) -+@item int8x8_t vreinterpret_s8_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_u8 (uint8x16_t) -+@item int8x8_t vreinterpret_s8_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_s32 (int32x4_t) -+@item int8x8_t vreinterpret_s8_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_s16 (int16x8_t) -+@item int8x8_t vreinterpret_s8_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_s8 (int8x16_t) -+@item int8x8_t vreinterpret_s8_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_u64 (uint64x2_t) -+@item int8x8_t vreinterpret_s8_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_f32 (float32x4_t) -+@item int16x4_t vreinterpret_s16_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_p16 (poly16x8_t) -+@item int16x4_t vreinterpret_s16_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item int64x2_t vreinterpretq_s64_p8 (poly8x16_t) -+@item int16x4_t vreinterpret_s16_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_u32 (uint32x2_t) -+@item int16x4_t vreinterpret_s16_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_u16 (uint16x4_t) -+@item int16x4_t vreinterpret_s16_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_u8 (uint8x8_t) -+@item int16x4_t vreinterpret_s16_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_s32 (int32x2_t) -+@item int16x4_t vreinterpret_s16_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_s16 (int16x4_t) -+@item int16x4_t vreinterpret_s16_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_s8 (int8x8_t) -+@item int16x4_t vreinterpret_s16_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_s64 (int64x1_t) -+@item int16x4_t vreinterpret_s16_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_f32 (float32x2_t) -+@item int16x4_t vreinterpret_s16_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_p16 (poly16x4_t) -+@item int32x2_t vreinterpret_s32_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item uint64x1_t vreinterpret_u64_p8 (poly8x8_t) -+@item int32x2_t vreinterpret_s32_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_u32 (uint32x4_t) -+@item int32x2_t vreinterpret_s32_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_u16 (uint16x8_t) -+@item int32x2_t vreinterpret_s32_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_u8 (uint8x16_t) -+@item int32x2_t vreinterpret_s32_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_s32 (int32x4_t) -+@item int32x2_t vreinterpret_s32_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_s16 (int16x8_t) -+@item int32x2_t vreinterpret_s32_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_s8 (int8x16_t) -+@item int32x2_t vreinterpret_s32_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_s64 (int64x2_t) -+@item int32x2_t vreinterpret_s32_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_f32 (float32x4_t) -+@item int32x2_t vreinterpret_s32_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_p16 (poly16x8_t) -+@item int32x2_t vreinterpret_s32_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item uint64x2_t vreinterpretq_u64_p8 (poly8x16_t) -+@item uint8x8_t vreinterpret_u8_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_u32 (uint32x2_t) -+@item uint8x8_t vreinterpret_u8_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_u16 (uint16x4_t) -+@item uint8x8_t vreinterpret_u8_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_u8 (uint8x8_t) -+@item uint8x8_t vreinterpret_u8_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_s32 (int32x2_t) -+@item uint8x8_t vreinterpret_u8_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_s16 (int16x4_t) -+@item uint8x8_t vreinterpret_u8_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_u64 (uint64x1_t) -+@item uint8x8_t vreinterpret_u8_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_s64 (int64x1_t) -+@item uint8x8_t vreinterpret_u8_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_f32 (float32x2_t) -+@item uint8x8_t vreinterpret_u8_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_p16 (poly16x4_t) -+@item uint8x8_t vreinterpret_u8_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item int8x8_t vreinterpret_s8_p8 (poly8x8_t) -+@item uint8x8_t vreinterpret_u8_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_u32 (uint32x4_t) -+@item uint16x4_t vreinterpret_u16_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_u16 (uint16x8_t) -+@item uint16x4_t vreinterpret_u16_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_u8 (uint8x16_t) -+@item uint16x4_t vreinterpret_u16_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_s32 (int32x4_t) -+@item uint16x4_t vreinterpret_u16_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_s16 (int16x8_t) -+@item uint16x4_t vreinterpret_u16_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_u64 (uint64x2_t) -+@item uint16x4_t vreinterpret_u16_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_s64 (int64x2_t) -+@item uint16x4_t vreinterpret_u16_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_f32 (float32x4_t) -+@item uint16x4_t vreinterpret_u16_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_p16 (poly16x8_t) -+@item uint16x4_t vreinterpret_u16_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item int8x16_t vreinterpretq_s8_p8 (poly8x16_t) -+@item uint16x4_t vreinterpret_u16_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_u32 (uint32x2_t) -+@item uint16x4_t vreinterpret_u16_u32 (uint32x2_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_u16 (uint16x4_t) -+@item uint32x2_t vreinterpret_u32_p8 (poly8x8_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_u8 (uint8x8_t) -+@item uint32x2_t vreinterpret_u32_p16 (poly16x4_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_s32 (int32x2_t) -+@item uint32x2_t vreinterpret_u32_f32 (float32x2_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_s8 (int8x8_t) -+@item uint32x2_t vreinterpret_u32_p64 (poly64x1_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_u64 (uint64x1_t) -+@item uint32x2_t vreinterpret_u32_s64 (int64x1_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_s64 (int64x1_t) -+@item uint32x2_t vreinterpret_u32_u64 (uint64x1_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_f32 (float32x2_t) -+@item uint32x2_t vreinterpret_u32_s8 (int8x8_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_p16 (poly16x4_t) -+@item uint32x2_t vreinterpret_u32_s16 (int16x4_t) - @end itemize - - - @itemize @bullet --@item int16x4_t vreinterpret_s16_p8 (poly8x8_t) -+@item uint32x2_t vreinterpret_u32_s32 (int32x2_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_u32 (uint32x4_t) -+@item uint32x2_t vreinterpret_u32_u8 (uint8x8_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_u16 (uint16x8_t) -+@item uint32x2_t vreinterpret_u32_u16 (uint16x4_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_u8 (uint8x16_t) -+@item poly8x16_t vreinterpretq_p8_p16 (poly16x8_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_s32 (int32x4_t) -+@item poly8x16_t vreinterpretq_p8_f32 (float32x4_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_s8 (int8x16_t) -+@item poly8x16_t vreinterpretq_p8_p64 (poly64x2_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_u64 (uint64x2_t) -+@item poly8x16_t vreinterpretq_p8_p128 (poly128_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_s64 (int64x2_t) -+@item poly8x16_t vreinterpretq_p8_s64 (int64x2_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_f32 (float32x4_t) -+@item poly8x16_t vreinterpretq_p8_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_p16 (poly16x8_t) -+@item poly8x16_t vreinterpretq_p8_s8 (int8x16_t) - @end itemize - - - @itemize @bullet --@item int16x8_t vreinterpretq_s16_p8 (poly8x16_t) -+@item poly8x16_t vreinterpretq_p8_s16 (int16x8_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_u32 (uint32x2_t) -+@item poly8x16_t vreinterpretq_p8_s32 (int32x4_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_u16 (uint16x4_t) -+@item poly8x16_t vreinterpretq_p8_u8 (uint8x16_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_u8 (uint8x8_t) -+@item poly8x16_t vreinterpretq_p8_u16 (uint16x8_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_s16 (int16x4_t) -+@item poly8x16_t vreinterpretq_p8_u32 (uint32x4_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_s8 (int8x8_t) -+@item poly16x8_t vreinterpretq_p16_p8 (poly8x16_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_u64 (uint64x1_t) -+@item poly16x8_t vreinterpretq_p16_f32 (float32x4_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_s64 (int64x1_t) -+@item poly16x8_t vreinterpretq_p16_p64 (poly64x2_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_f32 (float32x2_t) -+@item poly16x8_t vreinterpretq_p16_p128 (poly128_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_p16 (poly16x4_t) -+@item poly16x8_t vreinterpretq_p16_s64 (int64x2_t) - @end itemize - - - @itemize @bullet --@item int32x2_t vreinterpret_s32_p8 (poly8x8_t) -+@item poly16x8_t vreinterpretq_p16_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_u32 (uint32x4_t) -+@item poly16x8_t vreinterpretq_p16_s8 (int8x16_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_u16 (uint16x8_t) -+@item poly16x8_t vreinterpretq_p16_s16 (int16x8_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_u8 (uint8x16_t) -+@item poly16x8_t vreinterpretq_p16_s32 (int32x4_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_s16 (int16x8_t) -+@item poly16x8_t vreinterpretq_p16_u8 (uint8x16_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_s8 (int8x16_t) -+@item poly16x8_t vreinterpretq_p16_u16 (uint16x8_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_u64 (uint64x2_t) -+@item poly16x8_t vreinterpretq_p16_u32 (uint32x4_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_s64 (int64x2_t) -+@item float32x4_t vreinterpretq_f32_p8 (poly8x16_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_f32 (float32x4_t) -+@item float32x4_t vreinterpretq_f32_p16 (poly16x8_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_p16 (poly16x8_t) -+@item float32x4_t vreinterpretq_f32_p64 (poly64x2_t) - @end itemize - - - @itemize @bullet --@item int32x4_t vreinterpretq_s32_p8 (poly8x16_t) -+@item float32x4_t vreinterpretq_f32_p128 (poly128_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_u32 (uint32x2_t) -+@item float32x4_t vreinterpretq_f32_s64 (int64x2_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_u16 (uint16x4_t) -+@item float32x4_t vreinterpretq_f32_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_s32 (int32x2_t) -+@item float32x4_t vreinterpretq_f32_s8 (int8x16_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_s16 (int16x4_t) -+@item float32x4_t vreinterpretq_f32_s16 (int16x8_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_s8 (int8x8_t) -+@item float32x4_t vreinterpretq_f32_s32 (int32x4_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_u64 (uint64x1_t) -+@item float32x4_t vreinterpretq_f32_u8 (uint8x16_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_s64 (int64x1_t) -+@item float32x4_t vreinterpretq_f32_u16 (uint16x8_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_f32 (float32x2_t) -+@item float32x4_t vreinterpretq_f32_u32 (uint32x4_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_p16 (poly16x4_t) -+@item poly64x2_t vreinterpretq_p64_p8 (poly8x16_t) - @end itemize - - - @itemize @bullet --@item uint8x8_t vreinterpret_u8_p8 (poly8x8_t) -+@item poly64x2_t vreinterpretq_p64_p16 (poly16x8_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_u32 (uint32x4_t) -+@item poly64x2_t vreinterpretq_p64_f32 (float32x4_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_u16 (uint16x8_t) -+@item poly64x2_t vreinterpretq_p64_p128 (poly128_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_s32 (int32x4_t) -+@item poly64x2_t vreinterpretq_p64_s64 (int64x2_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_s16 (int16x8_t) -+@item poly64x2_t vreinterpretq_p64_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_s8 (int8x16_t) -+@item poly64x2_t vreinterpretq_p64_s8 (int8x16_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_u64 (uint64x2_t) -+@item poly64x2_t vreinterpretq_p64_s16 (int16x8_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_s64 (int64x2_t) -+@item poly64x2_t vreinterpretq_p64_s32 (int32x4_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_f32 (float32x4_t) -+@item poly64x2_t vreinterpretq_p64_u8 (uint8x16_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_p16 (poly16x8_t) -+@item poly64x2_t vreinterpretq_p64_u16 (uint16x8_t) - @end itemize - - - @itemize @bullet --@item uint8x16_t vreinterpretq_u8_p8 (poly8x16_t) -+@item poly64x2_t vreinterpretq_p64_u32 (uint32x4_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_u32 (uint32x2_t) -+@item poly128_t vreinterpretq_p128_p8 (poly8x16_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_u8 (uint8x8_t) -+@item poly128_t vreinterpretq_p128_p16 (poly16x8_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_s32 (int32x2_t) -+@item poly128_t vreinterpretq_p128_f32 (float32x4_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_s16 (int16x4_t) -+@item poly128_t vreinterpretq_p128_p64 (poly64x2_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_s8 (int8x8_t) -+@item poly128_t vreinterpretq_p128_s64 (int64x2_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_u64 (uint64x1_t) -+@item poly128_t vreinterpretq_p128_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_s64 (int64x1_t) -+@item poly128_t vreinterpretq_p128_s8 (int8x16_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_f32 (float32x2_t) -+@item poly128_t vreinterpretq_p128_s16 (int16x8_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_p16 (poly16x4_t) -+@item poly128_t vreinterpretq_p128_s32 (int32x4_t) - @end itemize - - - @itemize @bullet --@item uint16x4_t vreinterpret_u16_p8 (poly8x8_t) -+@item poly128_t vreinterpretq_p128_u8 (uint8x16_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_u32 (uint32x4_t) -+@item poly128_t vreinterpretq_p128_u16 (uint16x8_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_u8 (uint8x16_t) -+@item poly128_t vreinterpretq_p128_u32 (uint32x4_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_s32 (int32x4_t) -+@item int64x2_t vreinterpretq_s64_p8 (poly8x16_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_s16 (int16x8_t) -+@item int64x2_t vreinterpretq_s64_p16 (poly16x8_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_s8 (int8x16_t) -+@item int64x2_t vreinterpretq_s64_f32 (float32x4_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_u64 (uint64x2_t) -+@item int64x2_t vreinterpretq_s64_p64 (poly64x2_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_s64 (int64x2_t) -+@item int64x2_t vreinterpretq_s64_p128 (poly128_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_f32 (float32x4_t) -+@item int64x2_t vreinterpretq_s64_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item uint16x8_t vreinterpretq_u16_p16 (poly16x8_t) -+@item int64x2_t vreinterpretq_s64_s8 (int8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int64x2_t vreinterpretq_s64_s16 (int16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int64x2_t vreinterpretq_s64_s32 (int32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int64x2_t vreinterpretq_s64_u8 (uint8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int64x2_t vreinterpretq_s64_u16 (uint16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int64x2_t vreinterpretq_s64_u32 (uint32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_p8 (poly8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_p16 (poly16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_f32 (float32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_p64 (poly64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_p128 (poly128_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_s64 (int64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_s8 (int8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_s16 (int16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_s32 (int32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_u8 (uint8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_u16 (uint16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint64x2_t vreinterpretq_u64_u32 (uint32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_p8 (poly8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_p16 (poly16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_f32 (float32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_p64 (poly64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_p128 (poly128_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_s64 (int64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_u64 (uint64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_s16 (int16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_s32 (int32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_u8 (uint8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_u16 (uint16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int8x16_t vreinterpretq_s8_u32 (uint32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_p8 (poly8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_p16 (poly16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_f32 (float32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_p64 (poly64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_p128 (poly128_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_s64 (int64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_u64 (uint64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_s8 (int8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_s32 (int32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_u8 (uint8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_u16 (uint16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int16x8_t vreinterpretq_s16_u32 (uint32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_p8 (poly8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_p16 (poly16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_f32 (float32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_p64 (poly64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_p128 (poly128_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_s64 (int64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_u64 (uint64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_s8 (int8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_s16 (int16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_u8 (uint8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_u16 (uint16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item int32x4_t vreinterpretq_s32_u32 (uint32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_p8 (poly8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_p16 (poly16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_f32 (float32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_p64 (poly64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_p128 (poly128_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_s64 (int64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_u64 (uint64x2_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_s8 (int8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_s16 (int16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_s32 (int32x4_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_u16 (uint16x8_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint8x16_t vreinterpretq_u8_u32 (uint32x4_t) - @end itemize - - -@@ -11274,82 +11813,82 @@ - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_u16 (uint16x4_t) -+@item uint16x8_t vreinterpretq_u16_p16 (poly16x8_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_u8 (uint8x8_t) -+@item uint16x8_t vreinterpretq_u16_f32 (float32x4_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_s32 (int32x2_t) -+@item uint16x8_t vreinterpretq_u16_p64 (poly64x2_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_s16 (int16x4_t) -+@item uint16x8_t vreinterpretq_u16_p128 (poly128_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_s8 (int8x8_t) -+@item uint16x8_t vreinterpretq_u16_s64 (int64x2_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_u64 (uint64x1_t) -+@item uint16x8_t vreinterpretq_u16_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_s64 (int64x1_t) -+@item uint16x8_t vreinterpretq_u16_s8 (int8x16_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_f32 (float32x2_t) -+@item uint16x8_t vreinterpretq_u16_s16 (int16x8_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_p16 (poly16x4_t) -+@item uint16x8_t vreinterpretq_u16_s32 (int32x4_t) - @end itemize - - - @itemize @bullet --@item uint32x2_t vreinterpret_u32_p8 (poly8x8_t) -+@item uint16x8_t vreinterpretq_u16_u8 (uint8x16_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_u16 (uint16x8_t) -+@item uint16x8_t vreinterpretq_u16_u32 (uint32x4_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_u8 (uint8x16_t) -+@item uint32x4_t vreinterpretq_u32_p8 (poly8x16_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_s32 (int32x4_t) -+@item uint32x4_t vreinterpretq_u32_p16 (poly16x8_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_s16 (int16x8_t) -+@item uint32x4_t vreinterpretq_u32_f32 (float32x4_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_s8 (int8x16_t) -+@item uint32x4_t vreinterpretq_u32_p64 (poly64x2_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_u64 (uint64x2_t) -+@item uint32x4_t vreinterpretq_u32_p128 (poly128_t) - @end itemize - - -@@ -11359,19 +11898,111 @@ - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_f32 (float32x4_t) -+@item uint32x4_t vreinterpretq_u32_u64 (uint64x2_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_p16 (poly16x8_t) -+@item uint32x4_t vreinterpretq_u32_s8 (int8x16_t) - @end itemize - - - @itemize @bullet --@item uint32x4_t vreinterpretq_u32_p8 (poly8x16_t) -+@item uint32x4_t vreinterpretq_u32_s16 (int16x8_t) - @end itemize - - -+@itemize @bullet -+@item uint32x4_t vreinterpretq_u32_s32 (int32x4_t) -+@end itemize -+ - -+@itemize @bullet -+@item uint32x4_t vreinterpretq_u32_u8 (uint8x16_t) -+@end itemize -+ -+ -+@itemize @bullet -+@item uint32x4_t vreinterpretq_u32_u16 (uint16x8_t) -+@end itemize -+ -+ -+ -+ -+ -+@itemize @bullet -+@item poly128_t vldrq_p128(poly128_t const *) -+@end itemize -+ -+@itemize @bullet -+@item void vstrq_p128(poly128_t *, poly128_t) -+@end itemize -+ -+@itemize @bullet -+@item uint64x1_t vceq_p64 (poly64x1_t, poly64x1_t) -+@end itemize -+ -+@itemize @bullet -+@item uint64x1_t vtst_p64 (poly64x1_t, poly64x1_t) -+@end itemize -+ -+@itemize @bullet -+@item uint32_t vsha1h_u32 (uint32_t) -+@*@emph{Form of expected instruction(s):} @code{sha1h.32 @var{q0}, @var{q1}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1cq_u32 (uint32x4_t, uint32_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1c.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1pq_u32 (uint32x4_t, uint32_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1p.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1mq_u32 (uint32x4_t, uint32_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1m.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1su0q_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1su0.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1su1q_u32 (uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1su1.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256hq_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256h.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256h2q_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256h2.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256su0q_u32 (uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256su0.32 @var{q0}, @var{q1}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256su1q_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256su1.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item poly128_t vmull_p64 (poly64_t a, poly64_t b) -+@*@emph{Form of expected instruction(s):} @code{vmull.p64 @var{q0}, @var{d1}, @var{d2}} -+@end itemize -+ -+@itemize @bullet -+@item poly128_t vmull_high_p64 (poly64x2_t a, poly64x2_t b) -+@*@emph{Form of expected instruction(s):} @code{vmull.p64 @var{q0}, @var{d1}, @var{d2}} -+@end itemize - -Index: b/src/gcc/doc/md.texi -=================================================================== --- a/src/gcc/doc/md.texi +++ b/src/gcc/doc/md.texi @@ -1711,9 +1711,6 @@ reverted: --- gcc-4.8-4.8.2/debian/patches/gcc-linaro-no-local.diff +++ gcc-4.8-4.8.2.orig/debian/patches/gcc-linaro-no-local.diff @@ -1,189 +0,0 @@ -# DP: Revert Linaro local patch to build armv4t multilibs. - -Index: b/src/gcc/incpath.c -=================================================================== ---- a/src/gcc/incpath.c -+++ b/src/gcc/incpath.c -@@ -148,22 +148,20 @@ - if (!filename_ncmp (p->fname, cpp_GCC_INCLUDE_DIR, len)) - { - char *str = concat (iprefix, p->fname + len, NULL); -- if (p->multilib && imultilib) -- { -- str = reconcat (str, str, dir_separator_str, -- imultilib, NULL); -- add_path (str, SYSTEM, p->cxx_aware, false); -- } -- else -- add_path (str, SYSTEM, p->cxx_aware, false); -- -- if (p->multilib && imultiarch) -+ if (p->multilib == 1 && imultilib) -+ str = reconcat (str, str, dir_separator_str, -+ imultilib, NULL); -+ else if (p->multilib == 2) - { -- char *str = concat (iprefix, p->fname + len, NULL); -+ if (!imultiarch) -+ { -+ free (str); -+ continue; -+ } - str = reconcat (str, str, dir_separator_str, - imultiarch, NULL); -- add_path (str, SYSTEM, p->cxx_aware, false); - } -+ add_path (str, SYSTEM, p->cxx_aware, false); - } - } - } -@@ -173,7 +171,7 @@ - { - if (!p->cplusplus || cxx_stdinc) - { -- char *str, *str2; -+ char *str; - - /* Should this directory start with the sysroot? */ - if (sysroot && p->add_sysroot) -@@ -217,20 +215,19 @@ - else - str = update_path (p->fname, p->component); - -- str2 = xstrdup(str); -- if (p->multilib && imultilib) -+ if (p->multilib == 1 && imultilib) -+ str = reconcat (str, str, dir_separator_str, imultilib, NULL); -+ else if (p->multilib == 2) - { -- str = reconcat (str, str, dir_separator_str, imultilib, NULL); -- add_path (str, SYSTEM, p->cxx_aware, false); -+ if (!imultiarch) -+ { -+ free (str); -+ continue; -+ } -+ str = reconcat (str, str, dir_separator_str, imultiarch, NULL); - } -- else -- add_path (str, SYSTEM, p->cxx_aware, false); - -- if (p->multilib && imultiarch) -- { -- str2 = reconcat (str2, str2, dir_separator_str, imultiarch, NULL); -- add_path (str2, SYSTEM, p->cxx_aware, false); -- } -+ add_path (str, SYSTEM, p->cxx_aware, false); - } - } - } -Index: b/src/gcc/gcc.c -=================================================================== ---- a/src/gcc/gcc.c -+++ b/src/gcc/gcc.c -@@ -2227,7 +2227,7 @@ - } - - /* Now try the multiarch path. */ -- if (!skip_multi_dir && !multi_dir -+ if (!skip_multi_dir - && !pl->require_machine_suffix && multiarch_dir) - { - memcpy (path + len, multiarch_suffix, multiarch_len + 1); -@@ -2263,16 +2263,6 @@ - if (ret) - break; - } -- -- /* Now try the multiarch path. */ -- if (!skip_multi_dir -- && !pl->require_machine_suffix && multiarch_dir) -- { -- memcpy (path + len, multiarch_suffix, multiarch_len + 1); -- ret = callback (path, callback_info); -- if (ret) -- break; -- } - } - if (pl) - break; -@@ -7672,21 +7662,6 @@ - ++p; - } - -- if (first) -- { -- if (this_path_len > 3 -- && this_path[0] == '.' -- && this_path[1] == ':' -- && this_path[2] == ':') -- { -- char *new_multiarch_dir = XNEWVEC (char, this_path_len + 1); -- -- strncpy (new_multiarch_dir, this_path, this_path_len); -- new_multiarch_dir[this_path_len] = '\0'; -- multiarch_dir = &new_multiarch_dir[3]; -- } -- } -- - if (ok && first) - { - if (this_path_len != 1 -Index: b/src/gcc/ChangeLog.linaro -=================================================================== ---- a/src/gcc/ChangeLog.linaro -+++ b/src/gcc/ChangeLog.linaro -@@ -312,14 +312,6 @@ - GCC Linaro 4.8-2014.01 released. - * LINARO-VERSION: Update. - --2014-01-16 Zhenqiang Chen -- -- Linaro local patch for armv4t multilib support. -- * gcc/config/arm/t-mlibs: New file. -- * config.gcc: Add t-mlibs. -- * incpath.c (add_standard_paths): Try multilib path first. -- * gcc.c (for_each_path): Likewise. -- - 2013-12-21 Christophe Lyon - - * LINARO-VERSION: Bump version. -Index: b/src/gcc/config.gcc -=================================================================== ---- a/src/gcc/config.gcc -+++ b/src/gcc/config.gcc -@@ -878,7 +878,7 @@ - tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" - ;; - esac -- tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi arm/t-mlibs" -+ tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi" - tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h" - # Define multilib configuration for arm-linux-androideabi. - case ${target} in -Index: b/src/gcc/config/arm/t-mlibs -=================================================================== ---- a/src/gcc/config/arm/t-mlibs -+++ /dev/null -@@ -1,21 +0,0 @@ --# A set of predefined MULTILIB for different ARM targets. --# Through the configure option --with-multilib-list, user can customize the --# final MULTILIB implementation. -- --comma := , --space := --space += -- --MULTILIB_OPTIONS = marm --MULTILIB_DIRNAMES = arm --MULTILIB_OPTIONS += march=armv4t --MULTILIB_DIRNAMES += armv4t --MULTILIB_OPTIONS += mfloat-abi=soft --MULTILIB_DIRNAMES += soft -- --MULTILIB_EXCEPTIONS = -- --MULTILIB_REQUIRED = marm/march=armv4t/mfloat-abi=soft -- --MULTILIB_OSDIRNAMES = marm/march.armv4t/mfloat-abi.soft=!arm-linux-gnueabi -- diff -u gcc-4.8-4.8.2/debian/patches/gcc-linaro.diff gcc-4.8-4.8.2/debian/patches/gcc-linaro.diff --- gcc-4.8-4.8.2/debian/patches/gcc-linaro.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-linaro.diff @@ -1,39 +1,19 @@ -# DP: Changes for the Linaro 4.8-2014.03 release. +# DP: Changes for the Linaro 4.8-2013.11 release. -LANG=C svn diff svn://gcc.gnu.org/svn/gcc/branches/gcc-4_8-branch@208264 \ - svn://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_8-branch@208576 \ +LANG=C svn diff svn://gcc.gnu.org/svn/gcc/branches/gcc-4_8-branch@204657 \ + svn://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_8-branch@204811 \ | filterdiff --remove-timestamps --addoldprefix=a/src/ --addnewprefix=b/src/ --- a/src/libitm/ChangeLog.linaro +++ b/src/libitm/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -41,7 +21,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -49,7 +29,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -57,37 +37,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libgomp/ChangeLog.linaro +++ b/src/libgomp/ChangeLog.linaro -@@ -0,0 +1,59 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,39 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -103,7 +63,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -111,7 +71,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -119,7 +79,7 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libgomp/testsuite/libgomp.fortran/strassen.f90 +++ b/src/libgomp/testsuite/libgomp.fortran/strassen.f90 @@ -1,4 +1,5 @@ @@ -130,34 +90,14 @@ use omp_lib --- a/src/libquadmath/ChangeLog.linaro +++ b/src/libquadmath/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -165,7 +105,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -173,7 +113,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -181,7 +121,7 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libsanitizer/sanitizer_common/sanitizer_linux.cc +++ b/src/libsanitizer/sanitizer_common/sanitizer_linux.cc @@ -410,7 +410,9 @@ @@ -197,34 +137,14 @@ current_++; --- a/src/libsanitizer/ChangeLog.linaro +++ b/src/libsanitizer/ChangeLog.linaro -@@ -0,0 +1,66 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,46 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -232,7 +152,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -247,7 +167,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-06-04 Christophe Lyon + @@ -263,7 +183,7 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libsanitizer/configure.tgt +++ b/src/libsanitizer/configure.tgt @@ -29,6 +29,8 @@ @@ -277,34 +197,14 @@ ;; --- a/src/zlib/ChangeLog.linaro +++ b/src/zlib/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -312,7 +212,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -320,7 +220,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -328,37 +228,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libstdc++-v3/ChangeLog.linaro +++ b/src/libstdc++-v3/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -366,7 +246,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -374,7 +254,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -382,48 +262,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ---- a/src/configure.ac -+++ b/src/configure.ac -@@ -611,6 +611,8 @@ - - # Disable Java if libffi is not supported. - case "${target}" in -+ aarch64-*-*) -+ ;; - alpha*-*-*) - ;; - arm*-*-*) ++ * GCC Linaro 4.8-2013.04 released. --- a/src/intl/ChangeLog.linaro +++ b/src/intl/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -431,7 +280,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -439,7 +288,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -447,45 +296,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/ChangeLog.linaro +++ b/src/ChangeLog.linaro -@@ -0,0 +1,59 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-12-06 Michael Collison -+ -+ Backport from trunk r197997 -+ 2013-04-16 Andreas Schwab -+ -+ * configure.ac (aarch64-*-*): Don't disable java. -+ * configure: Regenerate. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,41 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -493,15 +314,25 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. ++ ++2013-07-09 Christophe Lyon ++ ++ gcc/ ++ * LINARO-VERSION: Bump version. + +2013-07-05 Christophe Lyon + + GCC Linaro 4.8-2013.07 released. + ++2013-06-18 Rob Savoye ++ ++ gcc/ ++ * LINARO-VERSION: Bump version. ++ +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -509,37 +340,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libmudflap/ChangeLog.linaro +++ b/src/libmudflap/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -547,7 +358,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -555,7 +366,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -563,37 +374,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/boehm-gc/ChangeLog.linaro +++ b/src/boehm-gc/ChangeLog.linaro -@@ -0,0 +1,64 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,44 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -601,7 +392,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -609,7 +400,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -630,7 +421,7 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/boehm-gc/include/private/gcconfig.h +++ b/src/boehm-gc/include/private/gcconfig.h @@ -60,6 +60,13 @@ @@ -666,7 +457,7 @@ /* ARM32 ==> Intel StrongARM */ /* IA64 ==> Intel IPF */ /* (e.g. Itanium) */ -@@ -1841,6 +1853,32 @@ +@@ -1833,6 +1845,32 @@ # define HEURISTIC1 # endif @@ -701,34 +492,14 @@ # define MACH_TYPE "ARM32" --- a/src/include/ChangeLog.linaro +++ b/src/include/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -736,7 +507,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -744,7 +515,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -752,37 +523,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libiberty/ChangeLog.linaro +++ b/src/libiberty/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -790,7 +541,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -798,7 +549,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -806,37 +557,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/lto-plugin/ChangeLog.linaro +++ b/src/lto-plugin/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -844,7 +575,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -852,7 +583,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -860,37 +591,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/contrib/regression/ChangeLog.linaro +++ b/src/contrib/regression/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -898,7 +609,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -906,7 +617,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -914,7 +625,7 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/contrib/config-list.mk +++ b/src/contrib/config-list.mk @@ -11,7 +11,8 @@ @@ -929,34 +640,14 @@ arm-linux-androideabi arm-uclinux_eabi arm-eabi \ --- a/src/contrib/ChangeLog.linaro +++ b/src/contrib/ChangeLog.linaro -@@ -0,0 +1,58 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,38 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -964,7 +655,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -972,7 +663,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -987,37 +678,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/contrib/reghunt/ChangeLog.linaro +++ b/src/contrib/reghunt/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1025,7 +696,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1033,7 +704,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1041,45 +712,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libatomic/ChangeLog.linaro +++ b/src/libatomic/ChangeLog.linaro -@@ -0,0 +1,59 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-12-06 Michael Collison -+ -+ Backport from trunk r203774 -+ 2013-10-17 Michael Hudson-Doyle -+ -+ * libatomic/configure.tgt (aarch64*): Remove code preventing -+ build. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1087,7 +730,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1095,7 +738,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1103,51 +746,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ---- a/src/libatomic/configure.tgt -+++ b/src/libatomic/configure.tgt -@@ -95,11 +95,6 @@ - - # Other system configury - case "${target}" in -- aarch64*) -- # This is currently not supported in AArch64. -- UNSUPPORTED=1 -- ;; -- - arm*-*-linux*) - # OS support for atomic primitives. - config_path="${config_path} linux/arm posix" ++ * GCC Linaro 4.8-2013.04 released. --- a/src/config/ChangeLog.linaro +++ b/src/config/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1155,7 +764,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1163,7 +772,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1171,37 +780,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libbacktrace/ChangeLog.linaro +++ b/src/libbacktrace/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1209,7 +798,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1217,7 +806,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1225,37 +814,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libjava/libltdl/ChangeLog.linaro +++ b/src/libjava/libltdl/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1263,7 +832,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1271,7 +840,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1279,72 +848,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ---- a/src/libjava/configure.host -+++ b/src/libjava/configure.host -@@ -81,6 +81,11 @@ - - # This case statement supports per-CPU defaults. - case "${host}" in -+ aarch64*-linux*) -+ libgcj_interpreter=yes -+ sysdeps_dir=aarch64 -+ ATOMICSPEC=-fuse-atomic-builtins -+ ;; - arm*-elf) - with_libffi_default=no - PROCESS=Ecos -@@ -289,6 +294,12 @@ - sysdeps_dir=i386 - DIVIDESPEC=-f%{m32:no-}use-divide-subroutine - ;; -+ aarch64*-linux* ) -+ slow_pthread_self=no -+ can_unwind_signal=no -+ CHECKREFSPEC=-fcheck-references -+ DIVIDESPEC=-fuse-divide-subroutine -+ ;; - arm*-linux* ) - slow_pthread_self=no - can_unwind_signal=no ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libjava/ChangeLog.linaro +++ b/src/libjava/ChangeLog.linaro -@@ -0,0 +1,59 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-12-06 Michael Collison -+ -+ Backport from trunk r197997 -+ 2013-04-16 Andreas Schwab -+ -+ * configure.host: Add support for aarch64. -+ * sysdep/aarch64/locks.h: New file. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1352,7 +866,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1360,7 +874,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1368,44 +882,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libjava/classpath/ChangeLog.linaro +++ b/src/libjava/classpath/ChangeLog.linaro -@@ -0,0 +1,58 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-12-06 Michael Collison -+ -+ Backport from trunk r197997 -+ 2013-04-16 Andreas Schwab -+ -+ * native/fdlibm/ieeefp.h: Add support for aarch64. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1413,7 +900,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1421,7 +908,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1429,114 +916,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ---- a/src/libjava/classpath/native/fdlibm/ieeefp.h -+++ b/src/libjava/classpath/native/fdlibm/ieeefp.h -@@ -4,6 +4,14 @@ - #ifndef __IEEE_BIG_ENDIAN - #ifndef __IEEE_LITTLE_ENDIAN - -+#ifdef __aarch64__ -+#ifdef __AARCH64EB__ -+#define __IEEE_BIG_ENDIAN -+#else -+#define __IEEE_LITTLE_ENDIAN -+#endif -+#endif -+ - #ifdef __alpha__ - #define __IEEE_LITTLE_ENDIAN - #endif ---- a/src/libjava/sysdep/aarch64/locks.h -+++ b/src/libjava/sysdep/aarch64/locks.h -@@ -0,0 +1,57 @@ -+// locks.h - Thread synchronization primitives. AArch64 implementation. -+ -+#ifndef __SYSDEP_LOCKS_H__ -+#define __SYSDEP_LOCKS_H__ -+ -+typedef size_t obj_addr_t; /* Integer type big enough for object */ -+ /* address. */ -+ -+// Atomically replace *addr by new_val if it was initially equal to old. -+// Return true if the comparison succeeded. -+// Assumed to have acquire semantics, i.e. later memory operations -+// cannot execute before the compare_and_swap finishes. -+inline static bool -+compare_and_swap(volatile obj_addr_t *addr, -+ obj_addr_t old, -+ obj_addr_t new_val) -+{ -+ return __sync_bool_compare_and_swap(addr, old, new_val); -+} -+ -+// Set *addr to new_val with release semantics, i.e. making sure -+// that prior loads and stores complete before this -+// assignment. -+inline static void -+release_set(volatile obj_addr_t *addr, obj_addr_t new_val) -+{ -+ __sync_synchronize(); -+ *addr = new_val; -+} -+ -+// Compare_and_swap with release semantics instead of acquire semantics. -+// On many architecture, the operation makes both guarantees, so the -+// implementation can be the same. -+inline static bool -+compare_and_swap_release(volatile obj_addr_t *addr, -+ obj_addr_t old, -+ obj_addr_t new_val) -+{ -+ return __sync_bool_compare_and_swap(addr, old, new_val); -+} -+ -+// Ensure that subsequent instructions do not execute on stale -+// data that was loaded from memory before the barrier. -+inline static void -+read_barrier() -+{ -+ __sync_synchronize(); -+} -+ -+// Ensure that prior stores to memory are completed with respect to other -+// processors. -+inline static void -+write_barrier() -+{ -+ __sync_synchronize(); -+} -+#endif ++ * GCC Linaro 4.8-2013.04 released. --- a/src/gnattools/ChangeLog.linaro +++ b/src/gnattools/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1544,7 +934,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1552,7 +942,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1560,37 +950,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/maintainer-scripts/ChangeLog.linaro +++ b/src/maintainer-scripts/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1598,7 +968,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1606,7 +976,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1614,48 +984,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ---- a/src/configure -+++ b/src/configure -@@ -3272,6 +3272,8 @@ - - # Disable Java if libffi is not supported. - case "${target}" in -+ aarch64-*-*) -+ ;; - alpha*-*-*) - ;; - arm*-*-*) ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libgcc/ChangeLog.linaro +++ b/src/libgcc/ChangeLog.linaro -@@ -0,0 +1,61 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,41 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1663,7 +1002,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1671,7 +1010,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1689,7 +1028,7 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libgcc/config/aarch64/sfp-machine.h +++ b/src/libgcc/config/aarch64/sfp-machine.h @@ -24,8 +24,8 @@ @@ -1705,34 +1044,14 @@ typedef int TItype __attribute__ ((mode (TI))); --- a/src/libgcc/config/libbid/ChangeLog.linaro +++ b/src/libgcc/config/libbid/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1740,7 +1059,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1748,7 +1067,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1756,37 +1075,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libdecnumber/ChangeLog.linaro +++ b/src/libdecnumber/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1794,7 +1093,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1802,7 +1101,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1810,43 +1109,11 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/gcc/LINARO-VERSION +++ b/src/gcc/LINARO-VERSION @@ -0,0 +1 @@ -+4.8-2014.03 ---- a/src/gcc/targhooks.c -+++ b/src/gcc/targhooks.c -@@ -1042,20 +1042,17 @@ - unsigned *cost = (unsigned *) data; - unsigned retval = 0; - -- if (flag_vect_cost_model) -- { -- tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; -- int stmt_cost = default_builtin_vectorization_cost (kind, vectype, -+ tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; -+ int stmt_cost = default_builtin_vectorization_cost (kind, vectype, - misalign); -- /* Statements in an inner loop relative to the loop being -- vectorized are weighted more heavily. The value here is -- arbitrary and could potentially be improved with analysis. */ -- if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) -- count *= 50; /* FIXME. */ -+ /* Statements in an inner loop relative to the loop being -+ vectorized are weighted more heavily. The value here is -+ arbitrary and could potentially be improved with analysis. */ -+ if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) -+ count *= 50; /* FIXME. */ - -- retval = (unsigned) (count * stmt_cost); -- cost[where] += retval; -- } -+ retval = (unsigned) (count * stmt_cost); -+ cost[where] += retval; - - return retval; - } ++4.8-2013.10-1~dev --- a/src/gcc/hooks.c +++ b/src/gcc/hooks.c @@ -147,6 +147,14 @@ @@ -1876,34 +1143,14 @@ HOST_WIDE_INT, --- a/src/gcc/c-family/ChangeLog.linaro +++ b/src/gcc/c-family/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1911,7 +1158,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1919,7 +1166,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1927,37 +1174,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/gcc/java/ChangeLog.linaro +++ b/src/gcc/java/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -1965,7 +1192,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -1973,7 +1200,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -1981,37 +1208,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/gcc/c/ChangeLog.linaro +++ b/src/gcc/c/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -2019,7 +1226,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -2027,7 +1234,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -2035,10 +1242,10 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/gcc/target.def +++ b/src/gcc/target.def -@@ -1289,7 +1289,8 @@ +@@ -1289,13 +1289,24 @@ "", tree, (unsigned int /*location_t*/ loc, tree fndecl, void *arglist), NULL) @@ -2048,7 +1255,6 @@ DEFHOOK (fold_builtin, "", -@@ -1296,6 +1297,16 @@ tree, (tree fndecl, int n_args, tree *argp, bool ignore), hook_tree_tree_int_treep_bool_null) @@ -2065,81 +1271,6 @@ /* Target hook is used to compare the target attributes in two functions to determine which function's features get higher priority. This is used during function multi-versioning to figure out the order in which two ---- a/src/gcc/incpath.c -+++ b/src/gcc/incpath.c -@@ -148,20 +148,22 @@ - if (!filename_ncmp (p->fname, cpp_GCC_INCLUDE_DIR, len)) - { - char *str = concat (iprefix, p->fname + len, NULL); -- if (p->multilib == 1 && imultilib) -- str = reconcat (str, str, dir_separator_str, -- imultilib, NULL); -- else if (p->multilib == 2) -+ if (p->multilib && imultilib) -+ { -+ str = reconcat (str, str, dir_separator_str, -+ imultilib, NULL); -+ add_path (str, SYSTEM, p->cxx_aware, false); -+ } -+ else -+ add_path (str, SYSTEM, p->cxx_aware, false); -+ -+ if (p->multilib && imultiarch) - { -- if (!imultiarch) -- { -- free (str); -- continue; -- } -+ char *str = concat (iprefix, p->fname + len, NULL); - str = reconcat (str, str, dir_separator_str, - imultiarch, NULL); -+ add_path (str, SYSTEM, p->cxx_aware, false); - } -- add_path (str, SYSTEM, p->cxx_aware, false); - } - } - } -@@ -171,7 +173,7 @@ - { - if (!p->cplusplus || cxx_stdinc) - { -- char *str; -+ char *str, *str2; - - /* Should this directory start with the sysroot? */ - if (sysroot && p->add_sysroot) -@@ -215,19 +217,20 @@ - else - str = update_path (p->fname, p->component); - -- if (p->multilib == 1 && imultilib) -- str = reconcat (str, str, dir_separator_str, imultilib, NULL); -- else if (p->multilib == 2) -+ str2 = xstrdup(str); -+ if (p->multilib && imultilib) - { -- if (!imultiarch) -- { -- free (str); -- continue; -- } -- str = reconcat (str, str, dir_separator_str, imultiarch, NULL); -+ str = reconcat (str, str, dir_separator_str, imultilib, NULL); -+ add_path (str, SYSTEM, p->cxx_aware, false); - } -+ else -+ add_path (str, SYSTEM, p->cxx_aware, false); - -- add_path (str, SYSTEM, p->cxx_aware, false); -+ if (p->multilib && imultiarch) -+ { -+ str2 = reconcat (str2, str2, dir_separator_str, imultiarch, NULL); -+ add_path (str2, SYSTEM, p->cxx_aware, false); -+ } - } - } - } --- a/src/gcc/rtlanal.c +++ b/src/gcc/rtlanal.c @@ -1199,6 +1199,10 @@ @@ -2174,7 +1305,7 @@ fi -@@ -25984,8 +25985,9 @@ +@@ -25913,8 +25914,9 @@ # ??? Once 2.11 is released, probably need to add first known working # version to the per-target configury. case "$cpu_type" in @@ -2186,56 +1317,6 @@ insn="nop" ;; ia64 | s390) ---- a/src/gcc/gcc.c -+++ b/src/gcc/gcc.c -@@ -2227,7 +2227,7 @@ - } - - /* Now try the multiarch path. */ -- if (!skip_multi_dir -+ if (!skip_multi_dir && !multi_dir - && !pl->require_machine_suffix && multiarch_dir) - { - memcpy (path + len, multiarch_suffix, multiarch_len + 1); -@@ -2263,6 +2263,16 @@ - if (ret) - break; - } -+ -+ /* Now try the multiarch path. */ -+ if (!skip_multi_dir -+ && !pl->require_machine_suffix && multiarch_dir) -+ { -+ memcpy (path + len, multiarch_suffix, multiarch_len + 1); -+ ret = callback (path, callback_info); -+ if (ret) -+ break; -+ } - } - if (pl) - break; -@@ -7662,6 +7672,21 @@ - ++p; - } - -+ if (first) -+ { -+ if (this_path_len > 3 -+ && this_path[0] == '.' -+ && this_path[1] == ':' -+ && this_path[2] == ':') -+ { -+ char *new_multiarch_dir = XNEWVEC (char, this_path_len + 1); -+ -+ strncpy (new_multiarch_dir, this_path, this_path_len); -+ new_multiarch_dir[this_path_len] = '\0'; -+ multiarch_dir = &new_multiarch_dir[3]; -+ } -+ } -+ - if (ok && first) - { - if (this_path_len != 1 --- a/src/gcc/gensupport.c +++ b/src/gcc/gensupport.c @@ -1717,6 +1717,21 @@ @@ -2281,34 +1362,14 @@ return 0; --- a/src/gcc/objc/ChangeLog.linaro +++ b/src/gcc/objc/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -2316,7 +1377,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -2324,7 +1385,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -2332,479 +1393,72 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/tree-ssa-uncprop.c -+++ b/src/gcc/tree-ssa-uncprop.c -@@ -466,12 +466,11 @@ - struct equiv_hash_elt equiv_hash_elt; - void **slot; - -- /* If the argument is not an invariant, and refers to the same -- underlying variable as the PHI result, then there's no -- point in un-propagating the argument. */ -+ /* If the argument is not an invariant and can be potentially -+ coalesced with the result, then there's no point in -+ un-propagating the argument. */ - if (!is_gimple_min_invariant (arg) -- && (SSA_NAME_VAR (arg) == SSA_NAME_VAR (res) -- && TREE_TYPE (arg) == TREE_TYPE (res))) -+ && gimple_can_coalesce_p (arg, res)) - continue; - - /* Lookup this argument's value in the hash table. */ -@@ -485,7 +484,7 @@ - int j; - - /* Walk every equivalence with the same value. If we find -- one with the same underlying variable as the PHI result, -+ one that can potentially coalesce with the PHI rsult, - then replace the value in the argument with its equivalent - SSA_NAME. Use the most recent equivalence as hopefully - that results in shortest lifetimes. */ -@@ -493,8 +492,7 @@ - { - tree equiv = elt->equivalences[j]; - -- if (SSA_NAME_VAR (equiv) == SSA_NAME_VAR (res) -- && TREE_TYPE (equiv) == TREE_TYPE (res)) -+ if (gimple_can_coalesce_p (equiv, res)) - { - SET_PHI_ARG_DEF (phi, e->dest_idx, equiv); - break; ++ * GCC Linaro 4.8-2013.04 released. --- a/src/gcc/ChangeLog.linaro +++ b/src/gcc/ChangeLog.linaro -@@ -0,0 +1,3063 @@ -+2014-03-11 Yvan Roux +@@ -0,0 +1,2681 @@ ++2013-11-06 Christophe Lyon + -+ GCC Linaro 4.8-2014.03 released. -+ * LINARO-VERSION: Update. ++ Revert backport from trunk r197526. ++ 2013-04-05 Greta Yorsh + -+2014-02-13 Yvan Roux ++ * config/arm/arm.md (negdi_extendsidi): New pattern. ++ (negdi_zero_extendsidi): Likewise. + -+ * LINARO-VERSION: Bump version. ++2013-11-05 Zhenqiang Chen + -+2014-02-11 Yvan Roux ++ Backport from trunk r203267, r203603 and r204247. ++ 2013-10-08 Zhenqiang Chen + -+ GCC Linaro 4.8-2014.02 released. -+ * LINARO-VERSION: Update. ++ PR target/58423 ++ * config/arm/arm.c (arm_emit_ldrd_pop): Attach ++ RTX_FRAME_RELATED_P on INSN. + -+2014-02-10 Michael Collison ++ 2013-10-15 Matthew Gretton-Dann ++ Ramana Radhakrishnan + -+ Backport from trunk r206518 -+ 2014-01-10 Kyrylo Tkachov ++ * config/arm/t-aprofile: New file. ++ * config.gcc: Handle --with-multilib-list option. + -+ * config/arm/arm.c (arm_init_iwmmxt_builtins): Skip -+ non-iwmmxt builtins. ++ 2013-10-31 Zhenqiang Chen + -+2014-02-10 Michael Collison ++ * lower-subreg.c (resolve_simple_move): Copy REG_INC note. + -+ Backport from trunk r206151 -+ 2013-12-20 Kyrylo Tkachov ++2013-10-17 Christophe Lyon + -+ * config/arm/neon.ml (crypto_intrinsics): Add vceq_64 and vtst_p64. -+ * config/arm/arm_neon.h: Regenerate. -+ * config/arm/neon-docgen.ml: Add vceq_p64 and vtst_p64. -+ * doc/arm-neon-intrinsics.texi: Regenerate. ++ Backport from trunk r200956 ++ 2013-07-15 Marcus Shawcroft + -+2014-02-10 Michael Collison ++ * config/aarch64/aarch64-protos.h (aarch64_symbol_type): ++ Define SYMBOL_TINY_GOT, update comment. ++ * config/aarch64/aarch64.c ++ (aarch64_load_symref_appropriately): Handle SYMBOL_TINY_GOT. ++ (aarch64_expand_mov_immediate): Likewise. ++ (aarch64_print_operand): Likewise. ++ (aarch64_classify_symbol): Likewise. ++ * config/aarch64/aarch64.md (UNSPEC_GOTTINYPIC): Define. ++ (ldr_got_tiny): Define. + -+ Backport from trunk r206149 -+ 2013-12-20 Kyrylo Tkachov ++2013-10-16 Christophe Lyon + -+ * config/arm/arm_acle.h: Add underscores before variables. ++ * LINARO-VERSION: Bump version. + -+2014-02-10 Michael Collison ++2013-10-15 Christophe Lyon + -+ Backport from trunk r206132 -+ 2013-12-19 Kyrylo Tkachov ++ GCC Linaro 4.8-2013.10 released. + -+ * config/arm/neon-docgen.ml: Add crypto intrinsics documentation. -+ * doc/arm-neon-intrinsics.texi: Regenerate. ++2013-10-09 Christophe Lyon + -+2014-02-10 Michael Collison ++ Backport from trunk r198526,198527,200020,200595. ++ 2013-05-02 Ian Bolton + -+ Backport from trunk r206131 -+ 2013-12-19 Kyrylo Tkachov ++ * config/aarch64/aarch64.md (*and_one_cmpl3_compare0): ++ New pattern. ++ (*and_one_cmplsi3_compare0_uxtw): Likewise. ++ (*and_one_cmpl_3_compare0): Likewise. ++ (*and_one_cmpl_si3_compare0_uxtw): Likewise. + -+ * config/arm/neon-testgen.ml (effective_target): Handle "CRYPTO". -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206130 -+ 2013-12-19 Kyrylo Tkachov -+ -+ * config/arm/arm.c (enum arm_builtins): Add crypto builtins. -+ (arm_init_neon_builtins): Handle crypto builtins. -+ (bdesc_2arg): Likewise. -+ (bdesc_1arg): Likewise. -+ (bdesc_3arg): New table. -+ (arm_expand_ternop_builtin): New function. -+ (arm_expand_unop_builtin): Handle sha1h explicitly. -+ (arm_expand_builtin): Handle ternary builtins. -+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): -+ Define __ARM_FEATURE_CRYPTO. -+ * config/arm/arm.md: Include crypto.md. -+ (is_neon_type): Add crypto types. -+ * config/arm/arm_neon_builtins.def: Add TImode reinterprets. -+ * config/arm/crypto.def: New. -+ * config/arm/crypto.md: Likewise. -+ * config/arm/iterators.md (CRYPTO_UNARY): New int iterator. -+ (CRYPTO_BINARY): Likewise. -+ (CRYPTO_TERNARY): Likewise. -+ (CRYPTO_SELECTING): Likewise. -+ (crypto_pattern): New int attribute. -+ (crypto_size_sfx): Likewise. -+ (crypto_mode): Likewise. -+ (crypto_type): Likewise. -+ * config/arm/neon-gen.ml: Handle poly64_t and poly128_t types. -+ Handle crypto intrinsics. -+ * config/arm/neon.ml: Add support for poly64 and polt128 types -+ and intrinsics. Define crypto intrinsics. -+ * config/arm/neon.md (neon_vreinterpretti): New pattern. -+ (neon_vreinterpretv16qi): Use VQXMOV mode iterator. -+ (neon_vreinterpretv8hi): Likewise. -+ (neon_vreinterpretv4si): Likewise. -+ (neon_vreinterpretv4sf): Likewise. -+ (neon_vreinterpretv2di): Likewise. -+ * config/arm/unspecs.md (UNSPEC_AESD, UNSPEC_AESE, UNSPEC_AESIMC, -+ UNSPEC_AESMC, UNSPEC_SHA1C, UNSPEC_SHA1M, UNSPEC_SHA1P, UNSPEC_SHA1H, -+ UNSPEC_SHA1SU0, UNSPEC_SHA1SU1, UNSPEC_SHA256H, UNSPEC_SHA256H2, -+ UNSPEC_SHA256SU0, UNSPEC_SHA256SU1, VMULLP64): Define. -+ * config/arm/arm_neon.h: Regenerate. -+ -+ Modifications needed to backport into linaro-4_8-branch: -+ * config/arm/arm.md (attribute neon_type): neon_crypto_aes, -+ neon_crypto_sha1_xor, neon_crypto_sha1_fast, -+ neon_crypto_sha1_slow, neon_crypto_sha256_fast, -+ neon_crypto_sha256_slow, neon_mul_d_long: New. -+ instead of: -+ * config/arm/arm.md: Include crypto.md. -+ (is_neon_type): Add crypto types. -+ -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206128 -+ 2013-12-19 Kyrylo Tkachov -+ -+ * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi. -+ * config.gcc (extra_headers): Add arm_acle.h. -+ * config/arm/arm.c (FL_CRC32): Define. -+ (arm_have_crc): Likewise. -+ (arm_option_override): Set arm_have_crc. -+ (arm_builtins): Add CRC32 builtins. -+ (bdesc_2arg): Likewise. -+ (arm_init_crc32_builtins): New function. -+ (arm_init_builtins): Initialise CRC32 builtins. -+ (arm_file_start): Handle architecture extensions. -+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __ARM_FEATURE_CRC32. -+ Define __ARM_32BIT_STATE. -+ (TARGET_CRC32): Define. -+ * config/arm/arm-arches.def: Add armv8-a+crc. -+ * config/arm/arm-tables.opt: Regenerate. -+ * config/arm/arm.md (type): Add crc. -+ (): New insn. -+ * config/arm/arm_acle.h: New file. -+ * config/arm/iterators.md (CRC): New int iterator. -+ (crc_variant, crc_mode): New int attributes. -+ * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H, UNSPEC_CRC32W, -+ UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs. -+ * doc/invoke.texi: Document -march=armv8-a+crc option. -+ * doc/extend.texi: Document ACLE intrinsics. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206120 -+ 2013-12-19 Tejas Belagod -+ -+ * config/aarch64/aarch64-builtins.c (aarch64_init_simd_builtins): -+ Define builtin types for poly64_t poly128_t. -+ (TYPES_BINOPP, aarch64_types_binopp_qualifiers): New. -+ * aarch64/aarch64-simd-builtins.def: Update builtins table. -+ * config/aarch64/aarch64-simd.md (aarch64_crypto_pmulldi, -+ aarch64_crypto_pmullv2di): New. -+ * config/aarch64/aarch64.c (aarch64_simd_mangle_map): Update table for -+ poly64x2_t mangler. -+ * config/aarch64/arm_neon.h (poly64x2_t, poly64_t, poly128_t): Define. -+ (vmull_p64, vmull_high_p64): New. -+ * config/aarch64/iterators.md (UNSPEC_PMULL<2>): New. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206119 -+ 2013-12-19 Tejas Belagod -+ -+ * config/aarch64/aarch64-simd-builtins.def: Update builtins table. -+ * config/aarch64/aarch64-simd.md (aarch64_crypto_sha256hv4si, -+ aarch64_crypto_sha256su0v4si, aarch64_crypto_sha256su1v4si): New. -+ * config/aarch64/arm_neon.h (vsha256hq_u32, vsha256h2q_u32, -+ vsha256su0q_u32, vsha256su1q_u32): New. -+ * config/aarch64/iterators.md (UNSPEC_SHA256H<2>, UNSPEC_SHA256SU<01>): -+ New. -+ (CRYPTO_SHA256): New int iterator. -+ (sha256_op): New int attribute. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206118 -+ 2013-12-19 Tejas Belagod -+ -+ * config/aarch64/aarch64-simd-builtins.def: Update builtins table. -+ * config/aarch64/aarch64-builtins.c (aarch64_types_ternopu_qualifiers, -+ TYPES_TERNOPU): New. -+ * config/aarch64/aarch64-simd.md (aarch64_crypto_sha1hsi, -+ aarch64_crypto_sha1su1v4si, aarch64_crypto_sha1v4si, -+ aarch64_crypto_sha1su0v4si): New. -+ * config/aarch64/arm_neon.h (vsha1cq_u32, sha1mq_u32, vsha1pq_u32, -+ vsha1h_u32, vsha1su0q_u32, vsha1su1q_u32): New. -+ * config/aarch64/iterators.md (UNSPEC_SHA1, UNSPEC_SHA1SU<01>): -+ New. -+ (CRYPTO_SHA1): New int iterator. -+ (sha1_op): New int attribute. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206117 -+ 2013-12-19 Tejas Belagod -+ -+ * config/aarch64/aarch64-simd-builtins.def: Update builtins table. -+ * config/aarch64/aarch64-builtins.c (aarch64_types_binopu_qualifiers, -+ TYPES_BINOPU): New. -+ * config/aarch64/aarch64-simd.md (aarch64_crypto_aesv16qi, -+ aarch64_crypto_aesv16qi): New. -+ * config/aarch64/arm_neon.h (vaeseq_u8, vaesdq_u8, vaesmcq_u8, -+ vaesimcq_u8): New. -+ * config/aarch64/iterators.md (UNSPEC_AESE, UNSPEC_AESD, UNSPEC_AESMC, -+ UNSPEC_AESIMC): New. -+ (CRYPTO_AES, CRYPTO_AESMC): New int iterators. -+ (aes_op, aesmc_op): New int attributes. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206115 -+ 2013-12-19 Tejas Belagod -+ -+ * config/arm/types.md (neon_mul_d_long, crypto_aes, crypto_sha1_xor, -+ crypto_sha1_fast, crypto_sha1_slow, crypto_sha256_fast, -+ crypto_sha256_slow): New. -+ -+ Modifications needed to backport into linaro-4_8-branch: -+ * config/aarch64/aarch64-simd.md (attribute simd_type): -+ (simd_mul_d_long, simd_crypto_aes, simd_crypto_sha1_xor, -+ simd_crypto_sha1_fast, simd_crypto_sha1_slow, simd_crypto_sha256_fast, -+ simd_crypto_sha256_slow) : New. -+ instead of the above change. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206114 -+ 2013-12-19 Tejas Belagod -+ -+ * config/aarch64/aarch64.h (TARGET_CRYPTO): New. -+ (__ARM_FEATURE_CRYPTO): Define if TARGET_CRYPTO is true. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r205384. -+ 2013-11-26 James Greenhalgh -+ -+ * config/aarch64/aarch64-builtins.c -+ (aarch64_type_qualifiers): Add qualifier_poly. -+ (aarch64_build_scalar_type): Also build Poly types. -+ (aarch64_build_vector_type): Likewise. -+ (aarch64_build_type): Likewise. -+ (aarch64_build_signed_type): New. -+ (aarch64_build_unsigned_type): Likewise. -+ (aarch64_build_poly_type): Likewise. -+ (aarch64_init_simd_builtins): Also handle Poly types. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r205383. -+ 2013-11-26 James Greenhalgh -+ -+ * config/aarch64/aarch64-builtins.c -+ (VAR1): Use new naming scheme for aarch64_builtins. -+ (aarch64_builtin_vectorized_function): Use new -+ aarch64_builtins names. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r205092. -+ 2013-11-20 James Greenhalgh -+ -+ * gcc/config/aarch64/aarch64-builtins.c -+ (aarch64_simd_itype): Remove. -+ (aarch64_simd_builtin_datum): Remove itype, add -+ qualifiers pointer. -+ (VAR1): Use qualifiers. -+ (aarch64_build_scalar_type): New. -+ (aarch64_build_vector_type): Likewise. -+ (aarch64_build_type): Likewise. -+ (aarch64_init_simd_builtins): Refactor, remove special cases, -+ consolidate main loop. -+ (aarch64_simd_expand_args): Likewise. -+ -+2014-02-01 Christophe Lyon -+ -+ Backport from trunk r202875,202980. -+ 2013-09-24 Xinliang David Li -+ -+ * tree-vect-data-refs.c (vect_enhance_data_refs_alignment): -+ Check max peel iterations parameter. -+ * param.def: New parameter. -+ * doc/invoke.texi: Document New parameter. -+ -+ 2013-09-27 Xinliang David Li -+ -+ * opts.c (finish_options): Adjust parameters -+ according to vect cost model. -+ (common_handle_option): Set dynamic vect cost -+ model for FDO. -+ targhooks.c (default_add_stmt_cost): Compute stmt cost -+ unconditionally. -+ * tree-vect-loop.c (vect_estimate_min_profitable_iters): -+ Use helper function. -+ * tree-vectorizer.h (unlimited_cost_model): New function. -+ * tree-vect-slp.c (vect_slp_analyze_bb_1): Use helper function. -+ * tree-vect-data-refs.c (vect_peeling_hash_insert): Use helper -+ function. -+ (vect_enhance_data_refs_alignment): Ditto. -+ * flag-types.h: New enum. -+ * common/config/i386/i386-common.c (ix86_option_init_struct): -+ No need to initialize vect_cost_model flag. -+ * config/i386/i386.c (ix86_add_stmt_cost): Compute stmt cost -+ unconditionally. -+ -+2014-01-21 Zhenqiang Chen -+ -+ Backport from trunk r200103 -+ 2013-06-15 Jeff Law -+ -+ * gimple.h (gimple_can_coalesce_p): Prototype. -+ * tree-ssa-coalesce.c (gimple_can_coalesce_p): New function. -+ (create_outofssa_var_map, coalesce_partitions): Use it. -+ * tree-ssa-uncprop.c (uncprop_into_successor_phis): Similarly. -+ * tree-ssa-live.c (var_map_base_init): Use TYPE_CANONICAL -+ if it's available. -+ -+2014-01-21 Christophe Lyon -+ -+ * LINARO-VERSION: Bump version. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ * LINARO-VERSION: Update. -+ -+2014-01-16 Zhenqiang Chen -+ -+ Linaro local patch for armv4t multilib support. -+ * gcc/config/arm/t-mlibs: New file. -+ * config.gcc: Add t-mlibs. -+ * incpath.c (add_standard_paths): Try multilib path first. -+ * gcc.c (for_each_path): Likewise. -+ -+2013-12-21 Christophe Lyon -+ -+ * LINARO-VERSION: Bump version. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ * LINARO-VERSION: Update. -+ -+2013-12-06 Christophe Lyon -+ -+ Backport from trunk r204737. -+ 2013-11-13 Christophe Lyon -+ -+ * config/aarch64/aarch64.h (FRAME_GROWS_DOWNWARD): Define to 1. -+ * config/aarch64/aarch64.c (aarch64_initial_elimination_offset): -+ Update offset calculations. -+ -+2013-12-06 Christophe Lyon -+ -+ Backport from trunk r203327. -+ 2013-10-09 Zhenqiang Chen -+ -+ * tree-ssa-phiopts.c (rhs_is_fed_for_value_replacement): New function. -+ (operand_equal_for_value_replacement): New function, extracted from -+ value_replacement and enhanced to catch more cases. -+ (value_replacement): Use operand_equal_for_value_replacement. -+ -+2013-11-18 Christophe Lyon -+ -+ * LINARO-VERSION: Bump version. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ * LINARO-VERSION: Update. -+ -+2013-11-06 Christophe Lyon -+ -+ Revert backport from trunk r197526. -+ 2013-04-05 Greta Yorsh -+ -+ * config/arm/arm.md (negdi_extendsidi): New pattern. -+ (negdi_zero_extendsidi): Likewise. -+ -+2013-11-05 Zhenqiang Chen -+ -+ Backport from trunk r203267, r203603 and r204247. -+ 2013-10-08 Zhenqiang Chen -+ -+ PR target/58423 -+ * config/arm/arm.c (arm_emit_ldrd_pop): Attach -+ RTX_FRAME_RELATED_P on INSN. -+ -+ 2013-10-15 Matthew Gretton-Dann -+ Ramana Radhakrishnan -+ -+ * config/arm/t-aprofile: New file. -+ * config.gcc: Handle --with-multilib-list option. -+ -+ 2013-10-31 Zhenqiang Chen -+ -+ * lower-subreg.c (resolve_simple_move): Copy REG_INC note. -+ -+2013-10-17 Christophe Lyon -+ -+ Backport from trunk r200956 -+ 2013-07-15 Marcus Shawcroft -+ -+ * config/aarch64/aarch64-protos.h (aarch64_symbol_type): -+ Define SYMBOL_TINY_GOT, update comment. -+ * config/aarch64/aarch64.c -+ (aarch64_load_symref_appropriately): Handle SYMBOL_TINY_GOT. -+ (aarch64_expand_mov_immediate): Likewise. -+ (aarch64_print_operand): Likewise. -+ (aarch64_classify_symbol): Likewise. -+ * config/aarch64/aarch64.md (UNSPEC_GOTTINYPIC): Define. -+ (ldr_got_tiny): Define. -+ -+2013-10-16 Christophe Lyon -+ -+ * LINARO-VERSION: Bump version. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ * LINARO-VERSION: Update. -+ -+2013-10-09 Christophe Lyon -+ -+ Backport from trunk r198526,198527,200020,200595. -+ 2013-05-02 Ian Bolton -+ -+ * config/aarch64/aarch64.md (*and_one_cmpl3_compare0): -+ New pattern. -+ (*and_one_cmplsi3_compare0_uxtw): Likewise. -+ (*and_one_cmpl_3_compare0): Likewise. -+ (*and_one_cmpl_si3_compare0_uxtw): Likewise. -+ -+ 2013-05-02 Ian Bolton ++ 2013-05-02 Ian Bolton + + * config/aarch64/aarch64.md (movsi_aarch64): Only allow to/from + S reg when fp attribute set. @@ -2898,7 +1552,7 @@ + + Backport from trunk r201260,202400. + 2013-07-26 Kyrylo Tkachov -+ Richard Earnshaw ++ Richard Earnshaw + + * combine.c (simplify_comparison): Re-canonicalize operands + where appropriate. @@ -2969,8 +1623,7 @@ + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. -+ * LINARO-VERSION: Update. ++ GCC Linaro 4.8-2013.09 released. + +2013-09-10 Venkataramanan Kumar + @@ -3460,7 +2113,6 @@ +2013-08-14 Christophe Lyon + + GCC Linaro 4.8-2013.08 released. -+ * LINARO-VERSION: Update. + +2013-08-08 Christophe Lyon + @@ -4163,8 +2815,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. -+ * LINARO-VERSION: Update. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-19 Matthew Gretton-Dann + @@ -4175,14 +2826,9 @@ + * config/arm/arm.c (gen_movmem_ldrd_strd): Fix unaligned load/store + usage in HI mode. + -+2013-07-09 Christophe Lyon -+ -+ * LINARO-VERSION: Bump version. -+ +2013-07-05 Christophe Lyon + + GCC Linaro 4.8-2013.07 released. -+ * LINARO-VERSION: Update. + +2013-07-03 Christophe Lyon + @@ -4353,14 +2999,9 @@ + * config/arm/linux-eabi.h (ASAN_CC1_SPEC): Define. + (LINUX_OR_ANDROID_CC): Add ASAN_CC1_SPEC. + -+2013-06-18 Rob Savoye -+ -+ * LINARO-VERSION: Bump version. -+ +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ * LINARO-VERSION: Update. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-06-06 Zhenqiang Chen + @@ -4704,7 +3345,6 @@ +2013-05-14 Matthew Gretton-Dann + + GCC Linaro 4.8-2013.05 released. -+ * LINARO-VERSION: Update. + +2013-05-14 Matthew Gretton-Dann + @@ -4974,7 +3614,7 @@ + + Backport from trunk 198298. + 2013-04-25 Kyrylo Tkachov -+ Julian Brown ++ Julian Brown + + * config/arm/arm.c (neon_builtin_type_mode): Add T_V4HF. + (TB_DREG): Add T_V4HF. @@ -5173,7 +3813,7 @@ + (movdf_soft_insn): Likewise. + * config/arm/vfp.md (movdi_vfp): Likewise. + * config/arm/t-arm (MD_INCLUDES): Add ldrdstrd.md. -+ * config/arm/arm-protos.h (gen_operands_ldrd_strd): New declaration. ++ * config/arm/arm-protos.h (gen_operands_ldrd_strd): New declaration. + * config/arm/arm.c (gen_operands_ldrd_strd): New function. + (mem_ok_for_ldrd_strd): Likewise. + (output_move_double): Update assertion. @@ -5191,7 +3831,7 @@ + + * config/arm/arm.md (arm_ashldi3_1bit): Convert define_insn into + define_insn_and_split. -+ (arm_ashrdi3_1bit,arm_lshrdi3_1bit): Likewise. ++ (arm_ashrdi3_1bit,arm_lshrdi3_1bit): Likewise. + (shiftsi3_compare): New pattern. + (rrx): New pattern. + * config/arm/unspecs.md (UNSPEC_RRX): New. @@ -5291,7 +3931,8 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. ++ + * LINARO-VERSION: New file. + * configure.ac: Add Linaro version string. + * configure: Regenerate. @@ -5458,5142 +4099,4916 @@ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_floorf } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vaesdq_u8.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vaesdq_u8.c -@@ -0,0 +1,22 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+int -+foo (void) -+{ -+ uint8x16_t a, b, c; -+ int i = 0; -+ -+ for (i = 0; i < 16; ++i) -+ { -+ a[i] = i; -+ b[i] = 15 - i; -+ } -+ c = vaesdq_u8 (a, b); -+ return c[0]; -+} -+ -+/* { dg-final { scan-assembler "aesd.8\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha256su0q_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha256su0q_u32.c -@@ -0,0 +1,17 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+int -+foo (void) -+{ -+ uint32x4_t a = {0xd, 0xe, 0xa, 0xd}; -+ uint32x4_t b = {0, 1, 2, 3}; -+ -+ uint32x4_t res = vsha256su0q_u32 (a, b); -+ return res[0]; -+} -+ -+/* { dg-final { scan-assembler "sha256su0.32\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld1p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld1p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld1p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vld1p64 (void) -+{ -+ poly64x1_t out_poly64x1_t; -+ -+ out_poly64x1_t = vld1_p64 (0); -+} -+ -+/* { dg-final { scan-assembler "vld1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vst4p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vst4p64.c +--- a/src/gcc/testsuite/gcc.target/arm/neon/vcvtf32_f16.c ++++ b/src/gcc/testsuite/gcc.target/arm/neon/vcvtf32_f16.c @@ -0,0 +1,20 @@ -+/* Test the `vst4p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vst4p64 (void) -+{ -+ poly64_t *arg0_poly64_t; -+ poly64x1x4_t arg1_poly64x1x4_t; -+ -+ vst4_p64 (arg0_poly64_t, arg1_poly64x1x4_t); -+} -+ -+/* { dg-final { scan-assembler "vst1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_u8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp128_u8 (void) -+{ -+ poly128_t out_poly128_t; -+ uint8x16_t arg0_uint8x16_t; -+ -+ out_poly128_t = vreinterpretq_p128_u8 (arg0_uint8x16_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_s32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp128_s32 (void) -+{ -+ poly128_t out_poly128_t; -+ int32x4_t arg0_int32x4_t; -+ -+ out_poly128_t = vreinterpretq_p128_s32 (arg0_int32x4_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_u8' ARM Neon intrinsic. */ ++/* Test the `vcvtf32_f16' ARM Neon intrinsic. */ +/* This file was autogenerated by neon-testgen. */ + +/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ ++/* { dg-require-effective-target arm_neon_fp16_ok } */ +/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-add-options arm_neon_fp16 } */ + +#include "arm_neon.h" + -+void test_vreinterpretQp64_u8 (void) ++void test_vcvtf32_f16 (void) +{ -+ poly64x2_t out_poly64x2_t; -+ uint8x16_t arg0_uint8x16_t; ++ float32x4_t out_float32x4_t; ++ float16x4_t arg0_float16x4_t; + -+ out_poly64x2_t = vreinterpretq_p64_u8 (arg0_uint8x16_t); ++ out_float32x4_t = vcvt_f32_f16 (arg0_float16x4_t); +} + ++/* { dg-final { scan-assembler "vcvt\.f32.f16\[ \]+\[qQ\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp8_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp8_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp8_p64' ARM Neon intrinsic. */ +--- a/src/gcc/testsuite/gcc.target/arm/neon/vcvtf16_f32.c ++++ b/src/gcc/testsuite/gcc.target/arm/neon/vcvtf16_f32.c +@@ -0,0 +1,20 @@ ++/* Test the `vcvtf16_f32' ARM Neon intrinsic. */ +/* This file was autogenerated by neon-testgen. */ + +/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ ++/* { dg-require-effective-target arm_neon_fp16_ok } */ +/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-add-options arm_neon_fp16 } */ + +#include "arm_neon.h" + -+void test_vreinterpretQp8_p64 (void) ++void test_vcvtf16_f32 (void) +{ -+ poly8x16_t out_poly8x16_t; -+ poly64x2_t arg0_poly64x2_t; ++ float16x4_t out_float16x4_t; ++ float32x4_t arg0_float32x4_t; + -+ out_poly8x16_t = vreinterpretq_p8_p64 (arg0_poly64x2_t); ++ out_float16x4_t = vcvt_f16_f32 (arg0_float32x4_t); +} + ++/* { dg-final { scan-assembler "vcvt\.f16.f32\[ \]+\[dD\]\[0-9\]+, \[qQ\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_s16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" +--- a/src/gcc/testsuite/gcc.target/arm/anddi3-opt.c ++++ b/src/gcc/testsuite/gcc.target/arm/anddi3-opt.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O1" } */ + -+void test_vreinterpretQp128_s16 (void) ++unsigned long long ++muld (unsigned long long X, unsigned long long Y) +{ -+ poly128_t out_poly128_t; -+ int16x8_t arg0_int16x8_t; -+ -+ out_poly128_t = vreinterpretq_p128_s16 (arg0_int16x8_t); ++ unsigned long long mask = 0xffffffffull; ++ return (X & mask) * (Y & mask); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld2p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld2p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld2p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vld2p64 (void) ++/* { dg-final { scan-assembler-not "and\[\\t \]+.+,\[\\t \]*.+,\[\\t \]*.+" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c ++++ b/src/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_prefer_ldrd_strd } */ ++/* { dg-options "-O2" } */ ++int foo(int a, int b, int* p, int *q) +{ -+ poly64x1x2_t out_poly64x1x2_t; -+ -+ out_poly64x1x2_t = vld2_p64 (0); ++ a = p[2] + p[3]; ++ *q = a; ++ *p = a; ++ return a; +} ++/* { dg-final { scan-assembler "ldrd" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselgtdf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselgtdf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_u64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp64_u64 (void) ++double ++foo (double x, double y) +{ -+ poly64x2_t out_poly64x2_t; -+ uint64x2_t arg0_uint64x2_t; -+ -+ out_poly64x2_t = vreinterpretq_p64_u64 (arg0_uint64x2_t); ++ volatile int i = 0; ++ return i > 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld4_dupp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld4_dupp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld4_dupp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "vselgt.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/iordi3-opt.c ++++ b/src/gcc/testsuite/gcc.target/arm/iordi3-opt.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O1" } */ + -+void test_vld4_dupp64 (void) ++unsigned long long or64 (unsigned long long input) +{ -+ poly64x1x4_t out_poly64x1x4_t; -+ -+ out_poly64x1x4_t = vld4_dup_p64 (0); ++ return input | 0x200000004ULL; +} + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu8_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu8_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu8_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#include "../aarch64/atomic-op-relaxed.x" + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselgesf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselgesf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretQu8_p64 (void) ++float ++foo (float x, float y) +{ -+ uint8x16_t out_uint8x16_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_uint8x16_t = vreinterpretq_u8_p64 (arg0_poly64x2_t); ++ volatile int i = 0; ++ return i >= 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_p16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_p16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_p16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp64_p16 (void) ++/* { dg-final { scan-assembler-times "vselge.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/peep-strd-1.c ++++ b/src/gcc/testsuite/gcc.target/arm/peep-strd-1.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_prefer_ldrd_strd } */ ++/* { dg-options "-O2" } */ ++void foo(int a, int b, int* p) +{ -+ poly64x2_t out_poly64x2_t; -+ poly16x8_t arg0_poly16x8_t; -+ -+ out_poly64x2_t = vreinterpretq_p64_p16 (arg0_poly16x8_t); ++ p[2] = a; ++ p[3] = b; +} ++/* { dg-final { scan-assembler "strd" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/lp1243022.c ++++ b/src/gcc/testsuite/gcc.target/arm/lp1243022.c +@@ -0,0 +1,201 @@ ++/* { dg-do compile { target arm_thumb2 } } */ ++/* { dg-options "-O2 -fdump-rtl-subreg2" } */ + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vdupQ_np64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vdupQ_np64.c -@@ -0,0 +1,19 @@ -+/* Test the `vdupQ_np64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vdupQ_np64 (void) ++/* { dg-final { scan-rtl-dump "REG_INC" "subreg2" } } */ ++/* { dg-final { cleanup-rtl-dump "subreg2" } } */ ++struct device; ++typedef unsigned int __u32; ++typedef unsigned long long u64; ++typedef __u32 __le32; ++typedef u64 dma_addr_t; ++typedef unsigned gfp_t; ++int dev_warn (const struct device *dev, const char *fmt, ...); ++struct usb_bus +{ -+ poly64x2_t out_poly64x2_t; -+ poly64_t arg0_poly64_t; -+ -+ out_poly64x2_t = vdupq_n_p64 (arg0_poly64_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs32_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs32_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs32_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQs32_p64 (void) ++ struct device *controller; ++}; ++struct usb_hcd +{ -+ int32x4_t out_int32x4_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_int32x4_t = vreinterpretq_s32_p64 (arg0_poly64x2_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_u32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp128_u32 (void) ++ struct usb_bus self; ++}; ++struct xhci_generic_trb +{ -+ poly128_t out_poly128_t; -+ uint32x4_t arg0_uint32x4_t; -+ -+ out_poly128_t = vreinterpretq_p128_u32 (arg0_uint32x4_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs64_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs64_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs64_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQs64_p64 (void) ++ __le32 field[4]; ++}; ++union xhci_trb +{ -+ int64x2_t out_int64x2_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_int64x2_t = vreinterpretq_s64_p64 (arg0_poly64x2_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld3p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld3p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld3p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vld3p64 (void) ++ struct xhci_generic_trb generic; ++}; ++struct xhci_segment +{ -+ poly64x1x3_t out_poly64x1x3_t; -+ -+ out_poly64x1x3_t = vld3_p64 (0); -+} -+ -+/* { dg-final { scan-assembler "vld1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu16_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu16_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu16_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQu16_p128 (void) ++ union xhci_trb *trbs; ++ dma_addr_t dma; ++}; ++struct xhci_ring +{ -+ uint16x8_t out_uint16x8_t; -+ poly128_t arg0_poly128_t; -+ -+ out_uint16x8_t = vreinterpretq_u16_p128 (arg0_poly128_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_u16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp128_u16 (void) ++ struct xhci_segment *first_seg; ++}; ++struct xhci_hcd +{ -+ poly128_t out_poly128_t; -+ uint16x8_t arg0_uint16x8_t; -+ -+ out_poly128_t = vreinterpretq_p128_u16 (arg0_uint16x8_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vcreatep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vcreatep64.c -@@ -0,0 +1,19 @@ -+/* Test the `vcreatep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vcreatep64 (void) ++ struct xhci_ring *cmd_ring; ++ struct xhci_ring *event_ring; ++}; ++struct usb_hcd *xhci_to_hcd (struct xhci_hcd *xhci) +{ -+ poly64x1_t out_poly64x1_t; -+ uint64_t arg0_uint64_t; -+ -+ out_poly64x1_t = vcreate_p64 (arg0_uint64_t); +} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vdupQ_lanep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vdupQ_lanep64.c -@@ -0,0 +1,19 @@ -+/* Test the `vdupQ_lanep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vdupQ_lanep64 (void) ++dma_addr_t xhci_trb_virt_to_dma (struct xhci_segment * seg, ++ union xhci_trb * trb); ++struct xhci_segment *trb_in_td (struct xhci_segment *start_seg, ++ dma_addr_t suspect_dma); ++xhci_test_trb_in_td (struct xhci_hcd *xhci, struct xhci_segment *input_seg, ++ union xhci_trb *start_trb, union xhci_trb *end_trb, ++ dma_addr_t input_dma, struct xhci_segment *result_seg, ++ char *test_name, int test_number) +{ -+ poly64x2_t out_poly64x2_t; -+ poly64x1_t arg0_poly64x1_t; -+ -+ out_poly64x2_t = vdupq_lane_p64 (arg0_poly64x1_t, 0); ++ unsigned long long start_dma; ++ unsigned long long end_dma; ++ struct xhci_segment *seg; ++ start_dma = xhci_trb_virt_to_dma (input_seg, start_trb); ++ end_dma = xhci_trb_virt_to_dma (input_seg, end_trb); ++ { ++ dev_warn (xhci_to_hcd (xhci)->self.controller, ++ "%d\n", test_number); ++ dev_warn (xhci_to_hcd (xhci)->self.controller, ++ "Expected seg %p, got seg %p\n", result_seg, seg); ++ } +} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_f32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_f32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_f32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp128_f32 (void) ++xhci_check_trb_in_td_math (struct xhci_hcd *xhci, gfp_t mem_flags) +{ -+ poly128_t out_poly128_t; -+ float32x4_t arg0_float32x4_t; -+ -+ out_poly128_t = vreinterpretq_p128_f32 (arg0_float32x4_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vsri_np64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vsri_np64.c -@@ -0,0 +1,21 @@ -+/* Test the `vsri_np64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vsri_np64 (void) -+{ -+ poly64x1_t out_poly64x1_t; -+ poly64x1_t arg0_poly64x1_t; -+ poly64x1_t arg1_poly64x1_t; -+ -+ out_poly64x1_t = vsri_n_p64 (arg0_poly64x1_t, arg1_poly64x1_t, 1); ++ struct ++ { ++ dma_addr_t input_dma; ++ struct xhci_segment *result_seg; ++ } ++ simple_test_vector[] = ++ { ++ { ++ 0, ((void *) 0) ++ } ++ , ++ { ++ xhci->event_ring->first_seg->dma - 16, ((void *) 0)} ++ , ++ { ++ xhci->event_ring->first_seg->dma - 1, ((void *) 0)} ++ , ++ { ++ xhci->event_ring->first_seg->dma, xhci->event_ring->first_seg} ++ , ++ { ++ xhci->event_ring->first_seg->dma + (64 - 1) * 16, ++ xhci->event_ring->first_seg ++ } ++ , ++ { ++ xhci->event_ring->first_seg->dma + (64 - 1) * 16 + 1, ((void *) 0)} ++ , ++ { ++ xhci->event_ring->first_seg->dma + (64) * 16, ((void *) 0)} ++ , ++ { ++ (dma_addr_t) (~0), ((void *) 0) ++ } ++ }; ++ struct ++ { ++ struct xhci_segment *input_seg; ++ union xhci_trb *start_trb; ++ union xhci_trb *end_trb; ++ dma_addr_t input_dma; ++ struct xhci_segment *result_seg; ++ } ++ complex_test_vector[] = ++ { ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ xhci->event_ring->first_seg->trbs,.end_trb = ++ &xhci->event_ring->first_seg->trbs[64 - 1],.input_dma = ++ xhci->cmd_ring->first_seg->dma,.result_seg = ((void *) 0), ++ } ++ , ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ xhci->event_ring->first_seg->trbs,.end_trb = ++ &xhci->cmd_ring->first_seg->trbs[64 - 1],.input_dma = ++ xhci->cmd_ring->first_seg->dma,.result_seg = ((void *) 0), ++ } ++ , ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ xhci->cmd_ring->first_seg->trbs,.end_trb = ++ &xhci->cmd_ring->first_seg->trbs[64 - 1],.input_dma = ++ xhci->cmd_ring->first_seg->dma,.result_seg = ((void *) 0), ++ } ++ , ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ &xhci->event_ring->first_seg->trbs[0],.end_trb = ++ &xhci->event_ring->first_seg->trbs[3],.input_dma = ++ xhci->event_ring->first_seg->dma + 4 * 16,.result_seg = ((void *) 0), ++ } ++ , ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ &xhci->event_ring->first_seg->trbs[3],.end_trb = ++ &xhci->event_ring->first_seg->trbs[6],.input_dma = ++ xhci->event_ring->first_seg->dma + 2 * 16,.result_seg = ((void *) 0), ++ } ++ , ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ &xhci->event_ring->first_seg->trbs[64 - 3],.end_trb = ++ &xhci->event_ring->first_seg->trbs[1],.input_dma = ++ xhci->event_ring->first_seg->dma + 2 * 16,.result_seg = ((void *) 0), ++ } ++ , ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ &xhci->event_ring->first_seg->trbs[64 - 3],.end_trb = ++ &xhci->event_ring->first_seg->trbs[1],.input_dma = ++ xhci->event_ring->first_seg->dma + (64 - 4) * 16,.result_seg = ++ ((void *) 0), ++ } ++ , ++ { ++ .input_seg = xhci->event_ring->first_seg,.start_trb = ++ &xhci->event_ring->first_seg->trbs[64 - 3],.end_trb = ++ &xhci->event_ring->first_seg->trbs[1],.input_dma = ++ xhci->cmd_ring->first_seg->dma + 2 * 16,.result_seg = ((void *) 0), ++ } ++ }; ++ unsigned int num_tests; ++ int i, ret; ++ num_tests = ++ (sizeof (simple_test_vector) / sizeof ((simple_test_vector)[0]) + ++ (sizeof (struct ++ { ++ } ++ ))); ++ for (i = 0; i < num_tests; i++) ++ { ++ ret = ++ xhci_test_trb_in_td (xhci, xhci->event_ring->first_seg, ++ xhci->event_ring->first_seg->trbs, ++ &xhci->event_ring->first_seg->trbs[64 - 1], ++ simple_test_vector[i].input_dma, ++ simple_test_vector[i].result_seg, "Simple", i); ++ if (ret < 0) ++ return ret; ++ } ++ for (i = 0; i < num_tests; i++) ++ { ++ ret = ++ xhci_test_trb_in_td (xhci, complex_test_vector[i].input_seg, ++ complex_test_vector[i].start_trb, ++ complex_test_vector[i].end_trb, ++ complex_test_vector[i].input_dma, ++ complex_test_vector[i].result_seg, "Complex", i); ++ if (ret < 0) ++ return ret; ++ } +} +--- a/src/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-final { scan-assembler "vsri\.64\[ \]+\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld1_lanep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld1_lanep64.c -@@ -0,0 +1,20 @@ -+/* Test the `vld1_lanep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++#include "../aarch64/atomic-comp-swap-release-acquire.x" + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 4 } } */ ++/* { dg-final { scan-assembler-times "stlex" 4 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/pr19599.c ++++ b/src/gcc/testsuite/gcc.target/arm/pr19599.c +@@ -0,0 +1,10 @@ ++/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" "-mthumb" } { "" } } */ ++/* { dg-options "-O2 -march=armv5te -marm" } */ ++/* { dg-final { scan-assembler "bx" } } */ + -+#include "arm_neon.h" ++int (*indirect_func)(); + -+void test_vld1_lanep64 (void) ++int indirect_call() +{ -+ poly64x1_t out_poly64x1_t; -+ poly64x1_t arg1_poly64x1_t; -+ -+ out_poly64x1_t = vld1_lane_p64 (0, arg1_poly64x1_t, 0); ++ return indirect_func(); +} +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs8_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs8_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs8_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#include "../aarch64/atomic-op-seq_cst.x" + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "stlex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselgedf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselgedf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretQs8_p128 (void) ++double ++foo (double x, double y) +{ -+ int8x16_t out_int8x16_t; -+ poly128_t arg0_poly128_t; -+ -+ out_int8x16_t = vreinterpretq_s8_p128 (arg0_poly128_t); ++ volatile int i = 0; ++ return i >= 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld4p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld4p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld4p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-times "vselge.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-consume.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-consume.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#include "../aarch64/atomic-op-consume.x" + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-char.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-char.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+void test_vld4p64 (void) -+{ -+ poly64x1x4_t out_poly64x1x4_t; ++#include "../aarch64/atomic-op-char.x" + -+ out_poly64x1x4_t = vld4_p64 (0); ++/* { dg-final { scan-assembler-times "ldrexb\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "strexb\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselnesf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselnesf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ ++ ++float ++foo (float x, float y) ++{ ++ volatile int i = 0; ++ return i != 0 ? x : y; +} + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_s32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-times "vseleq.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselvcsf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselvcsf.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++float ++foo (float x, float y) ++{ ++ return !__builtin_isunordered (x, y) ? x : y; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "vselvs.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/minmax_minus.c ++++ b/src/gcc/testsuite/gcc.target/arm/minmax_minus.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2" } */ + -+void test_vreinterpretQp64_s32 (void) ++#define MAX(a, b) (a > b ? a : b) ++int ++foo (int a, int b, int c) +{ -+ poly64x2_t out_poly64x2_t; -+ int32x4_t arg0_int32x4_t; -+ -+ out_poly64x2_t = vreinterpretq_p64_s32 (arg0_int32x4_t); ++ return c - MAX (a, b); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld1Q_lanep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld1Q_lanep64.c -@@ -0,0 +1,20 @@ -+/* Test the `vld1Q_lanep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-not "mov" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-release.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-release.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#include "../aarch64/atomic-op-release.x" + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "stlex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselvssf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselvssf.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vld1Q_lanep64 (void) ++float ++foo (float x, float y) +{ -+ poly64x2_t out_poly64x2_t; -+ poly64x2_t arg1_poly64x2_t; -+ -+ out_poly64x2_t = vld1q_lane_p64 (0, arg1_poly64x2_t, 1); ++ return __builtin_isunordered (x, y) ? x : y; +} + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_p8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_p8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_p8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-assembler-times "vselvs.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vect-rounding-roundf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vect-rounding-roundf.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_neon_ok } */ ++/* { dg-options "-O2 -ffast-math -ftree-vectorize" } */ ++/* { dg-add-options arm_v8_neon } */ + -+#include "arm_neon.h" ++#define N 32 + -+void test_vreinterpretQp128_p8 (void) ++void ++foo (float *output, float *input) +{ -+ poly128_t out_poly128_t; -+ poly8x16_t arg0_poly8x16_t; -+ -+ out_poly128_t = vreinterpretq_p128_p8 (arg0_poly8x16_t); ++ int i = 0; ++ /* Vectorizable. */ ++ for (i = 0; i < N; i++) ++ output[i] = __builtin_roundf (input[i]); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_p8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_p8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_p8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_roundf } } } */ ++/* { dg-final { cleanup-tree-dump "vect" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/neon-for-64bits-1.c ++++ b/src/gcc/testsuite/gcc.target/arm/neon-for-64bits-1.c +@@ -0,0 +1,54 @@ ++/* Check that Neon is *not* used by default to handle 64-bits scalar ++ operations. */ + -+#include "arm_neon.h" ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_neon_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_neon } */ + -+void test_vreinterpretQp64_p8 (void) -+{ -+ poly64x2_t out_poly64x2_t; -+ poly8x16_t arg0_poly8x16_t; ++typedef long long i64; ++typedef unsigned long long u64; ++typedef unsigned int u32; ++typedef int i32; + -+ out_poly64x2_t = vreinterpretq_p64_p8 (arg0_poly8x16_t); -+} ++/* Unary operators */ ++#define UNARY_OP(name, op) \ ++ void unary_##name(u64 *a, u64 *b) { *a = op (*b + 0x1234567812345678ULL) ; } + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vget_lowp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vget_lowp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vget_lowp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* Binary operators */ ++#define BINARY_OP(name, op) \ ++ void binary_##name(u64 *a, u64 *b, u64 *c) { *a = *b op *c ; } + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* Unsigned shift */ ++#define SHIFT_U(name, op, amount) \ ++ void ushift_##name(u64 *a, u64 *b, int c) { *a = *b op amount; } + -+#include "arm_neon.h" ++/* Signed shift */ ++#define SHIFT_S(name, op, amount) \ ++ void sshift_##name(i64 *a, i64 *b, int c) { *a = *b op amount; } + -+void test_vget_lowp64 (void) -+{ -+ poly64x1_t out_poly64x1_t; -+ poly64x2_t arg0_poly64x2_t; ++UNARY_OP(not, ~) + -+ out_poly64x1_t = vget_low_p64 (arg0_poly64x2_t); -+} ++BINARY_OP(add, +) ++BINARY_OP(sub, -) ++BINARY_OP(and, &) ++BINARY_OP(or, |) ++BINARY_OP(xor, ^) + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs64_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs64_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs64_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++SHIFT_U(right1, >>, 1) ++SHIFT_U(right2, >>, 2) ++SHIFT_U(right5, >>, 5) ++SHIFT_U(rightn, >>, c) + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++SHIFT_S(right1, >>, 1) ++SHIFT_S(right2, >>, 2) ++SHIFT_S(right5, >>, 5) ++SHIFT_S(rightn, >>, c) + -+#include "arm_neon.h" ++/* { dg-final {scan-assembler-times "vmvn" 0} } */ ++/* { dg-final {scan-assembler-times "vadd" 0} } */ ++/* { dg-final {scan-assembler-times "vsub" 0} } */ ++/* { dg-final {scan-assembler-times "vand" 0} } */ ++/* { dg-final {scan-assembler-times "vorr" 0} } */ ++/* { dg-final {scan-assembler-times "veor" 0} } */ ++/* { dg-final {scan-assembler-times "vshr" 0} } */ +--- a/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-2.c ++++ b/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-2.c +@@ -4,7 +4,7 @@ + + #include + +-char dest[16]; ++char dest[16] = { 0 }; + + void aligned_dest (char *src) + { +@@ -14,7 +14,10 @@ + /* Expect a multi-word store for the main part of the copy, but subword + loads/stores for the remainder. */ + +-/* { dg-final { scan-assembler-times "stmia" 1 } } */ ++/* { dg-final { scan-assembler-times "ldmia" 0 } } */ ++/* { dg-final { scan-assembler-times "ldrd" 0 } } */ ++/* { dg-final { scan-assembler-times "stmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ ++/* { dg-final { scan-assembler-times "strd" 1 { target { arm_prefer_ldrd_strd } } } } */ + /* { dg-final { scan-assembler-times "ldrh" 1 } } */ + /* { dg-final { scan-assembler-times "strh" 1 } } */ + /* { dg-final { scan-assembler-times "ldrb" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/xordi3-opt.c ++++ b/src/gcc/testsuite/gcc.target/arm/xordi3-opt.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O1" } */ + -+void test_vreinterpretQs64_p128 (void) ++unsigned long long xor64 (unsigned long long input) +{ -+ int64x2_t out_int64x2_t; -+ poly128_t arg0_poly128_t; -+ -+ out_int64x2_t = vreinterpretq_s64_p128 (arg0_poly128_t); ++ return input ^ 0x200000004ULL; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vst1_lanep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vst1_lanep64.c -@@ -0,0 +1,20 @@ -+/* Test the `vst1_lanep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#include "../aarch64/atomic-op-acq_rel.x" + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "stlex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselltsf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselltsf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vst1_lanep64 (void) ++float ++foo (float x, float y) +{ -+ poly64_t *arg0_poly64_t; -+ poly64x1_t arg1_poly64x1_t; -+ -+ vst1_lane_p64 (arg0_poly64_t, arg1_poly64x1_t, 0); ++ volatile int i = 0; ++ return i < 0 ? x : y; +} + -+/* { dg-final { scan-assembler "vst1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs16_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs16_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs16_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-times "vselge.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselnedf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselnedf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++double ++foo (double x, double y) ++{ ++ volatile int i = 0; ++ return i != 0 ? x : y; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "vseleq.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselvcdf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselvcdf.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretQs16_p64 (void) ++double ++foo (double x, double y) +{ -+ int16x8_t out_int16x8_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_int16x8_t = vreinterpretq_s16_p64 (arg0_poly64x2_t); ++ return !__builtin_isunordered (x, y) ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_s16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-assembler-times "vselvs.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vect-rounding-btruncf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vect-rounding-btruncf.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_neon_ok } */ ++/* { dg-options "-O2 -ffast-math -ftree-vectorize" } */ ++/* { dg-add-options arm_v8_neon } */ + -+#include "arm_neon.h" ++#define N 32 + -+void test_vreinterpretQp64_s16 (void) ++void ++foo (float *output, float *input) +{ -+ poly64x2_t out_poly64x2_t; -+ int16x8_t arg0_int16x8_t; -+ -+ out_poly64x2_t = vreinterpretq_p64_s16 (arg0_int16x8_t); ++ int i = 0; ++ /* Vectorizable. */ ++ for (i = 0; i < N; i++) ++ output[i] = __builtin_truncf (input[i]); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp16_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp16_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp16_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_btruncf } } } */ ++/* { dg-final { cleanup-tree-dump "vect" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vseleqsf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vseleqsf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretp16_p64 (void) ++float ++foo (float x, float y) +{ -+ poly16x4_t out_poly16x4_t; -+ poly64x1_t arg0_poly64x1_t; -+ -+ out_poly16x4_t = vreinterpret_p16_p64 (arg0_poly64x1_t); ++ volatile int i = 0; ++ return i == 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vst1Qp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vst1Qp64.c -@@ -0,0 +1,20 @@ -+/* Test the `vst1Qp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-assembler-times "vseleq.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c ++++ b/src/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-ivopts-details" } */ ++/* { dg-skip-if "" { arm_thumb1 } } */ + -+#include "arm_neon.h" ++extern char *__ctype_ptr__; + -+void test_vst1Qp64 (void) ++unsigned char * foo(unsigned char *ReadPtr) +{ -+ poly64_t *arg0_poly64_t; -+ poly64x2_t arg1_poly64x2_t; + -+ vst1q_p64 (arg0_poly64_t, arg1_poly64x2_t); -+} ++ unsigned char c; + -+/* { dg-final { scan-assembler "vst1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_s64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ while (!(((__ctype_ptr__+sizeof(""[*ReadPtr]))[(int)(*ReadPtr)])&04) == (!(0))) ++ ReadPtr++; + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ return ReadPtr; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-tree-dump-times "original biv" 2 "ivopts"} } */ ++/* { dg-final { cleanup-tree-dump "ivopts" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselvsdf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselvsdf.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretp64_s64 (void) ++double ++foo (double x, double y) +{ -+ poly64x1_t out_poly64x1_t; -+ int64x1_t arg0_int64x1_t; -+ -+ out_poly64x1_t = vreinterpret_p64_s64 (arg0_int64x1_t); ++ return __builtin_isunordered (x, y) ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu32_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu32_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu32_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "vselvs.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-3.c ++++ b/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-3.c +@@ -4,7 +4,7 @@ + + #include + +-char src[16]; ++char src[16] = {0}; + + void aligned_src (char *dest) + { +@@ -14,8 +14,11 @@ + /* Expect a multi-word load for the main part of the copy, but subword + loads/stores for the remainder. */ + +-/* { dg-final { scan-assembler-times "ldmia" 1 } } */ +-/* { dg-final { scan-assembler-times "ldrh" 1 } } */ ++/* { dg-final { scan-assembler-times "ldmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ ++/* { dg-final { scan-assembler-times "ldrd" 1 { target { arm_prefer_ldrd_strd } } } } */ ++/* { dg-final { scan-assembler-times "strd" 0 } } */ ++/* { dg-final { scan-assembler-times "stm" 0 } } */ ++/* { dg-final { scan-assembler-times "ldrh" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ + /* { dg-final { scan-assembler-times "strh" 1 } } */ +-/* { dg-final { scan-assembler-times "ldrb" 1 } } */ ++/* { dg-final { scan-assembler-times "ldrb" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ + /* { dg-final { scan-assembler-times "strb" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/pr46975-2.c ++++ b/src/gcc/testsuite/gcc.target/arm/pr46975-2.c +@@ -0,0 +1,10 @@ ++/* { dg-options "-mthumb -O2" } */ ++/* { dg-require-effective-target arm_thumb2_ok } */ ++/* { dg-final { scan-assembler "sub" } } */ ++/* { dg-final { scan-assembler "clz" } } */ ++/* { dg-final { scan-assembler "lsr.*#5" } } */ + -+void test_vreinterpretQu32_p64 (void) ++int foo (int s) +{ -+ uint32x4_t out_uint32x4_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_uint32x4_t = vreinterpretq_u32_p64 (arg0_poly64x2_t); ++ return s == 1; +} +--- a/src/gcc/testsuite/gcc.target/arm/anddi3-opt2.c ++++ b/src/gcc/testsuite/gcc.target/arm/anddi3-opt2.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O1" } */ + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_u32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp64_u32 (void) ++long long muld(long long X, long long Y) +{ -+ poly64x2_t out_poly64x2_t; -+ uint32x4_t arg0_uint32x4_t; -+ -+ out_poly64x2_t = vreinterpretq_p64_u32 (arg0_uint32x4_t); ++ return X & ~1; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vget_highp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vget_highp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vget_highp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-not "and\[\\t \]+.+,\[\\t \]*.+,\[\\t \]*.+" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/neon-vcond-ltgt.c ++++ b/src/gcc/testsuite/gcc.target/arm/neon-vcond-ltgt.c +@@ -15,4 +15,4 @@ + + /* { dg-final { scan-assembler-times "vcgt\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" 2 } } */ + /* { dg-final { scan-assembler "vorr\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ +-/* { dg-final { scan-assembler "vbsl\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "vbsl|vbit|vbif\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselltdf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselltdf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vget_highp64 (void) ++double ++foo (double x, double y) +{ -+ poly64x1_t out_poly64x1_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_poly64x1_t = vget_high_p64 (arg0_poly64x2_t); ++ volatile int i = 0; ++ return i < 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu64_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu64_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu64_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "vselge.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-4.c ++++ b/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-4.c +@@ -4,8 +4,8 @@ + + #include + +-char src[16]; +-char dest[16]; ++char src[16] = { 0 }; ++char dest[16] = { 0 }; + + void aligned_both (void) + { +@@ -14,5 +14,9 @@ + + /* We know both src and dest to be aligned: expect multiword loads/stores. */ + +-/* { dg-final { scan-assembler-times "ldmia" 1 } } */ +-/* { dg-final { scan-assembler-times "stmia" 1 } } */ ++/* { dg-final { scan-assembler-times "ldmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ ++/* { dg-final { scan-assembler-times "stmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ ++/* { dg-final { scan-assembler "ldrd" { target { arm_prefer_ldrd_strd } } } } */ ++/* { dg-final { scan-assembler-times "ldm" 0 { target { arm_prefer_ldrd_strd } } } } */ ++/* { dg-final { scan-assembler "strd" { target { arm_prefer_ldrd_strd } } } } */ ++/* { dg-final { scan-assembler-times "stm" 0 { target { arm_prefer_ldrd_strd } } } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vseleqdf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vseleqdf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretQu64_p64 (void) ++double ++foo (double x, double y) +{ -+ uint64x2_t out_uint64x2_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_uint64x2_t = vreinterpretq_u64_p64 (arg0_poly64x2_t); ++ volatile int i = 0; ++ return i == 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_u16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_u16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-times "vseleq.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#include "../aarch64/atomic-op-acquire.x" + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vsellesf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vsellesf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretQp64_u16 (void) ++float ++foo (float x, float y) +{ -+ poly64x2_t out_poly64x2_t; -+ uint16x8_t arg0_uint16x8_t; -+ -+ out_poly64x2_t = vreinterpretq_p64_u16 (arg0_uint16x8_t); ++ volatile int i = 0; ++ return i <= 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vcvtf32_f16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vcvtf32_f16.c -@@ -0,0 +1,20 @@ -+/* Test the `vcvtf32_f16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_neon_fp16_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_neon_fp16 } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "vselgt.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/neon-vcond-unordered.c ++++ b/src/gcc/testsuite/gcc.target/arm/neon-vcond-unordered.c +@@ -16,4 +16,4 @@ + /* { dg-final { scan-assembler "vcgt\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ + /* { dg-final { scan-assembler "vcge\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ + /* { dg-final { scan-assembler "vorr\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ +-/* { dg-final { scan-assembler "vbsl\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "vbsl|vbit|vbif\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-int.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-int.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+void test_vcvtf32_f16 (void) -+{ -+ float32x4_t out_float32x4_t; -+ float16x4_t arg0_float16x4_t; ++#include "../aarch64/atomic-op-int.x" + -+ out_float32x4_t = vcvt_f32_f16 (arg0_float16x4_t); -+} ++/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/atomic-op-short.c ++++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-short.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arch_v8a_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_arch_v8a } */ + -+/* { dg-final { scan-assembler "vcvt\.f32.f16\[ \]+\[qQ\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_f32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_f32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_f32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++#include "../aarch64/atomic-op-short.x" + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-assembler-times "ldrexh\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-times "strexh\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ ++/* { dg-final { scan-assembler-not "dmb" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/pr40887.c ++++ b/src/gcc/testsuite/gcc.target/arm/pr40887.c +@@ -2,9 +2,9 @@ + /* { dg-options "-O2 -march=armv5te" } */ + /* { dg-final { scan-assembler "blx" } } */ + +-int (*indirect_func)(); ++int (*indirect_func)(int x); + + int indirect_call() + { +- return indirect_func(); ++ return indirect_func(20) + indirect_func (40); + } +--- a/src/gcc/testsuite/gcc.target/arm/vect-rounding-ceilf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vect-rounding-ceilf.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_neon_ok } */ ++/* { dg-options "-O2 -ffast-math -ftree-vectorize" } */ ++/* { dg-add-options arm_v8_neon } */ + -+#include "arm_neon.h" ++#define N 32 + -+void test_vreinterpretQp64_f32 (void) ++void ++foo (float *output, float *input) +{ -+ poly64x2_t out_poly64x2_t; -+ float32x4_t arg0_float32x4_t; -+ -+ out_poly64x2_t = vreinterpretq_p64_f32 (arg0_float32x4_t); ++ int i = 0; ++ /* Vectorizable. */ ++ for (i = 0; i < N; i++) ++ output[i] = __builtin_ceilf (input[i]); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vbslp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vbslp64.c -@@ -0,0 +1,22 @@ -+/* Test the `vbslp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_ceilf } } } */ ++/* { dg-final { cleanup-tree-dump "vect" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselledf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselledf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vbslp64 (void) ++double ++foo (double x, double y) +{ -+ poly64x1_t out_poly64x1_t; -+ uint64x1_t arg0_uint64x1_t; -+ poly64x1_t arg1_poly64x1_t; -+ poly64x1_t arg2_poly64x1_t; -+ -+ out_poly64x1_t = vbsl_p64 (arg0_uint64x1_t, arg1_poly64x1_t, arg2_poly64x1_t); ++ volatile int i = 0; ++ return i <= 0 ? x : y; +} + -+/* { dg-final { scan-assembler "((vbsl)|(vbit)|(vbif))\[ \]+\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp16_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp16_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp16_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "vselgt.f64\td\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/vselgtsf.c ++++ b/src/gcc/testsuite/gcc.target/arm/vselgtsf.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_v8_vfp_ok } */ ++/* { dg-options "-O2" } */ ++/* { dg-add-options arm_v8_vfp } */ + -+void test_vreinterpretQp16_p128 (void) ++float ++foo (float x, float y) +{ -+ poly16x8_t out_poly16x8_t; -+ poly128_t arg0_poly128_t; -+ -+ out_poly16x8_t = vreinterpretq_p16_p128 (arg0_poly128_t); ++ volatile int i = 0; ++ return i > 0 ? x : y; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vsli_np64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vsli_np64.c -@@ -0,0 +1,21 @@ -+/* Test the `vsli_np64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-times "vselgt.f32\ts\[0-9\]+" 1 } } */ +--- a/src/gcc/testsuite/gcc.target/arm/pr58578.c ++++ b/src/gcc/testsuite/gcc.target/arm/pr58578.c +@@ -0,0 +1,54 @@ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* PR target/58578 */ ++/* { dg-do run } */ ++/* { dg-options "-O1" } */ + -+#include "arm_neon.h" ++#include + -+void test_vsli_np64 (void) -+{ -+ poly64x1_t out_poly64x1_t; -+ poly64x1_t arg0_poly64x1_t; -+ poly64x1_t arg1_poly64x1_t; ++typedef struct { ++ long _prec; ++ int _flag; ++ long _exp; ++} __my_st_t; + -+ out_poly64x1_t = vsli_n_p64 (arg0_poly64x1_t, arg1_poly64x1_t, 1); -+} ++typedef __my_st_t *__my_st_ptr; + -+/* { dg-final { scan-assembler "vsli\.64\[ \]+\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld1Q_dupp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld1Q_dupp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld1Q_dupp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++int ++_test_fn (__my_st_ptr y, const __my_st_ptr xt) ++{ ++ int inexact; ++ if (xt->_exp != -2147483647L) ++ { ++ (y->_flag = xt->_flag); ++ } + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ do { ++ __my_st_ptr _y = y; ++ long _err1 = -2 * xt->_exp; ++ long _err2 = 2; ++ if (0 < _err1) ++ { ++ unsigned long _err = (unsigned long) _err1 + _err2; ++ if (__builtin_expect(!!(_err > _y->_prec + 1), 0)) ++ return 2; ++ return 3; ++ } ++ } while (0); + -+#include "arm_neon.h" ++ return 0; ++} + -+void test_vld1Q_dupp64 (void) ++int main () +{ -+ poly64x2_t out_poly64x2_t; ++ __my_st_t x, y; ++ long pz; ++ int inex; + -+ out_poly64x2_t = vld1q_dup_p64 (0); ++ x._prec = 914; ++ y._exp = 18; ++ if (_test_fn (&x, &y)) ++ { ++ abort(); ++ } ++ return 0; +} +--- a/src/gcc/testsuite/gcc.target/arm/neon-vcond-gt.c ++++ b/src/gcc/testsuite/gcc.target/arm/neon-vcond-gt.c +@@ -14,4 +14,4 @@ + } + + /* { dg-final { scan-assembler "vcgt\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ +-/* { dg-final { scan-assembler "vbit\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "vbsl|vbit|vbif\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ +--- a/src/gcc/testsuite/gcc.target/arm/pr57637.c ++++ b/src/gcc/testsuite/gcc.target/arm/pr57637.c +@@ -0,0 +1,206 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 -fno-inline" } */ + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu8_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu8_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu8_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++typedef struct _GtkCssStyleProperty GtkCssStyleProperty; + -+void test_vreinterpretQu8_p128 (void) ++struct _GtkCssStyleProperty +{ -+ uint8x16_t out_uint8x16_t; -+ poly128_t arg0_poly128_t; -+ -+ out_uint8x16_t = vreinterpretq_u8_p128 (arg0_poly128_t); -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQf32_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQf32_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQf32_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ int *initial_value; ++ unsigned int id; ++ unsigned int inherit :1; ++ unsigned int animated :1; ++ unsigned int affects_size :1; ++ unsigned int affects_font :1; + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ int * parse_value; ++ int * query_value; ++ int * assign_value; ++}; + -+#include "arm_neon.h" ++void ++g_assertion_message_expr (const char *domain, ++ const char *file, ++ int line, ++ const char *func, ++ const char *expr) __attribute__((__noreturn__)); + -+void test_vreinterpretQf32_p64 (void) ++void ++g_assertion_message_expr (const char *domain, ++ const char *file, ++ int line, ++ const char *func, ++ const char *expr) +{ -+ float32x4_t out_float32x4_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_float32x4_t = vreinterpretq_f32_p64 (arg0_poly64x2_t); ++ __builtin_abort (); +} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_u64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretp64_u64 (void) ++int ++get_id (GtkCssStyleProperty *property) +{ -+ poly64x1_t out_poly64x1_t; -+ uint64x1_t arg0_uint64x1_t; -+ -+ out_poly64x1_t = vreinterpret_p64_u64 (arg0_uint64x1_t); ++ return 1; +} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vdup_lanep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vdup_lanep64.c -@@ -0,0 +1,19 @@ -+/* Test the `vdup_lanep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vdup_lanep64 (void) ++int ++_gtk_css_style_property_get_type () +{ -+ poly64x1_t out_poly64x1_t; -+ poly64x1_t arg0_poly64x1_t; -+ -+ out_poly64x1_t = vdup_lane_p64 (arg0_poly64x1_t, 0); ++ return 1; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_p16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_p16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_p16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++GtkCssStyleProperty * ++g_object_new (int object_type, ++ const char *first_property_name, ++ ...) ++{ ++ return (GtkCssStyleProperty *) __builtin_malloc (sizeof (GtkCssStyleProperty)); ++} + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++typedef enum { ++ INHERIT = (1 << 0), ++ ANIMATED = (1 << 1), ++ RESIZE = (1 << 2), ++ FONT = (1 << 3) ++} GtkStylePropertyFlags; + -+void test_vreinterpretp64_p16 (void) ++int t = 0; ++void ++gtk_css_style_property_register (const char * name, ++ int expected_id, ++ int value_type, ++ int flags, ++ int *parse_value, ++ int *query_value, ++ int *assign_value, ++ int *initial_value) +{ -+ poly64x1_t out_poly64x1_t; -+ poly16x4_t arg0_poly16x4_t; -+ -+ out_poly64x1_t = vreinterpret_p64_p16 (arg0_poly16x4_t); -+} ++ GtkCssStyleProperty *node; + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ do ++ { ++ if (__builtin_expect (__extension__ ( ++ { ++ int _g_boolean_var_; ++ if (initial_value != ((void *)0)) ++ _g_boolean_var_ = 1; ++ else ++ _g_boolean_var_ = 0; ++ _g_boolean_var_; ++ }), ++ 1)) ++ ; ++ else ++ g_assertion_message_expr ("Gtk", ++ "gtkcssstylepropertyimpl.c", ++ 85, ++ ((const char*) (__PRETTY_FUNCTION__)), ++ "initial_value != NULL"); ++ } while (0); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ do ++ { ++ if (__builtin_expect (__extension__ ( ++ { ++ int _g_boolean_var_; ++ if (parse_value != ((void *)0)) ++ _g_boolean_var_ = 1; ++ else ++ _g_boolean_var_ = 0; ++ _g_boolean_var_; ++ }), ++ 1)) ++ ; ++ else ++ g_assertion_message_expr ("Gtk", ++ "gtkcssstylepropertyimpl.c", ++ 86, ++ ((const char*) (__PRETTY_FUNCTION__)), ++ "parse_value != NULL"); ++ } while (0); + -+#include "arm_neon.h" ++ do ++ { ++ if (__builtin_expect (__extension__ ( ++ { ++ int _g_boolean_var_; ++ if (value_type == ((int) ((1) << (2))) ++ || query_value != ((void *)0)) ++ _g_boolean_var_ = 1; ++ else ++ _g_boolean_var_ = 0; ++ _g_boolean_var_; ++ }), ++ 1)) ++ ; ++ else ++ g_assertion_message_expr ("Gtk", ++ "gtkcssstylepropertyimpl.c", ++ 87, ((const char*) (__PRETTY_FUNCTION__)), ++ "value_type == NONE || query_value != NULL"); ++ } while (0); + -+void test_vreinterpretQp128_p64 (void) -+{ -+ poly128_t out_poly128_t; -+ poly64x2_t arg0_poly64x2_t; ++ /* FLAGS is changed in a cond_exec instruction with pr57637. */ ++ if (flags == 15) ++ t = 15; + -+ out_poly128_t = vreinterpretq_p128_p64 (arg0_poly64x2_t); -+} ++ do ++ { ++ if (__builtin_expect (__extension__ ( ++ { ++ int _g_boolean_var_; ++ if (value_type == ((1) << (2)) ++ || assign_value != ((void *)0)) ++ _g_boolean_var_ = 1; ++ else ++ _g_boolean_var_ = 0; ++ _g_boolean_var_; ++ }), ++ 1)) ++ ; ++ else ++ g_assertion_message_expr ("Gtk", ++ "gtkcssstylepropertyimpl.c", ++ 88, ((const char*) (__PRETTY_FUNCTION__)), ++ "value_type == NONE || assign_value != NULL"); ++ } while (0); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu16_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu16_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu16_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ node = g_object_new ((_gtk_css_style_property_get_type ()), ++ "value-type", value_type, ++ "affects-size", (flags & RESIZE) ? (0) : (!(0)), ++ "affects-font", (flags & FONT) ? (!(0)) : (0), ++ "animated", (flags & ANIMATED) ? (!(0)) : (0), ++ "inherit", (flags & INHERIT) ? (!(0)) : (0), ++ "initial-value", initial_value, ++ "name", name, ++ ((void *)0)); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ node->parse_value = parse_value; ++ node->query_value = query_value; ++ node->assign_value = assign_value; + -+#include "arm_neon.h" ++ do ++ { ++ if (__builtin_expect (__extension__ ( ++ { ++ int _g_boolean_var_; ++ if (get_id (node) == expected_id) ++ _g_boolean_var_ = 1; ++ else ++ _g_boolean_var_ = 0; ++ _g_boolean_var_; ++ }), ++ 1)) ++ ; ++ else ++ g_assertion_message_expr ("Gtk", ++ "gtkcssstylepropertyimpl.c", ++ 106, ++ ((const char*) (__PRETTY_FUNCTION__)), ++ "get_id (node) == expected_id"); ++ } while (0); ++} + -+void test_vreinterpretQu16_p64 (void) ++int main () +{ -+ uint16x8_t out_uint16x8_t; -+ poly64x2_t arg0_poly64x2_t; ++ gtk_css_style_property_register ("test", 1, 4, 15, &t, &t, &t, &t); + -+ out_uint16x8_t = vreinterpretq_u16_p64 (arg0_poly64x2_t); ++ if (t != 15) ++ __builtin_abort (); ++ return 0; +} +--- a/src/gcc/testsuite/gcc.target/aarch64/insv_2.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/insv_2.c +@@ -0,0 +1,85 @@ ++/* { dg-do run { target aarch64*-*-* } } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ ++/* { dg-require-effective-target aarch64_big_endian } */ + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets32_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets32_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterprets32_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++extern void abort (void); + -+void test_vreinterprets32_p64 (void) ++typedef struct bitfield +{ -+ int32x2_t out_int32x2_t; -+ poly64x1_t arg0_poly64x1_t; ++ unsigned short eight: 8; ++ unsigned short four: 4; ++ unsigned short five: 5; ++ unsigned short seven: 7; ++ unsigned int sixteen: 16; ++} bitfield; + -+ out_int32x2_t = vreinterpret_s32_p64 (arg0_poly64x1_t); ++bitfield ++bfi1 (bitfield a) ++{ ++ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 56, 8" } } */ ++ a.eight = 3; ++ return a; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets8_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets8_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterprets8_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterprets8_p64 (void) ++bitfield ++bfi2 (bitfield a) +{ -+ int8x8_t out_int8x8_t; -+ poly64x1_t arg0_poly64x1_t; -+ -+ out_int8x8_t = vreinterpret_s8_p64 (arg0_poly64x1_t); ++ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 43, 5" } } */ ++ a.five = 7; ++ return a; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vcvtf16_f32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vcvtf16_f32.c -@@ -0,0 +1,20 @@ -+/* Test the `vcvtf16_f32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_neon_fp16_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_neon_fp16 } */ -+ -+#include "arm_neon.h" -+ -+void test_vcvtf16_f32 (void) ++bitfield ++movk (bitfield a) +{ -+ float16x4_t out_float16x4_t; -+ float32x4_t arg0_float32x4_t; -+ -+ out_float16x4_t = vcvt_f16_f32 (arg0_float32x4_t); ++ /* { dg-final { scan-assembler "movk\tx\[0-9\]+, 0x1d6b, lsl 16" } } */ ++ a.sixteen = 7531; ++ return a; +} + -+/* { dg-final { scan-assembler "vcvt\.f16.f32\[ \]+\[dD\]\[0-9\]+, \[qQ\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets64_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets64_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterprets64_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterprets64_p64 (void) ++bitfield ++set1 (bitfield a) +{ -+ int64x1_t out_int64x1_t; -+ poly64x1_t arg0_poly64x1_t; -+ -+ out_int64x1_t = vreinterpret_s64_p64 (arg0_poly64x1_t); ++ /* { dg-final { scan-assembler "orr\tx\[0-9\]+, x\[0-9\]+, 272678883688448" } } */ ++ a.five = 0x1f; ++ return a; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu64_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu64_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu64_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQu64_p128 (void) ++bitfield ++set0 (bitfield a) +{ -+ uint64x2_t out_uint64x2_t; -+ poly128_t arg0_poly128_t; -+ -+ out_uint64x2_t = vreinterpretq_u64_p128 (arg0_poly128_t); ++ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -272678883688449" } } */ ++ a.five = 0; ++ return a; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_s8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" + -+void test_vreinterpretp64_s8 (void) ++int ++main (int argc, char** argv) +{ -+ poly64x1_t out_poly64x1_t; -+ int8x8_t arg0_int8x8_t; ++ static bitfield a; ++ bitfield b = bfi1 (a); ++ bitfield c = bfi2 (b); ++ bitfield d = movk (c); + -+ out_poly64x1_t = vreinterpret_p64_s8 (arg0_int8x8_t); -+} ++ if (d.eight != 3) ++ abort (); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld1_dupp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld1_dupp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld1_dupp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ if (d.five != 7) ++ abort (); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ if (d.sixteen != 7531) ++ abort (); + -+#include "arm_neon.h" ++ d = set1 (d); ++ if (d.five != 0x1f) ++ abort (); + -+void test_vld1_dupp64 (void) -+{ -+ poly64x1_t out_poly64x1_t; ++ d = set0 (d); ++ if (d.five != 0) ++ abort (); + -+ out_poly64x1_t = vld1_dup_p64 (0); ++ return 0; +} + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_s32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vrecps.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vrecps.c +@@ -0,0 +1,144 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps" } */ + -+#include "arm_neon.h" ++#include ++#include ++#include + -+void test_vreinterpretp64_s32 (void) ++int ++test_frecps_float32_t (void) +{ -+ poly64x1_t out_poly64x1_t; -+ int32x2_t arg0_int32x2_t; ++ int i; ++ float32_t value = 0.2; ++ float32_t reciprocal = 5.0; ++ float32_t step = vrecpes_f32 (value); ++ /* 3 steps should give us within ~0.001 accuracy. */ ++ for (i = 0; i < 3; i++) ++ step = step * vrecpss_f32 (step, value); + -+ out_poly64x1_t = vreinterpret_p64_s32 (arg0_int32x2_t); ++ return fabs (step - reciprocal) < 0.001; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vsriQ_np64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vsriQ_np64.c -@@ -0,0 +1,21 @@ -+/* Test the `vsriQ_np64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "frecpe\\ts\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "frecps\\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" } } */ + -+void test_vsriQ_np64 (void) ++int ++test_frecps_float32x2_t (void) +{ -+ poly64x2_t out_poly64x2_t; -+ poly64x2_t arg0_poly64x2_t; -+ poly64x2_t arg1_poly64x2_t; ++ int i; ++ int ret = 1; + -+ out_poly64x2_t = vsriq_n_p64 (arg0_poly64x2_t, arg1_poly64x2_t, 1); -+} ++ const float32_t value_pool[] = {0.2, 0.4}; ++ const float32_t reciprocal_pool[] = {5.0, 2.5}; ++ float32x2_t value = vld1_f32 (value_pool); ++ float32x2_t reciprocal = vld1_f32 (reciprocal_pool); + -+/* { dg-final { scan-assembler "vsri\.64\[ \]+\[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vbslQp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vbslQp64.c -@@ -0,0 +1,22 @@ -+/* Test the `vbslQp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ float32x2_t step = vrecpe_f32 (value); ++ /* 3 steps should give us within ~0.001 accuracy. */ ++ for (i = 0; i < 3; i++) ++ step = step * vrecps_f32 (step, value); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ ret &= fabs (vget_lane_f32 (step, 0) ++ - vget_lane_f32 (reciprocal, 0)) < 0.001; ++ ret &= fabs (vget_lane_f32 (step, 1) ++ - vget_lane_f32 (reciprocal, 1)) < 0.001; + -+#include "arm_neon.h" ++ return ret; ++} + -+void test_vbslQp64 (void) ++/* { dg-final { scan-assembler "frecpe\\tv\[0-9\]+.2s, v\[0-9\]+.2s" } } */ ++/* { dg-final { scan-assembler "frecps\\tv\[0-9\]+.2s, v\[0-9\]+.2s, v\[0-9\]+.2s" } } */ ++ ++int ++test_frecps_float32x4_t (void) +{ -+ poly64x2_t out_poly64x2_t; -+ uint64x2_t arg0_uint64x2_t; -+ poly64x2_t arg1_poly64x2_t; -+ poly64x2_t arg2_poly64x2_t; ++ int i; ++ int ret = 1; + -+ out_poly64x2_t = vbslq_p64 (arg0_uint64x2_t, arg1_poly64x2_t, arg2_poly64x2_t); -+} ++ const float32_t value_pool[] = {0.2, 0.4, 0.5, 0.8}; ++ const float32_t reciprocal_pool[] = {5.0, 2.5, 2.0, 1.25}; ++ float32x4_t value = vld1q_f32 (value_pool); ++ float32x4_t reciprocal = vld1q_f32 (reciprocal_pool); + -+/* { dg-final { scan-assembler "((vbsl)|(vbit)|(vbif))\[ \]+\[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs32_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs32_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs32_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ float32x4_t step = vrecpeq_f32 (value); ++ /* 3 steps should give us within ~0.001 accuracy. */ ++ for (i = 0; i < 3; i++) ++ step = step * vrecpsq_f32 (step, value); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ ret &= fabs (vgetq_lane_f32 (step, 0) ++ - vgetq_lane_f32 (reciprocal, 0)) < 0.001; ++ ret &= fabs (vgetq_lane_f32 (step, 1) ++ - vgetq_lane_f32 (reciprocal, 1)) < 0.001; ++ ret &= fabs (vgetq_lane_f32 (step, 2) ++ - vgetq_lane_f32 (reciprocal, 2)) < 0.001; ++ ret &= fabs (vgetq_lane_f32 (step, 3) ++ - vgetq_lane_f32 (reciprocal, 3)) < 0.001; + -+#include "arm_neon.h" ++ return ret; ++} + -+void test_vreinterpretQs32_p128 (void) ++/* { dg-final { scan-assembler "frecpe\\tv\[0-9\]+.4s, v\[0-9\]+.4s" } } */ ++/* { dg-final { scan-assembler "frecps\\tv\[0-9\]+.4s, v\[0-9\]+.4s, v\[0-9\]+.4s" } } */ ++ ++int ++test_frecps_float64_t (void) +{ -+ int32x4_t out_int32x4_t; -+ poly128_t arg0_poly128_t; ++ int i; ++ float64_t value = 0.2; ++ float64_t reciprocal = 5.0; ++ float64_t step = vrecped_f64 (value); ++ /* 3 steps should give us within ~0.001 accuracy. */ ++ for (i = 0; i < 3; i++) ++ step = step * vrecpsd_f64 (step, value); + -+ out_int32x4_t = vreinterpretq_s32_p128 (arg0_poly128_t); ++ return fabs (step - reciprocal) < 0.001; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_u8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "frecpe\\td\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "frecps\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" } } */ + -+void test_vreinterpretp64_u8 (void) ++int ++test_frecps_float64x2_t (void) +{ -+ poly64x1_t out_poly64x1_t; -+ uint8x8_t arg0_uint8x8_t; ++ int i; ++ int ret = 1; + -+ out_poly64x1_t = vreinterpret_p64_u8 (arg0_uint8x8_t); -+} ++ const float64_t value_pool[] = {0.2, 0.4}; ++ const float64_t reciprocal_pool[] = {5.0, 2.5}; ++ float64x2_t value = vld1q_f64 (value_pool); ++ float64x2_t reciprocal = vld1q_f64 (reciprocal_pool); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vst1Q_lanep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vst1Q_lanep64.c -@@ -0,0 +1,20 @@ -+/* Test the `vst1Q_lanep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ float64x2_t step = vrecpeq_f64 (value); ++ /* 3 steps should give us within ~0.001 accuracy. */ ++ for (i = 0; i < 3; i++) ++ step = step * vrecpsq_f64 (step, value); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ ret &= fabs (vgetq_lane_f64 (step, 0) ++ - vgetq_lane_f64 (reciprocal, 0)) < 0.001; ++ ret &= fabs (vgetq_lane_f64 (step, 1) ++ - vgetq_lane_f64 (reciprocal, 1)) < 0.001; + -+#include "arm_neon.h" ++ return ret; ++} + -+void test_vst1Q_lanep64 (void) ++/* { dg-final { scan-assembler "frecpe\\tv\[0-9\]+.2d, v\[0-9\]+.2d" } } */ ++/* { dg-final { scan-assembler "frecps\\tv\[0-9\]+.2d, v\[0-9\]+.2d, v\[0-9\]+.2d" } } */ ++ ++int ++main (int argc, char **argv) +{ -+ poly64_t *arg0_poly64_t; -+ poly64x2_t arg1_poly64x2_t; ++ if (!test_frecps_float32_t ()) ++ abort (); ++ if (!test_frecps_float32x2_t ()) ++ abort (); ++ if (!test_frecps_float32x4_t ()) ++ abort (); ++ if (!test_frecps_float64_t ()) ++ abort (); ++ if (!test_frecps_float64x2_t ()) ++ abort (); + -+ vst1q_lane_p64 (arg0_poly64_t, arg1_poly64x2_t, 1); ++ return 0; +} + -+/* { dg-final { scan-assembler "vst1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_s16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_s16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/ands_2.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/ands_2.c +@@ -0,0 +1,157 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ + -+#include "arm_neon.h" ++extern void abort (void); + -+void test_vreinterpretp64_s16 (void) ++int ++ands_si_test1 (int a, int b, int c) +{ -+ poly64x1_t out_poly64x1_t; -+ int16x4_t arg0_int16x4_t; ++ int d = a & b; + -+ out_poly64x1_t = vreinterpret_p64_s16 (arg0_int16x4_t); ++ /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler-times "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets16_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterprets16_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterprets16_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterprets16_p64 (void) ++int ++ands_si_test2 (int a, int b, int c) +{ -+ int16x4_t out_int16x4_t; -+ poly64x1_t arg0_poly64x1_t; ++ int d = a & 0x99999999; + -+ out_int16x4_t = vreinterpret_s16_p64 (arg0_poly64x1_t); ++ /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ ++ /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vcombinep64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vcombinep64.c -@@ -0,0 +1,20 @@ -+/* Test the `vcombinep64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++int ++ands_si_test3 (int a, int b, int c) ++{ ++ int d = a & (b << 3); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+#include "arm_neon.h" ++typedef long long s64; + -+void test_vcombinep64 (void) ++s64 ++ands_di_test1 (s64 a, s64 b, s64 c) +{ -+ poly64x2_t out_poly64x2_t; -+ poly64x1_t arg0_poly64x1_t; -+ poly64x1_t arg1_poly64x1_t; ++ s64 d = a & b; + -+ out_poly64x2_t = vcombine_p64 (arg0_poly64x1_t, arg1_poly64x1_t); ++ /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler-times "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld1Qp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld1Qp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld1Qp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vld1Qp64 (void) ++s64 ++ands_di_test2 (s64 a, s64 b, s64 c) +{ -+ poly64x2_t out_poly64x2_t; ++ s64 d = a & 0xaaaaaaaaaaaaaaaall; + -+ out_poly64x2_t = vld1q_p64 (0); ++ /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ ++ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_s64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp128_s64 (void) ++s64 ++ands_di_test3 (s64 a, s64 b, s64 c) +{ -+ poly128_t out_poly128_t; -+ int64x2_t arg0_int64x2_t; ++ s64 d = a & (b << 3); + -+ out_poly128_t = vreinterpretq_p128_s64 (arg0_int64x2_t); ++ /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp8_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp8_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp8_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++int ++main () ++{ ++ int x; ++ s64 y; + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ x = ands_si_test1 (29, 4, 5); ++ if (x != 13) ++ abort (); + -+#include "arm_neon.h" ++ x = ands_si_test1 (5, 2, 20); ++ if (x != 25) ++ abort (); + -+void test_vreinterpretp8_p64 (void) -+{ -+ poly8x8_t out_poly8x8_t; -+ poly64x1_t arg0_poly64x1_t; ++ x = ands_si_test2 (29, 4, 5); ++ if (x != 34) ++ abort (); + -+ out_poly8x8_t = vreinterpret_p8_p64 (arg0_poly64x1_t); -+} ++ x = ands_si_test2 (1024, 2, 20); ++ if (x != 1044) ++ abort (); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vdup_np64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vdup_np64.c -@@ -0,0 +1,19 @@ -+/* Test the `vdup_np64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ x = ands_si_test3 (35, 4, 5); ++ if (x != 41) ++ abort (); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ x = ands_si_test3 (5, 2, 20); ++ if (x != 25) ++ abort (); + -+#include "arm_neon.h" ++ y = ands_di_test1 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); + -+void test_vdup_np64 (void) -+{ -+ poly64x1_t out_poly64x1_t; -+ poly64_t arg0_poly64_t; ++ if (y != ((0x130000029ll & 0x320000004ll) + 0x320000004ll + 0x505050505ll)) ++ abort (); + -+ out_poly64x1_t = vdup_n_p64 (arg0_poly64_t); -+} ++ y = ands_di_test1 (0x5000500050005ll, ++ 0x2111211121112ll, ++ 0x0000000002020ll); ++ if (y != 0x5000500052025ll) ++ abort (); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vst1p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vst1p64.c -@@ -0,0 +1,20 @@ -+/* Test the `vst1p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ y = ands_di_test2 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); ++ if (y != ((0x130000029ll & 0xaaaaaaaaaaaaaaaall) + 0x320000004ll + 0x505050505ll)) ++ abort (); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ y = ands_di_test2 (0x540004100ll, ++ 0x320000004ll, ++ 0x805050205ll); ++ if (y != (0x540004100ll + 0x805050205ll)) ++ abort (); + -+#include "arm_neon.h" ++ y = ands_di_test3 (0x130000029ll, ++ 0x064000008ll, ++ 0x505050505ll); ++ if (y != ((0x130000029ll & (0x064000008ll << 3)) ++ + 0x064000008ll + 0x505050505ll)) ++ abort (); + -+void test_vst1p64 (void) -+{ -+ poly64_t *arg0_poly64_t; -+ poly64x1_t arg1_poly64x1_t; ++ y = ands_di_test3 (0x130002900ll, ++ 0x088000008ll, ++ 0x505050505ll); ++ if (y != (0x130002900ll + 0x505050505ll)) ++ abort (); + -+ vst1_p64 (arg0_poly64_t, arg1_poly64x1_t); ++ return 0; +} + -+/* { dg-final { scan-assembler "vst1\.64\[ \]+((\\\{\[dD\]\[0-9\]+\\\})|(\[dD\]\[0-9\]+)), \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu8_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu8_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretu8_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/scalar-vca.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/scalar-vca.c +@@ -0,0 +1,72 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps" } */ + -+#include "arm_neon.h" ++#include + -+void test_vreinterpretu8_p64 (void) -+{ -+ uint8x8_t out_uint8x8_t; -+ poly64x1_t arg0_poly64x1_t; ++extern void abort (void); ++extern float fabsf (float); ++extern double fabs (double); + -+ out_uint8x8_t = vreinterpret_u8_p64 (arg0_poly64x1_t); -+} ++#define NUM_TESTS 8 + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_u32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++float input_s1[] = {0.1f, -0.1f, 0.4f, 10.3f, 200.0f, -800.0f, -13.0f, -0.5f}; ++float input_s2[] = {-0.2f, 0.4f, 0.04f, -100.3f, 2.0f, -80.0f, 13.0f, -0.5f}; ++double input_d1[] = {0.1, -0.1, 0.4, 10.3, 200.0, -800.0, -13.0, -0.5}; ++double input_d2[] = {-0.2, 0.4, 0.04, -100.3, 2.0, -80.0, 13.0, -0.5}; + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#define TEST(TEST, CMP, SUFFIX, WIDTH, F) \ ++int \ ++test_fca##TEST##SUFFIX##_float##WIDTH##_t (void) \ ++{ \ ++ int ret = 0; \ ++ int i = 0; \ ++ uint##WIDTH##_t output[NUM_TESTS]; \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ { \ ++ float##WIDTH##_t f1 = fabs##F (input_##SUFFIX##1[i]); \ ++ float##WIDTH##_t f2 = fabs##F (input_##SUFFIX##2[i]); \ ++ /* Inhibit optimization of our linear test loop. */ \ ++ asm volatile ("" : : : "memory"); \ ++ output[i] = f1 CMP f2 ? -1 : 0; \ ++ } \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ { \ ++ output[i] = vca##TEST##SUFFIX##_f##WIDTH (input_##SUFFIX##1[i], \ ++ input_##SUFFIX##2[i]) \ ++ ^ output[i]; \ ++ /* Inhibit autovectorization of our scalar test loop. */ \ ++ asm volatile ("" : : : "memory"); \ ++ } \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ ret |= output[i]; \ ++ \ ++ return ret; \ ++} + -+#include "arm_neon.h" ++TEST (ge, >=, s, 32, f) ++/* { dg-final { scan-assembler "facge\\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" } } */ ++TEST (ge, >=, d, 64, ) ++/* { dg-final { scan-assembler "facge\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" } } */ ++TEST (gt, >, s, 32, f) ++/* { dg-final { scan-assembler "facgt\\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" } } */ ++TEST (gt, >, d, 64, ) ++/* { dg-final { scan-assembler "facgt\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" } } */ + -+void test_vreinterpretp64_u32 (void) ++int ++main (int argc, char **argv) +{ -+ poly64x1_t out_poly64x1_t; -+ uint32x2_t arg0_uint32x2_t; -+ -+ out_poly64x1_t = vreinterpret_p64_u32 (arg0_uint32x2_t); ++ if (test_fcages_float32_t ()) ++ abort (); ++ if (test_fcaged_float64_t ()) ++ abort (); ++ if (test_fcagts_float32_t ()) ++ abort (); ++ if (test_fcagtd_float64_t ()) ++ abort (); ++ return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu32_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu32_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretu32_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.x +@@ -0,0 +1,37 @@ ++int v = 0; + -+void test_vreinterpretu32_p64 (void) ++int ++atomic_fetch_add_ACQ_REL (int a) +{ -+ uint32x2_t out_uint32x2_t; -+ poly64x1_t arg0_poly64x1_t; -+ -+ out_uint32x2_t = vreinterpret_u32_p64 (arg0_poly64x1_t); ++ return __atomic_fetch_add (&v, a, __ATOMIC_ACQ_REL); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld2_dupp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld2_dupp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld2_dupp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vld2_dupp64 (void) ++int ++atomic_fetch_sub_ACQ_REL (int a) +{ -+ poly64x1x2_t out_poly64x1x2_t; -+ -+ out_poly64x1x2_t = vld2_dup_p64 (0); ++ return __atomic_fetch_sub (&v, a, __ATOMIC_ACQ_REL); +} + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu64_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu64_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretu64_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretu64_p64 (void) ++int ++atomic_fetch_and_ACQ_REL (int a) +{ -+ uint64x1_t out_uint64x1_t; -+ poly64x1_t arg0_poly64x1_t; -+ -+ out_uint64x1_t = vreinterpret_u64_p64 (arg0_poly64x1_t); ++ return __atomic_fetch_and (&v, a, __ATOMIC_ACQ_REL); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vsliQ_np64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vsliQ_np64.c -@@ -0,0 +1,21 @@ -+/* Test the `vsliQ_np64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vsliQ_np64 (void) ++int ++atomic_fetch_nand_ACQ_REL (int a) +{ -+ poly64x2_t out_poly64x2_t; -+ poly64x2_t arg0_poly64x2_t; -+ poly64x2_t arg1_poly64x2_t; -+ -+ out_poly64x2_t = vsliq_n_p64 (arg0_poly64x2_t, arg1_poly64x2_t, 1); ++ return __atomic_fetch_nand (&v, a, __ATOMIC_ACQ_REL); +} + -+/* { dg-final { scan-assembler "vsli\.64\[ \]+\[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_u16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_u16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretp64_u16 (void) ++int ++atomic_fetch_xor_ACQ_REL (int a) +{ -+ poly64x1_t out_poly64x1_t; -+ uint16x4_t arg0_uint16x4_t; -+ -+ out_poly64x1_t = vreinterpret_p64_u16 (arg0_uint16x4_t); ++ return __atomic_fetch_xor (&v, a, __ATOMIC_ACQ_REL); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_u64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_u64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQp128_u64 (void) ++int ++atomic_fetch_or_ACQ_REL (int a) +{ -+ poly128_t out_poly128_t; -+ uint64x2_t arg0_uint64x2_t; -+ -+ out_poly128_t = vreinterpretq_p128_u64 (arg0_uint64x2_t); ++ return __atomic_fetch_or (&v, a, __ATOMIC_ACQ_REL); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/vect_smlal_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect_smlal_1.c +@@ -0,0 +1,325 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 -fno-inline -save-temps -fno-vect-cost-model" } */ + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vst2p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vst2p64.c -@@ -0,0 +1,20 @@ -+/* Test the `vst2p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++typedef signed char S8_t; ++typedef signed short S16_t; ++typedef signed int S32_t; ++typedef signed long S64_t; ++typedef signed char *__restrict__ pS8_t; ++typedef signed short *__restrict__ pS16_t; ++typedef signed int *__restrict__ pS32_t; ++typedef signed long *__restrict__ pS64_t; ++typedef unsigned char U8_t; ++typedef unsigned short U16_t; ++typedef unsigned int U32_t; ++typedef unsigned long U64_t; ++typedef unsigned char *__restrict__ pU8_t; ++typedef unsigned short *__restrict__ pU16_t; ++typedef unsigned int *__restrict__ pU32_t; ++typedef unsigned long *__restrict__ pU64_t; + -+#include "arm_neon.h" ++extern void abort (); + -+void test_vst2p64 (void) ++void ++test_addS64_tS32_t4 (pS64_t a, pS32_t b, pS32_t c) +{ -+ poly64_t *arg0_poly64_t; -+ poly64x1x2_t arg1_poly64x1x2_t; -+ -+ vst2_p64 (arg0_poly64_t, arg1_poly64x1x2_t); ++ int i; ++ for (i = 0; i < 4; i++) ++ a[i] += (S64_t) b[i] * (S64_t) c[i]; +} + -+/* { dg-final { scan-assembler "vst1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp8_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp8_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp8_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "smlal\tv\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "smlal2\tv\[0-9\]+\.2d" } } */ + -+void test_vreinterpretQp8_p128 (void) ++void ++test_addS32_tS16_t8 (pS32_t a, pS16_t b, pS16_t c) +{ -+ poly8x16_t out_poly8x16_t; -+ poly128_t arg0_poly128_t; -+ -+ out_poly8x16_t = vreinterpretq_p8_p128 (arg0_poly128_t); ++ int i; ++ for (i = 0; i < 8; i++) ++ a[i] += (S32_t) b[i] * (S32_t) c[i]; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_f32.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_f32.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_f32' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "smlal\tv\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "smlal2\tv\[0-9\]+\.4s" } } */ + -+void test_vreinterpretp64_f32 (void) ++void ++test_addS16_tS8_t16 (pS16_t a, pS8_t b, pS8_t c) +{ -+ poly64x1_t out_poly64x1_t; -+ float32x2_t arg0_float32x2_t; -+ -+ out_poly64x1_t = vreinterpret_p64_f32 (arg0_float32x2_t); ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] += (S16_t) b[i] * (S16_t) c[i]; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQf32_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQf32_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQf32_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ -+void test_vreinterpretQf32_p128 (void) ++void ++test_addS16_tS8_t16_neg0 (pS16_t a, pS8_t b, pS8_t c) +{ -+ float32x4_t out_float32x4_t; -+ poly128_t arg0_poly128_t; -+ -+ out_float32x4_t = vreinterpretq_f32_p128 (arg0_poly128_t); ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] += (S16_t) -b[i] * (S16_t) -c[i]; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vextQp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vextQp64.c -@@ -0,0 +1,21 @@ -+/* Test the `vextQp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++void ++test_addS16_tS8_t16_neg1 (pS16_t a, pS8_t b, pS8_t c) ++{ ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] -= (S16_t) b[i] * (S16_t) -c[i]; ++} + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++void ++test_addS16_tS8_t16_neg2 (pS16_t a, pS8_t b, pS8_t c) ++{ ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] -= (S16_t) -b[i] * (S16_t) c[i]; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "smlal\tv\[0-9\]+\.8h" 4 } } */ ++/* { dg-final { scan-assembler-times "smlal2\tv\[0-9\]+\.8h" 4 } } */ + -+void test_vextQp64 (void) ++void ++test_subS64_tS32_t4 (pS64_t a, pS32_t b, pS32_t c) +{ -+ poly64x2_t out_poly64x2_t; -+ poly64x2_t arg0_poly64x2_t; -+ poly64x2_t arg1_poly64x2_t; -+ -+ out_poly64x2_t = vextq_p64 (arg0_poly64x2_t, arg1_poly64x2_t, 0); ++ int i; ++ for (i = 0; i < 4; i++) ++ a[i] -= (S64_t) b[i] * (S64_t) c[i]; +} + -+/* { dg-final { scan-assembler "vext\.64\[ \]+\[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_p16.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_p16.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_p16' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler "smlsl\tv\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "smlsl2\tv\[0-9\]+\.2d" } } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++void ++test_subS32_tS16_t8 (pS32_t a, pS16_t b, pS16_t c) ++{ ++ int i; ++ for (i = 0; i < 8; i++) ++ a[i] -= (S32_t) b[i] * (S32_t) c[i]; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "smlsl\tv\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "smlsl2\tv\[0-9\]+\.4s" } } */ + -+void test_vreinterpretQp128_p16 (void) ++void ++test_subS16_tS8_t16 (pS16_t a, pS8_t b, pS8_t c) +{ -+ poly128_t out_poly128_t; -+ poly16x8_t arg0_poly16x8_t; -+ -+ out_poly128_t = vreinterpretq_p128_p16 (arg0_poly16x8_t); ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] -= (S16_t) b[i] * (S16_t) c[i]; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++void ++test_subS16_tS8_t16_neg0 (pS16_t a, pS8_t b, pS8_t c) ++{ ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] += (S16_t) -b[i] * (S16_t) c[i]; ++} + -+#include "arm_neon.h" ++void ++test_subS16_tS8_t16_neg1 (pS16_t a, pS8_t b, pS8_t c) ++{ ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] += (S16_t) b[i] * (S16_t) -c[i]; ++} + -+void test_vreinterpretQp64_p128 (void) ++void ++test_subS16_tS8_t16_neg2 (pS16_t a, pS8_t b, pS8_t c) +{ -+ poly64x2_t out_poly64x2_t; -+ poly128_t arg0_poly128_t; ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] += -((S16_t) b[i] * (S16_t) c[i]); ++} + -+ out_poly64x2_t = vreinterpretq_p64_p128 (arg0_poly128_t); ++void ++test_subS16_tS8_t16_neg3 (pS16_t a, pS8_t b, pS8_t c) ++{ ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] -= (S16_t) -b[i] * (S16_t) -c[i]; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs16_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs16_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs16_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler-times "smlsl\tv\[0-9\]+\.8h" 5 } } */ ++/* { dg-final { scan-assembler-times "smlsl2\tv\[0-9\]+\.8h" 5 } } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++void ++test_addU64_tU32_t4 (pU64_t a, pU32_t b, pU32_t c) ++{ ++ int i; ++ for (i = 0; i < 4; i++) ++ a[i] += (U64_t) b[i] * (U64_t) c[i]; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "umlal\tv\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "umlal2\tv\[0-9\]+\.2d" } } */ + -+void test_vreinterpretQs16_p128 (void) ++void ++test_addU32_tU16_t8 (pU32_t a, pU16_t b, pU16_t c) +{ -+ int16x8_t out_int16x8_t; -+ poly128_t arg0_poly128_t; -+ -+ out_int16x8_t = vreinterpretq_s16_p128 (arg0_poly128_t); ++ int i; ++ for (i = 0; i < 8; i++) ++ a[i] += (U32_t) b[i] * (U32_t) c[i]; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs8_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQs8_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQs8_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler "umlal\tv\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "umlal2\tv\[0-9\]+\.4s" } } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++void ++test_addU16_tU8_t16 (pU16_t a, pU8_t b, pU8_t c) ++{ ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] += (U16_t) b[i] * (U16_t) c[i]; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "umlal\tv\[0-9\]+\.8h" } } */ ++/* { dg-final { scan-assembler "umlal2\tv\[0-9\]+\.8h" } } */ + -+void test_vreinterpretQs8_p64 (void) ++void ++test_subU64_tU32_t4 (pU64_t a, pU32_t b, pU32_t c) +{ -+ int8x16_t out_int8x16_t; -+ poly64x2_t arg0_poly64x2_t; -+ -+ out_int8x16_t = vreinterpretq_s8_p64 (arg0_poly64x2_t); ++ int i; ++ for (i = 0; i < 4; i++) ++ a[i] -= (U64_t) b[i] * (U64_t) c[i]; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vextp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vextp64.c -@@ -0,0 +1,21 @@ -+/* Test the `vextp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler "umlsl\tv\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "umlsl2\tv\[0-9\]+\.2d" } } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++void ++test_subU32_tU16_t8 (pU32_t a, pU16_t b, pU16_t c) ++{ ++ int i; ++ for (i = 0; i < 8; i++) ++ a[i] -= (U32_t) b[i] * (U32_t) c[i]; ++} + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "umlsl\tv\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "umlsl2\tv\[0-9\]+\.4s" } } */ + -+void test_vextp64 (void) ++void ++test_subU16_tU8_t16 (pU16_t a, pU8_t b, pU8_t c) +{ -+ poly64x1_t out_poly64x1_t; -+ poly64x1_t arg0_poly64x1_t; -+ poly64x1_t arg1_poly64x1_t; -+ -+ out_poly64x1_t = vext_p64 (arg0_poly64x1_t, arg1_poly64x1_t, 0); ++ int i; ++ for (i = 0; i < 16; i++) ++ a[i] -= (U16_t) b[i] * (U16_t) c[i]; +} + -+/* { dg-final { scan-assembler "vext\.64\[ \]+\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp16_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp16_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp16_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++/* { dg-final { scan-assembler "umlsl\tv\[0-9\]+\.8h" } } */ ++/* { dg-final { scan-assembler "umlsl2\tv\[0-9\]+\.8h" } } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ + -+#include "arm_neon.h" ++S64_t add_rS64[4] = { 6, 7, -4, -3 }; ++S32_t add_rS32[8] = { 6, 7, -4, -3, 10, 11, 0, 1 }; ++S16_t add_rS16[16] = ++ { 6, 7, -4, -3, 10, 11, 0, 1, 14, 15, 4, 5, 18, 19, 8, 9 }; ++ ++S64_t sub_rS64[4] = { 0, 1, 2, 3 }; ++S32_t sub_rS32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ++S16_t sub_rS16[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + -+void test_vreinterpretQp16_p64 (void) ++U64_t add_rU64[4] = { 0x6, 0x7, 0x2fffffffc, 0x2fffffffd }; ++ ++U32_t add_rU32[8] = +{ -+ poly16x8_t out_poly16x8_t; -+ poly64x2_t arg0_poly64x2_t; ++ 0x6, 0x7, 0x2fffc, 0x2fffd, ++ 0xa, 0xb, 0x30000, 0x30001 ++}; + -+ out_poly16x8_t = vreinterpretq_p16_p64 (arg0_poly64x2_t); -+} ++U16_t add_rU16[16] = ++{ ++ 0x6, 0x7, 0x2fc, 0x2fd, 0xa, 0xb, 0x300, 0x301, ++ 0xe, 0xf, 0x304, 0x305, 0x12, 0x13, 0x308, 0x309 ++}; + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretf32_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretf32_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretf32_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++U64_t sub_rU64[4] = { 0, 1, 2, 3 }; ++U32_t sub_rU32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ++U16_t sub_rU16[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++S8_t neg_r[16] = { -6, -5, 8, 9, -2, -1, 12, 13, 2, 3, 16, 17, 6, 7, 20, 21 }; + -+#include "arm_neon.h" ++S64_t S64_ta[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; ++S32_t S32_tb[16] = { 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2 }; ++S32_t S32_tc[16] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; + -+void test_vreinterpretf32_p64 (void) -+{ -+ float32x2_t out_float32x2_t; -+ poly64x1_t arg0_poly64x1_t; ++S32_t S32_ta[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; ++S16_t S16_tb[16] = { 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2 }; ++S16_t S16_tc[16] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; + -+ out_float32x2_t = vreinterpret_f32_p64 (arg0_poly64x1_t); -+} ++S16_t S16_ta[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; ++S8_t S8_tb[16] = { 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2 }; ++S8_t S8_tc[16] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp128_s8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp128_s8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++#define CHECK(T,N,AS,US) \ ++do \ ++ { \ ++ for (i = 0; i < N; i++) \ ++ if (S##T##_ta[i] != AS##_r##US##T[i]) \ ++ abort (); \ ++ } \ ++while (0) + -+#include "arm_neon.h" ++#define SCHECK(T,N,AS) CHECK(T,N,AS,S) ++#define UCHECK(T,N,AS) CHECK(T,N,AS,U) + -+void test_vreinterpretQp128_s8 (void) -+{ -+ poly128_t out_poly128_t; -+ int8x16_t arg0_int8x16_t; ++#define NCHECK(RES) \ ++do \ ++ { \ ++ for (i = 0; i < 16; i++) \ ++ if (S16_ta[i] != RES[i]) \ ++ abort (); \ ++ } \ ++while (0) + -+ out_poly128_t = vreinterpretq_p128_s8 (arg0_int8x16_t); -+} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_s8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++int ++main () ++{ ++ int i; + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ test_addS64_tS32_t4 (S64_ta, S32_tb, S32_tc); ++ SCHECK (64, 4, add); ++ test_addS32_tS16_t8 (S32_ta, S16_tb, S16_tc); ++ SCHECK (32, 8, add); ++ test_addS16_tS8_t16 (S16_ta, S8_tb, S8_tc); ++ SCHECK (16, 16, add); ++ test_subS64_tS32_t4 (S64_ta, S32_tb, S32_tc); ++ SCHECK (64, 4, sub); ++ test_subS32_tS16_t8 (S32_ta, S16_tb, S16_tc); ++ SCHECK (32, 8, sub); ++ test_subS16_tS8_t16 (S16_ta, S8_tb, S8_tc); ++ SCHECK (16, 16, sub); + -+#include "arm_neon.h" ++ test_addU64_tU32_t4 (S64_ta, S32_tb, S32_tc); ++ UCHECK (64, 4, add); ++ test_addU32_tU16_t8 (S32_ta, S16_tb, S16_tc); ++ UCHECK (32, 8, add); ++ test_addU16_tU8_t16 (S16_ta, S8_tb, S8_tc); ++ UCHECK (16, 16, add); ++ test_subU64_tU32_t4 (S64_ta, S32_tb, S32_tc); ++ UCHECK (64, 4, sub); ++ test_subU32_tU16_t8 (S32_ta, S16_tb, S16_tc); ++ UCHECK (32, 8, sub); ++ test_subU16_tU8_t16 (S16_ta, S8_tb, S8_tc); ++ UCHECK (16, 16, sub); + -+void test_vreinterpretQp64_s8 (void) -+{ -+ poly64x2_t out_poly64x2_t; -+ int8x16_t arg0_int8x16_t; ++ test_addS16_tS8_t16_neg0 (S16_ta, S8_tb, S8_tc); ++ NCHECK (add_rS16); ++ test_subS16_tS8_t16_neg0 (S16_ta, S8_tb, S8_tc); ++ NCHECK (sub_rS16); ++ test_addS16_tS8_t16_neg1 (S16_ta, S8_tb, S8_tc); ++ NCHECK (add_rS16); ++ test_subS16_tS8_t16_neg1 (S16_ta, S8_tb, S8_tc); ++ NCHECK (sub_rS16); ++ test_addS16_tS8_t16_neg2 (S16_ta, S8_tb, S8_tc); ++ NCHECK (add_rS16); ++ test_subS16_tS8_t16_neg2 (S16_ta, S8_tb, S8_tc); ++ NCHECK (sub_rS16); ++ test_subS16_tS8_t16_neg3 (S16_ta, S8_tb, S8_tc); ++ NCHECK (neg_r); + -+ out_poly64x2_t = vreinterpretq_p64_s8 (arg0_int8x16_t); ++ return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vst3p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vst3p64.c -@@ -0,0 +1,20 @@ -+/* Test the `vst3p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ +--- a/src/gcc/testsuite/gcc.target/aarch64/extr.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/extr.c +@@ -0,0 +1,34 @@ ++/* { dg-options "-O2 --save-temps" } */ ++/* { dg-do run } */ + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++extern void abort (void); + -+#include "arm_neon.h" ++int ++test_si (int a, int b) ++{ ++ /* { dg-final { scan-assembler "extr\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, 27\n" } } */ ++ return (a << 5) | ((unsigned int) b >> 27); ++} + -+void test_vst3p64 (void) ++long long ++test_di (long long a, long long b) +{ -+ poly64_t *arg0_poly64_t; -+ poly64x1x3_t arg1_poly64x1x3_t; ++ /* { dg-final { scan-assembler "extr\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, 45\n" } } */ ++ return (a << 19) | ((unsigned long long) b >> 45); ++} + -+ vst3_p64 (arg0_poly64_t, arg1_poly64x1x3_t); ++int ++main () ++{ ++ int v; ++ long long w; ++ v = test_si (0x00000004, 0x30000000); ++ if (v != 0x00000086) ++ abort(); ++ w = test_di (0x0001040040040004ll, 0x0070050066666666ll); ++ if (w != 0x2002002000200380ll) ++ abort(); ++ return 0; +} + -+/* { dg-final { scan-assembler "vst1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vld3_dupp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vld3_dupp64.c -@@ -0,0 +1,19 @@ -+/* Test the `vld3_dupp64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-compile.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-compile.c +@@ -16,5 +16,7 @@ + /* { dg-final { scan-assembler "uminv" } } */ + /* { dg-final { scan-assembler "smaxv" } } */ + /* { dg-final { scan-assembler "sminv" } } */ ++/* { dg-final { scan-assembler "sabd" } } */ ++/* { dg-final { scan-assembler "saba" } } */ + /* { dg-final { scan-assembler-times "addv" 2} } */ + /* { dg-final { scan-assembler-times "addp" 2} } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c +@@ -2,12 +2,13 @@ + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ + + #define FTYPE double ++#define ITYPE long + #define OP == + #define INV_OP != + + #include "vect-fcm.x" + +-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ ++/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ + /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ + /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ + /* { dg-final { cleanup-tree-dump "vect" } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/adds3.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/adds3.c +@@ -0,0 +1,61 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ + -+#include "arm_neon.h" ++extern void abort (void); ++typedef long long s64; + -+void test_vld3_dupp64 (void) ++int ++adds_ext (s64 a, int b, int c) +{ -+ poly64x1x3_t out_poly64x1x3_t; ++ s64 d = a + b; + -+ out_poly64x1x3_t = vld3_dup_p64 (0); ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "vld1\.64\[ \]+\\\{((\[dD\]\[0-9\]+-\[dD\]\[0-9\]+)|(\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+))\\\}, \\\[\[rR\]\[0-9\]+\(:\[0-9\]+\)?\\\]!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu16_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretu16_p64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretu16_p64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++int ++adds_shift_ext (s64 a, int b, int c) ++{ ++ s64 d = (a + ((s64)b << 3)); + -+#include "arm_neon.h" ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+void test_vreinterpretu16_p64 (void) ++int main () +{ -+ uint16x4_t out_uint16x4_t; -+ poly64x1_t arg0_poly64x1_t; ++ int x; ++ s64 y; + -+ out_uint16x4_t = vreinterpret_u16_p64 (arg0_poly64x1_t); -+} ++ x = adds_ext (0x13000002ll, 41, 15); ++ if (x != 318767203) ++ abort (); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_p8.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretp64_p8.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretp64_p8' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ x = adds_ext (0x50505050ll, 29, 4); ++ if (x != 1347440782) ++ abort (); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++ x = adds_ext (0x12121212121ll, 2, 14); ++ if (x != 555819315) ++ abort (); + -+#include "arm_neon.h" ++ x = adds_shift_ext (0x123456789ll, 4, 12); ++ if (x != 591751097) ++ abort (); + -+void test_vreinterpretp64_p8 (void) -+{ -+ poly64x1_t out_poly64x1_t; -+ poly8x8_t arg0_poly8x8_t; ++ x = adds_shift_ext (0x02020202ll, 9, 8); ++ if (x != 33686107) ++ abort (); + -+ out_poly64x1_t = vreinterpret_p64_p8 (arg0_poly8x8_t); -+} ++ x = adds_shift_ext (0x987987987987ll, 23, 41); ++ if (x != -2020050305) ++ abort (); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQp64_s64.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQp64_s64' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ ++ return 0; ++} + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-assembler-times "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw" 2 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/subs2.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/subs2.c +@@ -0,0 +1,155 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ + -+#include "arm_neon.h" ++extern void abort (void); + -+void test_vreinterpretQp64_s64 (void) ++int ++subs_si_test1 (int a, int b, int c) +{ -+ poly64x2_t out_poly64x2_t; -+ int64x2_t arg0_int64x2_t; ++ int d = a - b; + -+ out_poly64x2_t = vreinterpretq_p64_s64 (arg0_int64x2_t); ++ /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu32_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon/vreinterpretQu32_p128.c -@@ -0,0 +1,19 @@ -+/* Test the `vreinterpretQu32_p128' ARM Neon intrinsic. */ -+/* This file was autogenerated by neon-testgen. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crypto } */ ++int ++subs_si_test2 (int a, int b, int c) ++{ ++ int d = a - 0xfff; + -+#include "arm_neon.h" ++ /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, #4095" } } */ ++ /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, #4095" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+void test_vreinterpretQu32_p128 (void) ++int ++subs_si_test3 (int a, int b, int c) +{ -+ uint32x4_t out_uint32x4_t; -+ poly128_t arg0_poly128_t; ++ int d = a - (b << 3); + -+ out_uint32x4_t = vreinterpretq_u32_p128 (arg0_poly128_t); ++ /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/anddi3-opt.c -+++ b/src/gcc/testsuite/gcc.target/arm/anddi3-opt.c -@@ -0,0 +1,11 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O1" } */ ++typedef long long s64; + -+unsigned long long -+muld (unsigned long long X, unsigned long long Y) ++s64 ++subs_di_test1 (s64 a, s64 b, s64 c) +{ -+ unsigned long long mask = 0xffffffffull; -+ return (X & mask) * (Y & mask); -+} ++ s64 d = a - b; + -+/* { dg-final { scan-assembler-not "and\[\\t \]+.+,\[\\t \]*.+,\[\\t \]*.+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c -+++ b/src/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c -@@ -0,0 +1,11 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_prefer_ldrd_strd } */ -+/* { dg-options "-O2" } */ -+int foo(int a, int b, int* p, int *q) -+{ -+ a = p[2] + p[3]; -+ *q = a; -+ *p = a; -+ return a; ++ /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} -+/* { dg-final { scan-assembler "ldrd" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselgtdf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselgtdf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ + -+double -+foo (double x, double y) ++s64 ++subs_di_test2 (s64 a, s64 b, s64 c) +{ -+ volatile int i = 0; -+ return i > 0 ? x : y; ++ s64 d = a - 0x1000ll; ++ ++ /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, #4096" } } */ ++ /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, #4096" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler-times "vselgt.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/acle.exp -+++ b/src/gcc/testsuite/gcc.target/arm/acle/acle.exp -@@ -0,0 +1,35 @@ -+# Copyright (C) 2013-2014 Free Software Foundation, Inc. ++s64 ++subs_di_test3 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a - (b << 3); + -+# 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 3 of the License, 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 GCC; see the file COPYING3. If not see -+# . ++ /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+# GCC testsuite that uses the `dg.exp' driver. ++int main () ++{ ++ int x; ++ s64 y; + -+# Exit immediately if this isn't an ARM target. -+if ![istarget arm*-*-*] then { -+ return -+} ++ x = subs_si_test1 (29, 4, 5); ++ if (x != 34) ++ abort (); + -+# Load support procs. -+load_lib gcc-dg.exp ++ x = subs_si_test1 (5, 2, 20); ++ if (x != 25) ++ abort (); + -+# Initialize `dg'. -+dg-init ++ x = subs_si_test2 (29, 4, 5); ++ if (x != 34) ++ abort (); + -+# Main loop. -+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ -+ "" "" ++ x = subs_si_test2 (1024, 2, 20); ++ if (x != 1044) ++ abort (); + -+# All done. -+dg-finish ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32b.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32b.c -@@ -0,0 +1,20 @@ -+/* Test the crc32b ACLE intrinsic. */ ++ x = subs_si_test3 (35, 4, 5); ++ if (x != 12) ++ abort (); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ ++ x = subs_si_test3 (5, 2, 20); ++ if (x != 25) ++ abort (); + -+#include "arm_acle.h" ++ y = subs_di_test1 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); + -+void test_crc32b (void) -+{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint8_t arg1_uint8_t; ++ if (y != 0x63505052e) ++ abort (); + -+ out_uint32_t = __crc32b (arg0_uint32_t, arg1_uint8_t); -+} ++ y = subs_di_test1 (0x5000500050005ll, ++ 0x2111211121112ll, ++ 0x0000000002020ll); ++ if (y != 0x5000500052025) ++ abort (); + -+/* { dg-final { scan-assembler "crc32b\t...?, ...?, ...?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32d.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32d.c -@@ -0,0 +1,20 @@ -+/* Test the crc32d ACLE intrinsic. */ ++ y = subs_di_test2 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); ++ if (y != 0x95504f532) ++ abort (); + -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ ++ y = subs_di_test2 (0x540004100ll, ++ 0x320000004ll, ++ 0x805050205ll); ++ if (y != 0x1065053309) ++ abort (); + -+#include "arm_acle.h" ++ y = subs_di_test3 (0x130000029ll, ++ 0x064000008ll, ++ 0x505050505ll); ++ if (y != 0x63505052e) ++ abort (); + -+void test_crc32d (void) -+{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint64_t arg1_uint64_t; ++ y = subs_di_test3 (0x130002900ll, ++ 0x088000008ll, ++ 0x505050505ll); ++ if (y != 0x635052e05) ++ abort (); + -+ out_uint32_t = __crc32d (arg0_uint32_t, arg1_uint64_t); ++ return 0; +} + -+/* { dg-final { scan-assembler-times "crc32w\t...?, ...?, ...?\n" 2 } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32cb.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32cb.c -@@ -0,0 +1,20 @@ -+/* Test the crc32cb ACLE intrinsic. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/bics_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/bics_1.c +@@ -0,0 +1,107 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ + -+#include "arm_acle.h" ++extern void abort (void); + -+void test_crc32cb (void) ++int ++bics_si_test1 (int a, int b, int c) +{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint8_t arg1_uint8_t; ++ int d = a & ~b; + -+ out_uint32_t = __crc32cb (arg0_uint32_t, arg1_uint8_t); ++ /* { dg-final { scan-assembler-times "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "crc32cb\t...?, ...?, ...?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32cd.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32cd.c -@@ -0,0 +1,20 @@ -+/* Test the crc32cd ACLE intrinsic. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ -+ -+#include "arm_acle.h" -+ -+void test_crc32cd (void) ++int ++bics_si_test2 (int a, int b, int c) +{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint64_t arg1_uint64_t; ++ int d = a & ~(b << 3); + -+ out_uint32_t = __crc32cd (arg0_uint32_t, arg1_uint64_t); ++ /* { dg-final { scan-assembler "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler-times "crc32cw\t...?, ...?, ...?\n" 2 } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32w.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32w.c -@@ -0,0 +1,20 @@ -+/* Test the crc32w ACLE intrinsic. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ -+ -+#include "arm_acle.h" ++typedef long long s64; + -+void test_crc32w (void) ++s64 ++bics_di_test1 (s64 a, s64 b, s64 c) +{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint32_t arg1_uint32_t; ++ s64 d = a & ~b; + -+ out_uint32_t = __crc32w (arg0_uint32_t, arg1_uint32_t); ++ /* { dg-final { scan-assembler-times "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "crc32w\t...?, ...?, ...?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32h.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32h.c -@@ -0,0 +1,20 @@ -+/* Test the crc32h ACLE intrinsic. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ -+ -+#include "arm_acle.h" -+ -+void test_crc32h (void) ++s64 ++bics_di_test2 (s64 a, s64 b, s64 c) +{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint16_t arg1_uint16_t; ++ s64 d = a & ~(b << 3); + -+ out_uint32_t = __crc32h (arg0_uint32_t, arg1_uint16_t); ++ /* { dg-final { scan-assembler "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "crc32h\t...?, ...?, ...?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32cw.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32cw.c -@@ -0,0 +1,20 @@ -+/* Test the crc32cw ACLE intrinsic. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ -+ -+#include "arm_acle.h" -+ -+void test_crc32cw (void) ++int ++main () +{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint32_t arg1_uint32_t; ++ int x; ++ s64 y; + -+ out_uint32_t = __crc32cw (arg0_uint32_t, arg1_uint32_t); -+} -+ -+/* { dg-final { scan-assembler "crc32cw\t...?, ...?, ...?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/acle/crc32ch.c -+++ b/src/gcc/testsuite/gcc.target/arm/acle/crc32ch.c -@@ -0,0 +1,20 @@ -+/* Test the crc32ch ACLE intrinsic. */ -+ -+/* { dg-do assemble } */ -+/* { dg-require-effective-target arm_crc_ok } */ -+/* { dg-options "-save-temps -O0" } */ -+/* { dg-add-options arm_crc } */ ++ x = bics_si_test1 (29, ~4, 5); ++ if (x != ((29 & 4) + ~4 + 5)) ++ abort (); + -+#include "arm_acle.h" ++ x = bics_si_test1 (5, ~2, 20); ++ if (x != 25) ++ abort (); + -+void test_crc32ch (void) -+{ -+ uint32_t out_uint32_t; -+ uint32_t arg0_uint32_t; -+ uint16_t arg1_uint16_t; ++ x = bics_si_test2 (35, ~4, 5); ++ if (x != ((35 & ~(~4 << 3)) + ~4 + 5)) ++ abort (); + -+ out_uint32_t = __crc32ch (arg0_uint32_t, arg1_uint16_t); -+} ++ x = bics_si_test2 (96, ~2, 20); ++ if (x != 116) ++ abort (); + -+/* { dg-final { scan-assembler "crc32ch\t...?, ...?, ...?\n" } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/arm/iordi3-opt.c -+++ b/src/gcc/testsuite/gcc.target/arm/iordi3-opt.c -@@ -0,0 +1,9 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O1" } */ ++ y = bics_di_test1 (0x130000029ll, ++ ~0x320000004ll, ++ 0x505050505ll); + -+unsigned long long or64 (unsigned long long input) -+{ -+ return input | 0x200000004ULL; -+} ++ if (y != ((0x130000029ll & 0x320000004ll) + ~0x320000004ll + 0x505050505ll)) ++ abort (); + -+/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++ y = bics_di_test1 (0x5000500050005ll, ++ ~0x2111211121112ll, ++ 0x0000000002020ll); ++ if (y != 0x5000500052025ll) ++ abort (); + -+#include "arm_neon.h" ++ y = bics_di_test2 (0x130000029ll, ++ ~0x064000008ll, ++ 0x505050505ll); ++ if (y != ((0x130000029ll & ~(~0x064000008ll << 3)) ++ + ~0x064000008ll + 0x505050505ll)) ++ abort (); + -+int -+foo (void) -+{ -+ uint32_t hash = 0xdeadbeef; -+ uint32x4_t a = {0, 1, 2, 3}; -+ uint32x4_t b = {3, 2, 1, 0}; ++ y = bics_di_test2 (0x130002900ll, ++ ~0x088000008ll, ++ 0x505050505ll); ++ if (y != (0x130002900ll + 0x505050505ll)) ++ abort (); + -+ uint32x4_t res = vsha1pq_u32 (a, hash, b); -+ return res[0]; ++ return 0; +} + -+/* { dg-final { scan-assembler "sha1p.32\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-vmaxv.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vmaxv.c +@@ -0,0 +1,117 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps -ffast-math" } */ + -+#include "../aarch64/atomic-op-relaxed.x" ++#include + -+/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselgesf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselgesf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++extern void abort (void); + -+float -+foo (float x, float y) -+{ -+ volatile int i = 0; -+ return i >= 0 ? x : y; -+} ++#define NUM_TESTS 16 ++#define DELTA 0.000001 + -+/* { dg-final { scan-assembler-times "vselge.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/peep-strd-1.c -+++ b/src/gcc/testsuite/gcc.target/arm/peep-strd-1.c -@@ -0,0 +1,9 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_prefer_ldrd_strd } */ -+/* { dg-options "-O2" } */ -+void foo(int a, int b, int* p) -+{ -+ p[2] = a; -+ p[3] = b; -+} -+/* { dg-final { scan-assembler "strd" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha1su1q_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha1su1q_u32.c -@@ -0,0 +1,17 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++int8_t input_int8[] = {1, 56, 2, -9, -90, 23, 54, 76, ++ -4, 34, 110, -110, 6, 4, 75, -34}; ++int16_t input_int16[] = {1, 56, 2, -9, -90, 23, 54, 76, ++ -4, 34, 110, -110, 6, 4, 75, -34}; ++int32_t input_int32[] = {1, 56, 2, -9, -90, 23, 54, 76, ++ -4, 34, 110, -110, 6, 4, 75, -34}; + -+#include "arm_neon.h" ++uint8_t input_uint8[] = {1, 56, 2, 9, 90, 23, 54, 76, ++ 4, 34, 110, 110, 6, 4, 75, 34}; ++uint16_t input_uint16[] = {1, 56, 2, 9, 90, 23, 54, 76, ++ 4, 34, 110, 110, 6, 4, 75, 34}; ++uint32_t input_uint32[] = {1, 56, 2, 9, 90, 23, 54, 76, ++ 4, 34, 110, 110, 6, 4, 75, 34}; + -+int -+foo (void) -+{ -+ uint32x4_t a = {0xd, 0xe, 0xa, 0xd}; -+ uint32x4_t b = {0, 1, 2, 3}; ++#define EQUAL(a, b) (a == b) + -+ uint32x4_t res = vsha1su1q_u32 (a, b); -+ return res[0]; ++#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES) \ ++int \ ++test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t (void) \ ++{ \ ++ int i, j; \ ++ int moves = (NUM_TESTS - LANES) + 1; \ ++ TYPE##_t out_l[NUM_TESTS]; \ ++ TYPE##_t out_v[NUM_TESTS]; \ ++ \ ++ /* Calculate linearly. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ out_l[i] = input_##TYPE[i]; \ ++ for (j = 0; j < LANES; j++) \ ++ out_l[i] = input_##TYPE[i + j] CMP_OP out_l[i] ? \ ++ input_##TYPE[i + j] : out_l[i]; \ ++ } \ ++ \ ++ /* Calculate using vector reduction intrinsics. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ ++ out_v[i] = v##MAXMIN##v##Q##_##SUFFIX (t1); \ ++ } \ ++ \ ++ /* Compare. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ if (!EQUAL (out_v[i], out_l[i])) \ ++ return 0; \ ++ } \ ++ return 1; \ +} + -+/* { dg-final { scan-assembler "sha1su1.32\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vmullp64.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vmullp64.c -@@ -0,0 +1,15 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++#define BUILD_VARIANTS(TYPE, STYPE, W32, W64) \ ++TEST (max, >, STYPE, , TYPE, W32) \ ++TEST (max, >, STYPE, q, TYPE, W64) \ ++TEST (min, <, STYPE, , TYPE, W32) \ ++TEST (min, <, STYPE, q, TYPE, W64) + -+#include "arm_neon.h" ++BUILD_VARIANTS (int8, s8, 8, 16) ++/* { dg-final { scan-assembler "smaxv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ ++/* { dg-final { scan-assembler "sminv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ ++/* { dg-final { scan-assembler "smaxv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ ++/* { dg-final { scan-assembler "sminv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ ++BUILD_VARIANTS (uint8, u8, 8, 16) ++/* { dg-final { scan-assembler "umaxv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ ++/* { dg-final { scan-assembler "uminv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ ++/* { dg-final { scan-assembler "umaxv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ ++/* { dg-final { scan-assembler "uminv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ ++BUILD_VARIANTS (int16, s16, 4, 8) ++/* { dg-final { scan-assembler "smaxv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ ++/* { dg-final { scan-assembler "sminv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ ++/* { dg-final { scan-assembler "smaxv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ ++/* { dg-final { scan-assembler "sminv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ ++BUILD_VARIANTS (uint16, u16, 4, 8) ++/* { dg-final { scan-assembler "umaxv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ ++/* { dg-final { scan-assembler "uminv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ ++/* { dg-final { scan-assembler "umaxv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ ++/* { dg-final { scan-assembler "uminv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ ++BUILD_VARIANTS (int32, s32, 2, 4) ++/* { dg-final { scan-assembler "smaxp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "sminp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "smaxv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "sminv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++BUILD_VARIANTS (uint32, u32, 2, 4) ++/* { dg-final { scan-assembler "umaxp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "uminp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "umaxv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "uminv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ + -+poly128_t -+foo (void) -+{ -+ poly64_t a = 0xdeadbeef; -+ poly64_t b = 0xadadadad; -+ return vmull_p64 (a, b); ++#undef TEST ++#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES) \ ++{ \ ++ if (!test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t ()) \ ++ abort (); \ +} + -+/* { dg-final { scan-assembler "vmull.p64.*" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/lp1243022.c -+++ b/src/gcc/testsuite/gcc.target/arm/lp1243022.c -@@ -0,0 +1,201 @@ -+/* { dg-do compile { target arm_thumb2 } } */ -+/* { dg-options "-O2 -fdump-rtl-subreg2" } */ -+ -+/* { dg-final { scan-rtl-dump "REG_INC" "subreg2" { target { ! arm_neon } } } } */ -+/* { dg-final { cleanup-rtl-dump "subreg2" } } */ -+struct device; -+typedef unsigned int __u32; -+typedef unsigned long long u64; -+typedef __u32 __le32; -+typedef u64 dma_addr_t; -+typedef unsigned gfp_t; -+int dev_warn (const struct device *dev, const char *fmt, ...); -+struct usb_bus -+{ -+ struct device *controller; -+}; -+struct usb_hcd -+{ -+ struct usb_bus self; -+}; -+struct xhci_generic_trb -+{ -+ __le32 field[4]; -+}; -+union xhci_trb -+{ -+ struct xhci_generic_trb generic; -+}; -+struct xhci_segment -+{ -+ union xhci_trb *trbs; -+ dma_addr_t dma; -+}; -+struct xhci_ring -+{ -+ struct xhci_segment *first_seg; -+}; -+struct xhci_hcd -+{ -+ struct xhci_ring *cmd_ring; -+ struct xhci_ring *event_ring; -+}; -+struct usb_hcd *xhci_to_hcd (struct xhci_hcd *xhci) -+{ -+} -+dma_addr_t xhci_trb_virt_to_dma (struct xhci_segment * seg, -+ union xhci_trb * trb); -+struct xhci_segment *trb_in_td (struct xhci_segment *start_seg, -+ dma_addr_t suspect_dma); -+xhci_test_trb_in_td (struct xhci_hcd *xhci, struct xhci_segment *input_seg, -+ union xhci_trb *start_trb, union xhci_trb *end_trb, -+ dma_addr_t input_dma, struct xhci_segment *result_seg, -+ char *test_name, int test_number) -+{ -+ unsigned long long start_dma; -+ unsigned long long end_dma; -+ struct xhci_segment *seg; -+ start_dma = xhci_trb_virt_to_dma (input_seg, start_trb); -+ end_dma = xhci_trb_virt_to_dma (input_seg, end_trb); -+ { -+ dev_warn (xhci_to_hcd (xhci)->self.controller, -+ "%d\n", test_number); -+ dev_warn (xhci_to_hcd (xhci)->self.controller, -+ "Expected seg %p, got seg %p\n", result_seg, seg); -+ } -+} -+xhci_check_trb_in_td_math (struct xhci_hcd *xhci, gfp_t mem_flags) ++int ++main (int argc, char **argv) +{ -+ struct -+ { -+ dma_addr_t input_dma; -+ struct xhci_segment *result_seg; -+ } -+ simple_test_vector[] = -+ { -+ { -+ 0, ((void *) 0) -+ } -+ , -+ { -+ xhci->event_ring->first_seg->dma - 16, ((void *) 0)} -+ , -+ { -+ xhci->event_ring->first_seg->dma - 1, ((void *) 0)} -+ , -+ { -+ xhci->event_ring->first_seg->dma, xhci->event_ring->first_seg} -+ , -+ { -+ xhci->event_ring->first_seg->dma + (64 - 1) * 16, -+ xhci->event_ring->first_seg -+ } -+ , -+ { -+ xhci->event_ring->first_seg->dma + (64 - 1) * 16 + 1, ((void *) 0)} -+ , -+ { -+ xhci->event_ring->first_seg->dma + (64) * 16, ((void *) 0)} -+ , -+ { -+ (dma_addr_t) (~0), ((void *) 0) -+ } -+ }; -+ struct -+ { -+ struct xhci_segment *input_seg; -+ union xhci_trb *start_trb; -+ union xhci_trb *end_trb; -+ dma_addr_t input_dma; -+ struct xhci_segment *result_seg; -+ } -+ complex_test_vector[] = -+ { -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ xhci->event_ring->first_seg->trbs,.end_trb = -+ &xhci->event_ring->first_seg->trbs[64 - 1],.input_dma = -+ xhci->cmd_ring->first_seg->dma,.result_seg = ((void *) 0), -+ } -+ , -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ xhci->event_ring->first_seg->trbs,.end_trb = -+ &xhci->cmd_ring->first_seg->trbs[64 - 1],.input_dma = -+ xhci->cmd_ring->first_seg->dma,.result_seg = ((void *) 0), -+ } -+ , -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ xhci->cmd_ring->first_seg->trbs,.end_trb = -+ &xhci->cmd_ring->first_seg->trbs[64 - 1],.input_dma = -+ xhci->cmd_ring->first_seg->dma,.result_seg = ((void *) 0), -+ } -+ , -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ &xhci->event_ring->first_seg->trbs[0],.end_trb = -+ &xhci->event_ring->first_seg->trbs[3],.input_dma = -+ xhci->event_ring->first_seg->dma + 4 * 16,.result_seg = ((void *) 0), -+ } -+ , -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ &xhci->event_ring->first_seg->trbs[3],.end_trb = -+ &xhci->event_ring->first_seg->trbs[6],.input_dma = -+ xhci->event_ring->first_seg->dma + 2 * 16,.result_seg = ((void *) 0), -+ } -+ , -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ &xhci->event_ring->first_seg->trbs[64 - 3],.end_trb = -+ &xhci->event_ring->first_seg->trbs[1],.input_dma = -+ xhci->event_ring->first_seg->dma + 2 * 16,.result_seg = ((void *) 0), -+ } -+ , -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ &xhci->event_ring->first_seg->trbs[64 - 3],.end_trb = -+ &xhci->event_ring->first_seg->trbs[1],.input_dma = -+ xhci->event_ring->first_seg->dma + (64 - 4) * 16,.result_seg = -+ ((void *) 0), -+ } -+ , -+ { -+ .input_seg = xhci->event_ring->first_seg,.start_trb = -+ &xhci->event_ring->first_seg->trbs[64 - 3],.end_trb = -+ &xhci->event_ring->first_seg->trbs[1],.input_dma = -+ xhci->cmd_ring->first_seg->dma + 2 * 16,.result_seg = ((void *) 0), -+ } -+ }; -+ unsigned int num_tests; -+ int i, ret; -+ num_tests = -+ (sizeof (simple_test_vector) / sizeof ((simple_test_vector)[0]) + -+ (sizeof (struct -+ { -+ } -+ ))); -+ for (i = 0; i < num_tests; i++) -+ { -+ ret = -+ xhci_test_trb_in_td (xhci, xhci->event_ring->first_seg, -+ xhci->event_ring->first_seg->trbs, -+ &xhci->event_ring->first_seg->trbs[64 - 1], -+ simple_test_vector[i].input_dma, -+ simple_test_vector[i].result_seg, "Simple", i); -+ if (ret < 0) -+ return ret; -+ } -+ for (i = 0; i < num_tests; i++) -+ { -+ ret = -+ xhci_test_trb_in_td (xhci, complex_test_vector[i].input_seg, -+ complex_test_vector[i].start_trb, -+ complex_test_vector[i].end_trb, -+ complex_test_vector[i].input_dma, -+ complex_test_vector[i].result_seg, "Complex", i); -+ if (ret < 0) -+ return ret; -+ } ++ BUILD_VARIANTS (int8, s8, 8, 16) ++ BUILD_VARIANTS (uint8, u8, 8, 16) ++ BUILD_VARIANTS (int16, s16, 4, 8) ++ BUILD_VARIANTS (uint16, u16, 4, 8) ++ BUILD_VARIANTS (int32, s32, 2, 4) ++ BUILD_VARIANTS (uint32, u32, 2, 4) ++ return 0; +} ---- a/src/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ + -+#include "../aarch64/atomic-comp-swap-release-acquire.x" ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vrecpx.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vrecpx.c +@@ -0,0 +1,54 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps" } */ + -+/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 4 } } */ -+/* { dg-final { scan-assembler-times "stlex" 4 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/pr19599.c -+++ b/src/gcc/testsuite/gcc.target/arm/pr19599.c -@@ -0,0 +1,10 @@ -+/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" "-mthumb" } { "" } } */ -+/* { dg-options "-O2 -march=armv5te -marm" } */ -+/* { dg-final { scan-assembler "bx" } } */ ++#include ++#include ++#include + -+int (*indirect_func)(); ++float32_t in_f[] = ++{2.0, 4.0, 8.0, 16.0, 1.0, 0.5, 0.25, 0.125}; ++float32_t rec_f[] = ++{1.0, 0.5, 0.25, 0.125, 2.0, 4.0, 8.0, 16.0}; ++float64_t in_d[] = ++{2.0, 4.0, 8.0, 16.0, 1.0, 0.5, 0.25, 0.125}; ++float32_t rec_d[] = ++{1.0, 0.5, 0.25, 0.125, 2.0, 4.0, 8.0, 16.0}; + -+int indirect_call() ++int ++test_frecpx_float32_t (void) +{ -+ return indirect_func(); ++ int i = 0; ++ int ret = 1; ++ for (i = 0; i < 8; i++) ++ ret &= fabs (vrecpxs_f32 (in_f[i]) - rec_f[i]) < 0.001; ++ ++ return ret; +} ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vstrq_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vstrq_p128.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "frecpx\\ts\[0-9\]+, s\[0-9\]+" } } */ + -+void -+foo (poly128_t* ptr, poly128_t val) ++int ++test_frecpx_float64_t (void) +{ -+ vstrq_p128 (ptr, val); -+} -+ -+/* { dg-final { scan-assembler "vst1.64\t{d\[0-9\]+-d\[0-9\]+}.*" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++ int i = 0; ++ int ret = 1; ++ for (i = 0; i < 8; i++) ++ ret &= fabs (vrecpxd_f64 (in_d[i]) - rec_d[i]) < 0.001; + -+#include "../aarch64/atomic-op-seq_cst.x" ++ return ret; ++} + -+/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "stlex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselgedf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselgedf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++/* { dg-final { scan-assembler "frecpx\\td\[0-9\]+, d\[0-9\]+" } } */ + -+double -+foo (double x, double y) ++int ++main (int argc, char **argv) +{ -+ volatile int i = 0; -+ return i >= 0 ? x : y; ++ if (!test_frecpx_float32_t ()) ++ abort (); ++ if (!test_frecpx_float64_t ()) ++ abort (); ++ ++ return 0; +} + -+/* { dg-final { scan-assembler-times "vselge.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-consume.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-consume.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-vca.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vca.c +@@ -0,0 +1,89 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps" } */ + -+#include "../aarch64/atomic-op-consume.x" ++#include + -+/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-char.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-char.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++extern void abort (void); ++extern float fabsf (float); ++extern double fabs (double); + -+#include "../aarch64/atomic-op-char.x" ++#define NUM_TESTS 8 + -+/* { dg-final { scan-assembler-times "ldrexb\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "strexb\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/thumb-ltu.c -+++ b/src/gcc/testsuite/gcc.target/arm/thumb-ltu.c -@@ -1,5 +1,5 @@ - /* { dg-do compile } */ --/* { dg-skip-if "incompatible options" { arm*-*-* } { "-march=*" } { "-march=armv6" "-march=armv6j" "-march=armv6z" } } */ -+/* { dg-require-effective-target arm_thumb1_ok } */ - /* { dg-options "-mcpu=arm1136jf-s -mthumb -O2" } */ - - void f(unsigned a, unsigned b, unsigned c, unsigned d) ---- a/src/gcc/testsuite/gcc.target/arm/vselnesf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselnesf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++float input_s1[] = {0.1f, -0.1f, 0.4f, 10.3f, 200.0f, -800.0f, -13.0f, -0.5f}; ++float input_s2[] = {-0.2f, 0.4f, 0.04f, -100.3f, 2.0f, -80.0f, 13.0f, -0.5f}; ++double input_d1[] = {0.1, -0.1, 0.4, 10.3, 200.0, -800.0, -13.0, -0.5}; ++double input_d2[] = {-0.2, 0.4, 0.04, -100.3, 2.0, -80.0, 13.0, -0.5}; + -+float -+foo (float x, float y) -+{ -+ volatile int i = 0; -+ return i != 0 ? x : y; ++#define TEST(T, CMP, SUFFIX, WIDTH, LANES, Q, F) \ ++int \ ++test_vca##T##_float##WIDTH##x##LANES##_t (void) \ ++{ \ ++ int ret = 0; \ ++ int i = 0; \ ++ uint##WIDTH##_t output[NUM_TESTS]; \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ { \ ++ float##WIDTH##_t f1 = fabs##F (input_##SUFFIX##1[i]); \ ++ float##WIDTH##_t f2 = fabs##F (input_##SUFFIX##2[i]); \ ++ /* Inhibit optimization of our linear test loop. */ \ ++ asm volatile ("" : : : "memory"); \ ++ output[i] = f1 CMP f2 ? -1 : 0; \ ++ } \ ++ \ ++ for (i = 0; i < NUM_TESTS; i += LANES) \ ++ { \ ++ float##WIDTH##x##LANES##_t in1 = \ ++ vld1##Q##_f##WIDTH (input_##SUFFIX##1 + i); \ ++ float##WIDTH##x##LANES##_t in2 = \ ++ vld1##Q##_f##WIDTH (input_##SUFFIX##2 + i); \ ++ uint##WIDTH##x##LANES##_t expected_out = \ ++ vld1##Q##_u##WIDTH (output + i); \ ++ uint##WIDTH##x##LANES##_t out = \ ++ veor##Q##_u##WIDTH (vca##T##Q##_f##WIDTH (in1, in2), \ ++ expected_out); \ ++ vst1##Q##_u##WIDTH (output + i, out); \ ++ } \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ ret |= output[i]; \ ++ \ ++ return ret; \ +} + -+/* { dg-final { scan-assembler-times "vseleq.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vaesmcq_u8.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vaesmcq_u8.c -@@ -0,0 +1,20 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++#define BUILD_VARIANTS(T, CMP) \ ++TEST (T, CMP, s, 32, 2, , f) \ ++TEST (T, CMP, s, 32, 4, q, f) \ ++TEST (T, CMP, d, 64, 2, q, ) + -+int -+foo (void) -+{ -+ uint8x16_t a, b; -+ int i = 0; ++BUILD_VARIANTS (ge, >=) ++/* { dg-final { scan-assembler "facge\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "facge\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "facge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ + -+ for (i = 0; i < 16; ++i) -+ a[i] = i; ++BUILD_VARIANTS (gt, >) ++/* { dg-final { scan-assembler "facgt\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "facgt\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "facgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ + -+ b = vaesmcq_u8 (a); -+ return b[0]; -+} ++/* No need for another scan-assembler as these tests ++ also generate facge, facgt instructions. */ ++BUILD_VARIANTS (le, <=) ++BUILD_VARIANTS (lt, <) + -+/* { dg-final { scan-assembler "aesmc.8\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselvcsf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselvcsf.c -@@ -0,0 +1,12 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++#undef TEST ++#define TEST(T, CMP, SUFFIX, WIDTH, LANES, Q, F) \ ++if (test_vca##T##_float##WIDTH##x##LANES##_t ()) \ ++ abort (); + -+float -+foo (float x, float y) ++int ++main (int argc, char **argv) +{ -+ return !__builtin_isunordered (x, y) ? x : y; ++BUILD_VARIANTS (ge, >=) ++BUILD_VARIANTS (gt, >) ++BUILD_VARIANTS (le, <=) ++BUILD_VARIANTS (lt, <) ++ return 0; +} + -+/* { dg-final { scan-assembler-times "vselvs.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha256hq_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha256hq_u32.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-vrnd.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vrnd.c +@@ -0,0 +1,117 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps" } */ + -+#include "arm_neon.h" ++#include + -+int -+foo (void) -+{ -+ uint32x4_t a = {0xd, 0xe, 0xa, 0xd}; -+ uint32x4_t b = {0, 1, 2, 3}; -+ uint32x4_t c = {3, 2, 1, 0}; ++extern void abort (void); ++extern float fabsf (float); ++extern double fabs (double); + -+ uint32x4_t res = vsha256hq_u32 (a, b, c); -+ return res[0]; -+} ++extern double trunc (double); ++extern double round (double); ++extern double nearbyint (double); ++extern double floor (double); ++extern double ceil (double); ++extern double rint (double); + -+/* { dg-final { scan-assembler "sha256h.32\tq\[0-9\]+, q\[0-9\]+, q\[0-9\]" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/minmax_minus.c -+++ b/src/gcc/testsuite/gcc.target/arm/minmax_minus.c -@@ -0,0 +1,12 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_cond_exec } */ -+/* { dg-options "-O2" } */ ++extern float truncf (float); ++extern float roundf (float); ++extern float nearbyintf (float); ++extern float floorf (float); ++extern float ceilf (float); ++extern float rintf (float); + -+#define MAX(a, b) (a > b ? a : b) -+int -+foo (int a, int b, int c) -+{ -+ return c - MAX (a, b); -+} ++#define NUM_TESTS 8 ++#define DELTA 0.000001 + -+/* { dg-final { scan-assembler-not "mov" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-release.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-release.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++float input_f32[] = {0.1f, -0.1f, 0.4f, 10.3f, ++ 200.0f, -800.0f, -13.0f, -0.5f}; ++double input_f64[] = {0.1, -0.1, 0.4, 10.3, ++ 200.0, -800.0, -13.0, -0.5}; + -+#include "../aarch64/atomic-op-release.x" ++#define TEST(SUFFIX, Q, WIDTH, LANES, C_FN, F) \ ++int \ ++test_vrnd##SUFFIX##_float##WIDTH##x##LANES##_t (void) \ ++{ \ ++ int ret = 1; \ ++ int i = 0; \ ++ int nlanes = LANES; \ ++ float##WIDTH##_t expected_out[NUM_TESTS]; \ ++ float##WIDTH##_t actual_out[NUM_TESTS]; \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ { \ ++ expected_out[i] = C_FN##F (input_f##WIDTH[i]); \ ++ /* Don't vectorize this. */ \ ++ asm volatile ("" : : : "memory"); \ ++ } \ ++ \ ++ /* Prevent the compiler from noticing these two loops do the same \ ++ thing and optimizing away the comparison. */ \ ++ asm volatile ("" : : : "memory"); \ ++ \ ++ for (i = 0; i < NUM_TESTS; i+=nlanes) \ ++ { \ ++ float##WIDTH##x##LANES##_t out = \ ++ vrnd##SUFFIX##Q##_f##WIDTH \ ++ (vld1##Q##_f##WIDTH (input_f##WIDTH + i)); \ ++ vst1##Q##_f##WIDTH (actual_out + i, out); \ ++ } \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ ret &= fabs##F (expected_out[i] - actual_out[i]) < DELTA; \ ++ \ ++ return ret; \ ++} \ + -+/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "stlex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselvssf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselvssf.c -@@ -0,0 +1,12 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ + -+float -+foo (float x, float y) -+{ -+ return __builtin_isunordered (x, y) ? x : y; -+} ++#define BUILD_VARIANTS(SUFFIX, C_FN) \ ++TEST (SUFFIX, , 32, 2, C_FN, f) \ ++TEST (SUFFIX, q, 32, 4, C_FN, f) \ ++TEST (SUFFIX, q, 64, 2, C_FN, ) \ + -+/* { dg-final { scan-assembler-times "vselvs.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++BUILD_VARIANTS ( , trunc) ++/* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (a, round) ++/* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (i, nearbyint) ++/* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (m, floor) ++/* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (p, ceil) ++/* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (x, rint) ++/* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ + -+#include "arm_neon.h" ++#undef TEST ++#define TEST(SUFFIX, Q, WIDTH, LANES, C_FN, F) \ ++{ \ ++ if (!test_vrnd##SUFFIX##_float##WIDTH##x##LANES##_t ()) \ ++ abort (); \ ++} + +int -+foo (void) ++main (int argc, char **argv) +{ -+ uint32_t hash = 0xdeadbeef; -+ uint32x4_t a = {0, 1, 2, 3}; -+ uint32x4_t b = {3, 2, 1, 0}; -+ -+ uint32x4_t res = vsha1cq_u32 (a, hash, b); -+ return res[0]; ++ BUILD_VARIANTS ( , trunc) ++ BUILD_VARIANTS (a, round) ++ BUILD_VARIANTS (i, nearbyint) ++ BUILD_VARIANTS (m, floor) ++ BUILD_VARIANTS (p, ceil) ++ BUILD_VARIANTS (x, rint) ++ return 0; +} + -+/* { dg-final { scan-assembler "sha1c.32\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vaeseq_u8.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vaeseq_u8.c -@@ -0,0 +1,22 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.c +@@ -1,43 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ + +-int v = 0; ++#include "atomic-op-relaxed.x" + +-int +-atomic_fetch_add_RELAXED (int a) +-{ +- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_sub_RELAXED (int a) +-{ +- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_and_RELAXED (int a) +-{ +- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_nand_RELAXED (int a) +-{ +- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_xor_RELAXED (int a) +-{ +- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_or_RELAXED (int a) +-{ +- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); +-} +- + /* { dg-final { scan-assembler-times "ldxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ + /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm.x +@@ -13,6 +13,8 @@ + 2.0, -4.0, 8.0, -16.0, + -2.125, 4.25, -8.5, 17.0}; + ++/* Float comparisons, float results. */ + -+#include "arm_neon.h" + void + foo (FTYPE *in1, FTYPE *in2, FTYPE *output) + { +@@ -49,11 +51,52 @@ + output[i] = (in1[i] INV_OP 0.0) ? 4.0 : 2.0; + } + ++/* Float comparisons, int results. */ + -+int -+foo (void) ++void ++foo_int (FTYPE *in1, FTYPE *in2, ITYPE *output) +{ -+ uint8x16_t a, b, c; + int i = 0; -+ -+ for (i = 0; i < 16; ++i) -+ { -+ a[i] = i; -+ b[i] = 15 - i; -+ } -+ c = vaeseq_u8 (a, b); -+ return c[0]; ++ /* Vectorizable. */ ++ for (i = 0; i < N; i++) ++ output[i] = (in1[i] OP in2[i]) ? 2 : 4; +} + -+/* { dg-final { scan-assembler "aese.8\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vect-rounding-roundf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vect-rounding-roundf.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_neon_ok } */ -+/* { dg-options "-O2 -ffast-math -ftree-vectorize" } */ -+/* { dg-add-options arm_v8_neon } */ ++void ++bar_int (FTYPE *in1, FTYPE *in2, ITYPE *output) ++{ ++ int i = 0; ++ /* Vectorizable. */ ++ for (i = 0; i < N; i++) ++ output[i] = (in1[i] INV_OP in2[i]) ? 4 : 2; ++} + -+#define N 32 ++void ++foobar_int (FTYPE *in1, FTYPE *in2, ITYPE *output) ++{ ++ int i = 0; ++ /* Vectorizable. */ ++ for (i = 0; i < N; i++) ++ output[i] = (in1[i] OP 0.0) ? 4 : 2; ++} + +void -+foo (float *output, float *input) ++foobarbar_int (FTYPE *in1, FTYPE *in2, ITYPE *output) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) -+ output[i] = __builtin_roundf (input[i]); ++ output[i] = (in1[i] INV_OP 0.0) ? 4 : 2; +} + -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_roundf } } } */ -+/* { dg-final { cleanup-tree-dump "vect" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon-vtst_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon-vtst_p64.c -@@ -0,0 +1,38 @@ -+/* { dg-do run } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-require-effective-target arm_neon_hw } */ -+/* { dg-add-options arm_crypto } */ + int + main (int argc, char **argv) + { + FTYPE out1[N]; + FTYPE out2[N]; ++ ITYPE outi1[N]; ++ ITYPE outi2[N]; + -+#include "arm_neon.h" -+#include + int i = 0; + foo (input1, input2, out1); + bar (input1, input2, out2); +@@ -65,6 +108,17 @@ + for (i = 0; i < N; i++) + if (out1[i] == out2[i]) + abort (); + -+extern void abort (void); ++ foo_int (input1, input2, outi1); ++ bar_int (input1, input2, outi2); ++ for (i = 0; i < N; i++) ++ if (outi1[i] != outi2[i]) ++ abort (); ++ foobar_int (input1, input2, outi1); ++ foobarbar_int (input1, input2, outi2); ++ for (i = 0; i < N; i++) ++ if (outi1[i] == outi2[i]) ++ abort (); + return 0; + } + +--- a/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic-compile.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic-compile.c +@@ -0,0 +1,11 @@ + -+int -+main (void) -+{ -+ uint64_t args[] = { 0x0, 0xdeadbeef, ~0xdeadbeef, 0xffff, -+ ~0xffff, 0xffffffff, ~0xffffffff, ~0x0 }; -+ int i, j; ++/* { dg-do compile } */ ++/* { dg-options "-O3" } */ + -+ for (i = 0; i < sizeof (args) / sizeof (args[0]); ++i) -+ { -+ for (j = 0; j < sizeof (args) / sizeof (args[0]); ++j) -+ { -+ uint64_t a1 = args[i]; -+ uint64_t a2 = args[j]; -+ uint64_t res = vtst_p64 (vreinterpret_p64_u64 (a1), -+ vreinterpret_p64_u64 (a2)); -+ uint64_t exp = (a1 & a2) ? ~0x0 : 0x0; ++#include "arm_neon.h" + -+ if (res != exp) -+ { -+ fprintf (stderr, "vtst_p64 (a1= %lx, a2= %lx)" -+ " returned %lx, expected %lx\n", -+ a1, a2, res, exp); -+ abort (); -+ } -+ } -+ } -+ return 0; -+} ---- a/src/gcc/testsuite/gcc.target/arm/neon-for-64bits-1.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon-for-64bits-1.c -@@ -0,0 +1,54 @@ -+/* Check that Neon is *not* used by default to handle 64-bits scalar -+ operations. */ ++#include "vaddv-intrinsic.x" + ++/* { dg-final { scan-assembler "faddp\\ts\[0-9\]+"} } */ ++/* { dg-final { scan-assembler-times "faddp\\tv\[0-9\]+\.4s" 2} } */ ++/* { dg-final { scan-assembler "faddp\\td\[0-9\]+"} } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/movi_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/movi_1.c +@@ -0,0 +1,13 @@ +/* { dg-do compile } */ -+/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O2" } */ -+/* { dg-add-options arm_neon } */ -+ -+typedef long long i64; -+typedef unsigned long long u64; -+typedef unsigned int u32; -+typedef int i32; + -+/* Unary operators */ -+#define UNARY_OP(name, op) \ -+ void unary_##name(u64 *a, u64 *b) { *a = op (*b + 0x1234567812345678ULL) ; } ++void ++dummy (short* b) ++{ ++ /* { dg-final { scan-assembler "movi\tv\[0-9\]+\.4h, 0x4, lsl 8" } } */ ++ /* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 0x400" } } */ ++ /* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 1024" } } */ ++ register short x asm ("h8") = 1024; ++ asm volatile ("" : : "w" (x)); ++ *b = x; ++} +--- a/src/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c +@@ -0,0 +1,101 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps" } */ + -+/* Binary operators */ -+#define BINARY_OP(name, op) \ -+ void binary_##name(u64 *a, u64 *b, u64 *c) { *a = *b op *c ; } ++#include + -+/* Unsigned shift */ -+#define SHIFT_U(name, op, amount) \ -+ void ushift_##name(u64 *a, u64 *b, int c) { *a = *b op amount; } ++extern void abort (void); + -+/* Signed shift */ -+#define SHIFT_S(name, op, amount) \ -+ void sshift_##name(i64 *a, i64 *b, int c) { *a = *b op amount; } ++#define ETYPE(size) int##size##_t ++#define VTYPE(size, lanes) int##size##x##lanes##_t + -+UNARY_OP(not, ~) ++#define TEST_VABS(q, size, lanes) \ ++static void \ ++test_vabs##q##_##size (ETYPE (size) * res, \ ++ const ETYPE (size) *in1) \ ++{ \ ++ VTYPE (size, lanes) a = vld1##q##_s##size (res); \ ++ VTYPE (size, lanes) b = vld1##q##_s##size (in1); \ ++ a = vabs##q##_s##size (b); \ ++ vst1##q##_s##size (res, a); \ ++} + -+BINARY_OP(add, +) -+BINARY_OP(sub, -) -+BINARY_OP(and, &) -+BINARY_OP(or, |) -+BINARY_OP(xor, ^) ++#define BUILD_VARS(width, n_lanes, n_half_lanes) \ ++TEST_VABS (, width, n_half_lanes) \ ++TEST_VABS (q, width, n_lanes) \ + -+SHIFT_U(right1, >>, 1) -+SHIFT_U(right2, >>, 2) -+SHIFT_U(right5, >>, 5) -+SHIFT_U(rightn, >>, c) ++BUILD_VARS (64, 2, 1) ++BUILD_VARS (32, 4, 2) ++BUILD_VARS (16, 8, 4) ++BUILD_VARS (8, 16, 8) + -+SHIFT_S(right1, >>, 1) -+SHIFT_S(right2, >>, 2) -+SHIFT_S(right5, >>, 5) -+SHIFT_S(rightn, >>, c) ++#define POOL1 {-10} ++#define POOL2 {2, -10} ++#define POOL4 {0, -10, 2, -3} ++#define POOL8 {0, -10, 2, -3, 4, -50, 6, -70} ++#define POOL16 {0, -10, 2, -3, 4, -50, 6, -70, \ ++ -5, 10, -2, 3, -4, 50, -6, 70} + -+/* { dg-final {scan-assembler-times "vmvn" 0} } */ -+/* { dg-final {scan-assembler-times "vadd" 0} } */ -+/* { dg-final {scan-assembler-times "vsub" 0} } */ -+/* { dg-final {scan-assembler-times "vand" 0} } */ -+/* { dg-final {scan-assembler-times "vorr" 0} } */ -+/* { dg-final {scan-assembler-times "veor" 0} } */ -+/* { dg-final {scan-assembler-times "vshr" 0} } */ ---- a/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-2.c -+++ b/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-2.c -@@ -4,7 +4,7 @@ - - #include - --char dest[16]; -+char dest[16] = { 0 }; - - void aligned_dest (char *src) - { -@@ -14,7 +14,10 @@ - /* Expect a multi-word store for the main part of the copy, but subword - loads/stores for the remainder. */ - --/* { dg-final { scan-assembler-times "stmia" 1 } } */ -+/* { dg-final { scan-assembler-times "ldmia" 0 } } */ -+/* { dg-final { scan-assembler-times "ldrd" 0 } } */ -+/* { dg-final { scan-assembler-times "stmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ -+/* { dg-final { scan-assembler-times "strd" 1 { target { arm_prefer_ldrd_strd } } } } */ - /* { dg-final { scan-assembler-times "ldrh" 1 } } */ - /* { dg-final { scan-assembler-times "strh" 1 } } */ - /* { dg-final { scan-assembler-times "ldrb" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c -@@ -0,0 +1,14 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++#define EXPECTED1 {10} ++#define EXPECTED2 {2, 10} ++#define EXPECTED4 {0, 10, 2, 3} ++#define EXPECTED8 {0, 10, 2, 3, 4, 50, 6, 70} ++#define EXPECTED16 {0, 10, 2, 3, 4, 50, 6, 70, \ ++ 5, 10, 2, 3, 4, 50, 6, 70} + -+int -+foo (void) -+{ -+ uint32_t val = 0xdeadbeef; -+ return vsha1h_u32 (val); ++#define BUILD_TEST(size, lanes_64, lanes_128) \ ++static void \ ++test_##size (void) \ ++{ \ ++ int i; \ ++ ETYPE (size) pool1[lanes_64] = POOL##lanes_64; \ ++ ETYPE (size) res1[lanes_64] = {0}; \ ++ ETYPE (size) expected1[lanes_64] = EXPECTED##lanes_64; \ ++ ETYPE (size) pool2[lanes_128] = POOL##lanes_128; \ ++ ETYPE (size) res2[lanes_128] = {0}; \ ++ ETYPE (size) expected2[lanes_128] = EXPECTED##lanes_128; \ ++ \ ++ /* Forcefully avoid optimization. */ \ ++ asm volatile ("" : : : "memory"); \ ++ test_vabs_##size (res1, pool1); \ ++ for (i = 0; i < lanes_64; i++) \ ++ if (res1[i] != expected1[i]) \ ++ abort (); \ ++ \ ++ /* Forcefully avoid optimization. */ \ ++ asm volatile ("" : : : "memory"); \ ++ test_vabsq_##size (res2, pool2); \ ++ for (i = 0; i < lanes_128; i++) \ ++ if (res2[i] != expected2[i]) \ ++ abort (); \ +} + -+/* { dg-final { scan-assembler "sha1h.32\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/xordi3-opt.c -+++ b/src/gcc/testsuite/gcc.target/arm/xordi3-opt.c -@@ -0,0 +1,9 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O1" } */ ++/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.8b, v\[0-9\]+\.8b" 1 } } */ ++/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */ ++BUILD_TEST (8 , 8, 16) + -+unsigned long long xor64 (unsigned long long input) -+{ -+ return input ^ 0x200000004ULL; -+} ++/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.4h, v\[0-9\]+\.4h" 1 } } */ ++/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h" 1 } } */ ++BUILD_TEST (16, 4, 8) + -+/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha256su1q_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha256su1q_u32.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" 1 } } */ ++/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" 1 } } */ ++BUILD_TEST (32, 2, 4) + -+#include "arm_neon.h" ++/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" 1 } } */ ++BUILD_TEST (64, 1, 2) ++ ++#undef BUILD_TEST ++ ++#define BUILD_TEST(size) test_##size () + +int -+foo (void) ++main (int argc, char **argv) +{ -+ uint32x4_t a = {0xd, 0xe, 0xa, 0xd}; -+ uint32x4_t b = {0, 1, 2, 3}; -+ uint32x4_t c = {3, 2, 1, 0}; -+ -+ uint32x4_t res = vsha256su1q_u32 (a, b, c); -+ return res[0]; ++ BUILD_TEST (8); ++ BUILD_TEST (16); ++ BUILD_TEST (32); ++ BUILD_TEST (64); ++ return 0; +} + -+/* { dg-final { scan-assembler "sha256su1.32\tq\[0-9\]+, q\[0-9\]+, q\[0-9\]" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.x +@@ -0,0 +1,37 @@ ++int v = 0; + -+#include "../aarch64/atomic-op-acq_rel.x" ++int ++atomic_fetch_add_RELAXED (int a) ++{ ++ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); ++} + -+/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "stlex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselltsf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselltsf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++int ++atomic_fetch_sub_RELAXED (int a) ++{ ++ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); ++} + -+float -+foo (float x, float y) ++int ++atomic_fetch_and_RELAXED (int a) +{ -+ volatile int i = 0; -+ return i < 0 ? x : y; ++ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +} + -+/* { dg-final { scan-assembler-times "vselge.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselnedf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselnedf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++int ++atomic_fetch_nand_RELAXED (int a) ++{ ++ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); ++} + -+double -+foo (double x, double y) ++int ++atomic_fetch_xor_RELAXED (int a) +{ -+ volatile int i = 0; -+ return i != 0 ? x : y; ++ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +} + -+/* { dg-final { scan-assembler-times "vseleq.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselvcdf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselvcdf.c -@@ -0,0 +1,12 @@ ++int ++atomic_fetch_or_RELAXED (int a) ++{ ++ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); ++} +--- a/src/gcc/testsuite/gcc.target/aarch64/vect.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect.c +@@ -55,6 +55,8 @@ + int smin_vector[] = {0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}; + unsigned int umax_vector[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + unsigned int umin_vector[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; ++ int sabd_vector[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ++ int saba_vector[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int reduce_smax_value = 0; + int reduce_smin_value = -15; + unsigned int reduce_umax_value = 15; +@@ -81,6 +83,8 @@ + TEST (smin, s); + TEST (umax, u); + TEST (umin, u); ++ TEST (sabd, s); ++ TEST (saba, s); + TESTV (reduce_smax, s); + TESTV (reduce_smin, s); + TESTV (reduce_umax, u); +--- a/src/gcc/testsuite/gcc.target/aarch64/scalar-mov.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/scalar-mov.c +@@ -0,0 +1,9 @@ +/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++/* { dg-options "-g -mgeneral-regs-only" } */ + -+double -+foo (double x, double y) ++void ++foo (const char *c, ...) +{ -+ return !__builtin_isunordered (x, y) ? x : y; ++ char buf[256]; ++ buf[256 - 1] = '\0'; +} +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-movi.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-movi.c +@@ -0,0 +1,74 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps -fno-inline" } */ + -+/* { dg-final { scan-assembler-times "vselvs.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vect-rounding-btruncf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vect-rounding-btruncf.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_neon_ok } */ -+/* { dg-options "-O2 -ffast-math -ftree-vectorize" } */ -+/* { dg-add-options arm_v8_neon } */ ++extern void abort (void); + -+#define N 32 ++#define N 16 + -+void -+foo (float *output, float *input) ++static void ++movi_msl8 (int *__restrict a) +{ -+ int i = 0; -+ /* Vectorizable. */ ++ int i; ++ ++ /* { dg-final { scan-assembler "movi\\tv\[0-9\]+\.4s, 0xab, msl 8" } } */ + for (i = 0; i < N; i++) -+ output[i] = __builtin_truncf (input[i]); ++ a[i] = 0xabff; +} + -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_btruncf } } } */ -+/* { dg-final { cleanup-tree-dump "vect" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vseleqsf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vseleqsf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++static void ++movi_msl16 (int *__restrict a) ++{ ++ int i; + -+float -+foo (float x, float y) ++ /* { dg-final { scan-assembler "movi\\tv\[0-9\]+\.4s, 0xab, msl 16" } } */ ++ for (i = 0; i < N; i++) ++ a[i] = 0xabffff; ++} ++ ++static void ++mvni_msl8 (int *__restrict a) +{ -+ volatile int i = 0; -+ return i == 0 ? x : y; ++ int i; ++ ++ /* { dg-final { scan-assembler "mvni\\tv\[0-9\]+\.4s, 0xab, msl 8" } } */ ++ for (i = 0; i < N; i++) ++ a[i] = 0xffff5400; +} + -+/* { dg-final { scan-assembler-times "vseleq.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c -+++ b/src/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c -@@ -0,0 +1,19 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */ -+/* { dg-skip-if "" { arm_thumb1 } } */ ++static void ++mvni_msl16 (int *__restrict a) ++{ ++ int i; + -+extern char *__ctype_ptr__; ++ /* { dg-final { scan-assembler "mvni\\tv\[0-9\]+\.4s, 0xab, msl 16" } } */ ++ for (i = 0; i < N; i++) ++ a[i] = 0xff540000; ++} + -+unsigned char * foo(unsigned char *ReadPtr) ++int ++main (void) +{ ++ int a[N] = { 0 }; ++ int i; + -+ unsigned char c; ++#define CHECK_ARRAY(a, val) \ ++ for (i = 0; i < N; i++) \ ++ if (a[i] != val) \ ++ abort (); + -+ while (!(((__ctype_ptr__+sizeof(""[*ReadPtr]))[(int)(*ReadPtr)])&04) == (!(0))) -+ ReadPtr++; ++ movi_msl8 (a); ++ CHECK_ARRAY (a, 0xabff); + -+ return ReadPtr; -+} ++ movi_msl16 (a); ++ CHECK_ARRAY (a, 0xabffff); + -+/* { dg-final { scan-tree-dump-times "original biv" 2 "ivopts"} } */ -+/* { dg-final { cleanup-tree-dump "ivopts" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselvsdf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselvsdf.c -@@ -0,0 +1,12 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++ mvni_msl8 (a); ++ CHECK_ARRAY (a, 0xffff5400); + -+double -+foo (double x, double y) -+{ -+ return __builtin_isunordered (x, y) ? x : y; ++ mvni_msl16 (a); ++ CHECK_ARRAY (a, 0xff540000); ++ ++ return 0; +} + -+/* { dg-final { scan-assembler-times "vselvs.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-3.c -+++ b/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-3.c -@@ -4,7 +4,7 @@ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c +@@ -2,12 +2,13 @@ + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ - #include + #define FTYPE double ++#define ITYPE long + #define OP >= + #define INV_OP < --char src[16]; -+char src[16] = {0}; + #include "vect-fcm.x" - void aligned_src (char *dest) - { -@@ -14,8 +14,11 @@ - /* Expect a multi-word load for the main part of the copy, but subword - loads/stores for the remainder. */ +-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ ++/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ + /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ + /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ + /* { dg-final { scan-assembler "fcmlt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.c +@@ -1,43 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ --/* { dg-final { scan-assembler-times "ldmia" 1 } } */ --/* { dg-final { scan-assembler-times "ldrh" 1 } } */ -+/* { dg-final { scan-assembler-times "ldmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ -+/* { dg-final { scan-assembler-times "ldrd" 1 { target { arm_prefer_ldrd_strd } } } } */ -+/* { dg-final { scan-assembler-times "strd" 0 } } */ -+/* { dg-final { scan-assembler-times "stm" 0 } } */ -+/* { dg-final { scan-assembler-times "ldrh" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ - /* { dg-final { scan-assembler-times "strh" 1 } } */ --/* { dg-final { scan-assembler-times "ldrb" 1 } } */ -+/* { dg-final { scan-assembler-times "ldrb" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ - /* { dg-final { scan-assembler-times "strb" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/pr46975-2.c -+++ b/src/gcc/testsuite/gcc.target/arm/pr46975-2.c -@@ -0,0 +1,10 @@ -+/* { dg-options "-mthumb -O2" } */ -+/* { dg-require-effective-target arm_thumb2_ok } */ -+/* { dg-final { scan-assembler "sub" } } */ -+/* { dg-final { scan-assembler "clz" } } */ -+/* { dg-final { scan-assembler "lsr.*#5" } } */ -+ -+int foo (int s) -+{ -+ return s == 1; -+} ---- a/src/gcc/testsuite/gcc.target/arm/neon-vceq_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon-vceq_p64.c -@@ -0,0 +1,38 @@ +-int v = 0; ++#include "atomic-op-acquire.x" + +-int +-atomic_fetch_add_ACQUIRE (int a) +-{ +- return __atomic_fetch_add (&v, a, __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_fetch_sub_ACQUIRE (int a) +-{ +- return __atomic_fetch_sub (&v, a, __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_fetch_and_ACQUIRE (int a) +-{ +- return __atomic_fetch_and (&v, a, __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_fetch_nand_ACQUIRE (int a) +-{ +- return __atomic_fetch_nand (&v, a, __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_fetch_xor_ACQUIRE (int a) +-{ +- return __atomic_fetch_xor (&v, a, __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_fetch_or_ACQUIRE (int a) +-{ +- return __atomic_fetch_or (&v, a, __ATOMIC_ACQUIRE); +-} +- + /* { dg-final { scan-assembler-times "ldaxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ + /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/abs_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/abs_1.c +@@ -0,0 +1,53 @@ +/* { dg-do run } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-require-effective-target arm_neon_hw } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+#include ++/* { dg-options "-O2 -fno-inline --save-temps" } */ + ++extern long long llabs (long long); +extern void abort (void); + -+int -+main (void) ++long long ++abs64 (long long a) +{ -+ uint64_t args[] = { 0x0, 0xdeadbeef, ~0xdeadbeef, 0xffff, -+ ~0xffff, 0xffffffff, ~0xffffffff, ~0x0 }; -+ int i, j; -+ -+ for (i = 0; i < sizeof (args) / sizeof (args[0]); ++i) -+ { -+ for (j = 0; j < sizeof (args) / sizeof (args[0]); ++j) -+ { -+ uint64_t a1 = args[i]; -+ uint64_t a2 = args[j]; -+ uint64_t res = vceq_p64 (vreinterpret_p64_u64 (a1), -+ vreinterpret_p64_u64 (a2)); -+ uint64_t exp = (a1 == a2) ? ~0x0 : 0x0; -+ -+ if (res != exp) -+ { -+ fprintf (stderr, "vceq_p64 (a1= %lx, a2= %lx)" -+ " returned %lx, expected %lx\n", -+ a1, a2, res, exp); -+ abort (); -+ } -+ } -+ } -+ return 0; ++ /* { dg-final { scan-assembler "eor\t" } } */ ++ /* { dg-final { scan-assembler "sub\t" } } */ ++ return llabs (a); +} ---- a/src/gcc/testsuite/gcc.target/arm/anddi3-opt2.c -+++ b/src/gcc/testsuite/gcc.target/arm/anddi3-opt2.c -@@ -0,0 +1,9 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O1" } */ + -+long long muld(long long X, long long Y) ++long long ++abs64_in_dreg (long long a) +{ -+ return X & ~1; ++ /* { dg-final { scan-assembler "abs\td\[0-9\]+, d\[0-9\]+" } } */ ++ register long long x asm ("d8") = a; ++ register long long y asm ("d9"); ++ asm volatile ("" : : "w" (x)); ++ y = llabs (x); ++ asm volatile ("" : : "w" (y)); ++ return y; +} + -+/* { dg-final { scan-assembler-not "and\[\\t \]+.+,\[\\t \]*.+,\[\\t \]*.+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon-vcond-ltgt.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon-vcond-ltgt.c -@@ -15,4 +15,4 @@ - - /* { dg-final { scan-assembler-times "vcgt\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" 2 } } */ - /* { dg-final { scan-assembler "vorr\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ --/* { dg-final { scan-assembler "vbsl\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "vbsl|vbit|vbif\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha256h2q_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha256h2q_u32.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" -+ +int -+foo (void) ++main (void) +{ -+ uint32x4_t a = {0xd, 0xe, 0xa, 0xd}; -+ uint32x4_t b = {0, 1, 2, 3}; -+ uint32x4_t c = {3, 2, 1, 0}; ++ volatile long long ll0 = 0LL, ll1 = 1LL, llm1 = -1LL; + -+ uint32x4_t res = vsha256h2q_u32 (a, b, c); -+ return res[0]; -+} ++ if (abs64 (ll0) != 0LL) ++ abort (); + -+/* { dg-final { scan-assembler "sha256h2.32\tq\[0-9\]+, q\[0-9\]+, q\[0-9\]" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselltdf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselltdf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++ if (abs64 (ll1) != 1LL) ++ abort (); + -+double -+foo (double x, double y) -+{ -+ volatile int i = 0; -+ return i < 0 ? x : y; ++ if (abs64 (llm1) != 1LL) ++ abort (); ++ ++ if (abs64_in_dreg (ll0) != 0LL) ++ abort (); ++ ++ if (abs64_in_dreg (ll1) != 1LL) ++ abort (); ++ ++ if (abs64_in_dreg (llm1) != 1LL) ++ abort (); ++ ++ return 0; +} + -+/* { dg-final { scan-assembler-times "vselge.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-4.c -+++ b/src/gcc/testsuite/gcc.target/arm/unaligned-memcpy-4.c -@@ -4,8 +4,8 @@ - - #include ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.c +@@ -1,41 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ --char src[16]; --char dest[16]; -+char src[16] = { 0 }; -+char dest[16] = { 0 }; +-#define STRONG 0 +-#define WEAK 1 +-int v = 0; ++#include "atomic-comp-swap-release-acquire.x" - void aligned_both (void) - { -@@ -14,5 +14,9 @@ - - /* We know both src and dest to be aligned: expect multiword loads/stores. */ +-int +-atomic_compare_exchange_STRONG_RELEASE_ACQUIRE (int a, int b) +-{ +- return __atomic_compare_exchange (&v, &a, &b, +- STRONG, __ATOMIC_RELEASE, +- __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_compare_exchange_WEAK_RELEASE_ACQUIRE (int a, int b) +-{ +- return __atomic_compare_exchange (&v, &a, &b, +- WEAK, __ATOMIC_RELEASE, +- __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_compare_exchange_n_STRONG_RELEASE_ACQUIRE (int a, int b) +-{ +- return __atomic_compare_exchange_n (&v, &a, b, +- STRONG, __ATOMIC_RELEASE, +- __ATOMIC_ACQUIRE); +-} +- +-int +-atomic_compare_exchange_n_WEAK_RELEASE_ACQUIRE (int a, int b) +-{ +- return __atomic_compare_exchange_n (&v, &a, b, +- WEAK, __ATOMIC_RELEASE, +- __ATOMIC_ACQUIRE); +-} +- + /* { dg-final { scan-assembler-times "ldaxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 4 } } */ + /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 4 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect.x +@@ -138,3 +138,17 @@ --/* { dg-final { scan-assembler-times "ldmia" 1 } } */ --/* { dg-final { scan-assembler-times "stmia" 1 } } */ -+/* { dg-final { scan-assembler-times "ldmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ -+/* { dg-final { scan-assembler-times "stmia" 1 { target { ! { arm_prefer_ldrd_strd } } } } } */ -+/* { dg-final { scan-assembler "ldrd" { target { arm_prefer_ldrd_strd } } } } */ -+/* { dg-final { scan-assembler-times "ldm" 0 { target { arm_prefer_ldrd_strd } } } } */ -+/* { dg-final { scan-assembler "strd" { target { arm_prefer_ldrd_strd } } } } */ -+/* { dg-final { scan-assembler-times "stm" 0 { target { arm_prefer_ldrd_strd } } } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vseleqdf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vseleqdf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ + return s; + } + -+double -+foo (double x, double y) ++void sabd (pRINT a, pRINT b, pRINT c) +{ -+ volatile int i = 0; -+ return i == 0 ? x : y; ++ int i; ++ for (i = 0; i < 16; i++) ++ c[i] = abs (a[i] - b[i]); +} + -+/* { dg-final { scan-assembler-times "vseleq.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ -+ -+#include "../aarch64/atomic-op-acquire.x" -+ -+/* { dg-final { scan-assembler-times "ldaex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vsellesf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vsellesf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ -+ -+float -+foo (float x, float y) ++void saba (pRINT a, pRINT b, pRINT c) +{ -+ volatile int i = 0; -+ return i <= 0 ? x : y; ++ int i; ++ for (i = 0; i < 16; i++) ++ c[i] += abs (a[i] - b[i]); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-clz.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-clz.c +@@ -0,0 +1,35 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 -save-temps -fno-inline" } */ + -+/* { dg-final { scan-assembler-times "vselgt.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/neon-vcond-unordered.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon-vcond-unordered.c -@@ -16,4 +16,4 @@ - /* { dg-final { scan-assembler "vcgt\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ - /* { dg-final { scan-assembler "vcge\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ - /* { dg-final { scan-assembler "vorr\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ --/* { dg-final { scan-assembler "vbsl\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "vbsl|vbit|vbif\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha1su0q_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha1su0q_u32.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++extern void abort (); + -+int -+foo (void) ++void ++count_lz_v4si (unsigned *__restrict a, int *__restrict b) +{ -+ uint32x4_t a = {0xd, 0xe, 0xa, 0xd}; -+ uint32x4_t b = {0, 1, 2, 3}; -+ uint32x4_t c = {3, 2, 1, 0}; ++ int i; + -+ uint32x4_t res = vsha1su0q_u32 (a, b, c); -+ return res[0]; ++ for (i = 0; i < 4; i++) ++ b[i] = __builtin_clz (a[i]); +} + -+/* { dg-final { scan-assembler "sha1su0.32\tq\[0-9\]+, q\[0-9\]+, q\[0-9\]" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vmull_high_p64.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vmull_high_p64.c -@@ -0,0 +1,15 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ -+ -+#include "arm_neon.h" ++/* { dg-final { scan-assembler "clz\tv\[0-9\]+\.4s" } } */ + -+poly128_t -+foo (void) ++int ++main () +{ -+ poly64x2_t a = { 0xdeadbeef, 0xadabcaca }; -+ poly64x2_t b = { 0xdcdcdcdc, 0xbdbdbdbd }; -+ return vmull_high_p64 (a, b); -+} ++ unsigned int x[4] = { 0x0, 0xFFFF, 0x1FFFF, 0xFFFFFFFF }; ++ int r[4] = { 32, 16, 15, 0 }; ++ int d[4], i; + -+/* { dg-final { scan-assembler "vmull.p64.*" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-int.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-int.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++ count_lz_v4si (x, d); + -+#include "../aarch64/atomic-op-int.x" ++ for (i = 0; i < 4; i++) ++ { ++ if (d[i] != r[i]) ++ abort (); ++ } + -+/* { dg-final { scan-assembler-times "ldrex\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "strex\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++ return 0; ++} + -+#include "arm_neon.h" ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c +@@ -2,12 +2,13 @@ + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ + + #define FTYPE float ++#define ITYPE int + #define OP > + #define INV_OP <= + + #include "vect-fcm.x" + +-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ ++/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ + /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */ + /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ + /* { dg-final { scan-assembler "fcmle\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/subs3.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/subs3.c +@@ -0,0 +1,61 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ ++ ++extern void abort (void); ++typedef long long s64; + +int -+foo (void) ++subs_ext (s64 a, int b, int c) +{ -+ uint32_t hash = 0xdeadbeef; -+ uint32x4_t a = {0, 1, 2, 3}; -+ uint32x4_t b = {3, 2, 1, 0}; ++ s64 d = a - b; + -+ uint32x4_t res = vsha1mq_u32 (a, hash, b); -+ return res[0]; ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "sha1m.32\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vldrq_p128.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vldrq_p128.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++int ++subs_shift_ext (s64 a, int b, int c) ++{ ++ s64 d = (a - ((s64)b << 3)); + -+#include "arm_neon.h" ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+poly128_t -+foo (poly128_t* ptr) ++int main () +{ -+ return vldrq_p128 (ptr); -+} ++ int x; ++ s64 y; + -+/* { dg-final { scan-assembler "vld1.64\t{d\[0-9\]+-d\[0-9\]+}.*" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/atomic-op-short.c -+++ b/src/gcc/testsuite/gcc.target/arm/atomic-op-short.c -@@ -0,0 +1,10 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_arch_v8a_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_arch_v8a } */ ++ x = subs_ext (0x13000002ll, 41, 15); ++ if (x != 318767121) ++ abort (); + -+#include "../aarch64/atomic-op-short.x" ++ x = subs_ext (0x50505050ll, 29, 4); ++ if (x != 1347440724) ++ abort (); + -+/* { dg-final { scan-assembler-times "ldrexh\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-times "strexh\t...?, r\[0-9\]+, \\\[r\[0-9\]+\\\]" 6 } } */ -+/* { dg-final { scan-assembler-not "dmb" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/pr40887.c -+++ b/src/gcc/testsuite/gcc.target/arm/pr40887.c -@@ -2,9 +2,9 @@ - /* { dg-options "-O2 -march=armv5te" } */ - /* { dg-final { scan-assembler "blx" } } */ - --int (*indirect_func)(); -+int (*indirect_func)(int x); - - int indirect_call() - { -- return indirect_func(); -+ return indirect_func(20) + indirect_func (40); - } ---- a/src/gcc/testsuite/gcc.target/arm/crypto-vaesimcq_u8.c -+++ b/src/gcc/testsuite/gcc.target/arm/crypto-vaesimcq_u8.c -@@ -0,0 +1,20 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_crypto_ok } */ -+/* { dg-add-options arm_crypto } */ ++ x = subs_ext (0x12121212121ll, 2, 14); ++ if (x != 555819311) ++ abort (); + -+#include "arm_neon.h" ++ x = subs_shift_ext (0x123456789ll, 4, 12); ++ if (x != 591751033) ++ abort (); + -+int -+foo (void) -+{ -+ uint8x16_t a, b; -+ int i = 0; ++ x = subs_shift_ext (0x02020202ll, 9, 8); ++ if (x != 33685963) ++ abort (); + -+ for (i = 0; i < 16; ++i) -+ a[i] = i; ++ x = subs_shift_ext (0x987987987987ll, 23, 41); ++ if (x != -2020050673) ++ abort (); + -+ b = vaesimcq_u8 (a); -+ return b[0]; ++ return 0; +} + -+/* { dg-final { scan-assembler "aesimc.8\tq\[0-9\]+, q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vect-rounding-ceilf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vect-rounding-ceilf.c -@@ -0,0 +1,18 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_neon_ok } */ -+/* { dg-options "-O2 -ffast-math -ftree-vectorize" } */ -+/* { dg-add-options arm_v8_neon } */ ++/* { dg-final { scan-assembler-times "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw" 2 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/bics_2.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/bics_2.c +@@ -0,0 +1,111 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ + -+#define N 32 ++extern void abort (void); + -+void -+foo (float *output, float *input) ++int ++bics_si_test1 (int a, int b, int c) +{ -+ int i = 0; -+ /* Vectorizable. */ -+ for (i = 0; i < N; i++) -+ output[i] = __builtin_ceilf (input[i]); -+} ++ int d = a & ~b; + -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_ceilf } } } */ -+/* { dg-final { cleanup-tree-dump "vect" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselledf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselledf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++ /* { dg-final { scan-assembler-not "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler-times "bic\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+double -+foo (double x, double y) ++int ++bics_si_test2 (int a, int b, int c) +{ -+ volatile int i = 0; -+ return i <= 0 ? x : y; ++ int d = a & ~(b << 3); ++ ++ /* { dg-final { scan-assembler-not "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "bic\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler-times "vselgt.f64\td\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/vselgtsf.c -+++ b/src/gcc/testsuite/gcc.target/arm/vselgtsf.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_v8_vfp_ok } */ -+/* { dg-options "-O2" } */ -+/* { dg-add-options arm_v8_vfp } */ ++typedef long long s64; + -+float -+foo (float x, float y) ++s64 ++bics_di_test1 (s64 a, s64 b, s64 c) +{ -+ volatile int i = 0; -+ return i > 0 ? x : y; ++ s64 d = a & ~b; ++ ++ /* { dg-final { scan-assembler-not "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler-times "bic\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler-times "vselgt.f32\ts\[0-9\]+" 1 } } */ ---- a/src/gcc/testsuite/gcc.target/arm/pr58578.c -+++ b/src/gcc/testsuite/gcc.target/arm/pr58578.c -@@ -0,0 +1,54 @@ ++s64 ++bics_di_test2 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a & ~(b << 3); + -+/* PR target/58578 */ -+/* { dg-do run } */ -+/* { dg-options "-O1" } */ ++ /* { dg-final { scan-assembler-not "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "bic\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d <= 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+#include ++int ++main () ++{ ++ int x; ++ s64 y; + -+typedef struct { -+ long _prec; -+ int _flag; -+ long _exp; -+} __my_st_t; ++ x = bics_si_test1 (29, ~4, 5); ++ if (x != ((29 & 4) + ~4 + 5)) ++ abort (); + -+typedef __my_st_t *__my_st_ptr; ++ x = bics_si_test1 (5, ~2, 20); ++ if (x != 25) ++ abort (); + -+int -+_test_fn (__my_st_ptr y, const __my_st_ptr xt) -+{ -+ int inexact; -+ if (xt->_exp != -2147483647L) -+ { -+ (y->_flag = xt->_flag); -+ } ++ x = bics_si_test2 (35, ~4, 5); ++ if (x != ((35 & ~(~4 << 3)) + ~4 + 5)) ++ abort (); + -+ do { -+ __my_st_ptr _y = y; -+ long _err1 = -2 * xt->_exp; -+ long _err2 = 2; -+ if (0 < _err1) -+ { -+ unsigned long _err = (unsigned long) _err1 + _err2; -+ if (__builtin_expect(!!(_err > _y->_prec + 1), 0)) -+ return 2; -+ return 3; -+ } -+ } while (0); ++ x = bics_si_test2 (96, ~2, 20); ++ if (x != 116) ++ abort (); + -+ return 0; -+} ++ y = bics_di_test1 (0x130000029ll, ++ ~0x320000004ll, ++ 0x505050505ll); + -+int main () -+{ -+ __my_st_t x, y; -+ long pz; -+ int inex; ++ if (y != ((0x130000029ll & 0x320000004ll) + ~0x320000004ll + 0x505050505ll)) ++ abort (); ++ ++ y = bics_di_test1 (0x5000500050005ll, ++ ~0x2111211121112ll, ++ 0x0000000002020ll); ++ if (y != 0x5000500052025ll) ++ abort (); ++ ++ y = bics_di_test2 (0x130000029ll, ++ ~0x064000008ll, ++ 0x505050505ll); ++ if (y != ((0x130000029ll & ~(~0x064000008ll << 3)) ++ + ~0x064000008ll + 0x505050505ll)) ++ abort (); ++ ++ y = bics_di_test2 (0x130002900ll, ++ ~0x088000008ll, ++ 0x505050505ll); ++ if (y != (0x130002900ll + 0x505050505ll)) ++ abort (); + -+ x._prec = 914; -+ y._exp = 18; -+ if (_test_fn (&x, &y)) -+ { -+ abort(); -+ } + return 0; +} ---- a/src/gcc/testsuite/gcc.target/arm/neon-vcond-gt.c -+++ b/src/gcc/testsuite/gcc.target/arm/neon-vcond-gt.c -@@ -14,4 +14,4 @@ - } - - /* { dg-final { scan-assembler "vcgt\\.f32\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ --/* { dg-final { scan-assembler "vbit\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "vbsl|vbit|vbif\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+,\[\\t \]*q\[0-9\]+" } } */ ---- a/src/gcc/testsuite/gcc.target/arm/pr57637.c -+++ b/src/gcc/testsuite/gcc.target/arm/pr57637.c -@@ -0,0 +1,206 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 -fno-inline" } */ + -+typedef struct _GtkCssStyleProperty GtkCssStyleProperty; ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.x +@@ -0,0 +1,37 @@ ++int v = 0; + -+struct _GtkCssStyleProperty ++int ++atomic_fetch_add_ACQUIRE (int a) +{ -+ int *initial_value; -+ unsigned int id; -+ unsigned int inherit :1; -+ unsigned int animated :1; -+ unsigned int affects_size :1; -+ unsigned int affects_font :1; -+ -+ int * parse_value; -+ int * query_value; -+ int * assign_value; -+}; ++ return __atomic_fetch_add (&v, a, __ATOMIC_ACQUIRE); ++} + -+void -+g_assertion_message_expr (const char *domain, -+ const char *file, -+ int line, -+ const char *func, -+ const char *expr) __attribute__((__noreturn__)); ++int ++atomic_fetch_sub_ACQUIRE (int a) ++{ ++ return __atomic_fetch_sub (&v, a, __ATOMIC_ACQUIRE); ++} + -+void -+g_assertion_message_expr (const char *domain, -+ const char *file, -+ int line, -+ const char *func, -+ const char *expr) ++int ++atomic_fetch_and_ACQUIRE (int a) +{ -+ __builtin_abort (); ++ return __atomic_fetch_and (&v, a, __ATOMIC_ACQUIRE); +} ++ +int -+get_id (GtkCssStyleProperty *property) ++atomic_fetch_nand_ACQUIRE (int a) +{ -+ return 1; ++ return __atomic_fetch_nand (&v, a, __ATOMIC_ACQUIRE); +} ++ +int -+_gtk_css_style_property_get_type () ++atomic_fetch_xor_ACQUIRE (int a) +{ -+ return 1; ++ return __atomic_fetch_xor (&v, a, __ATOMIC_ACQUIRE); +} + -+GtkCssStyleProperty * -+g_object_new (int object_type, -+ const char *first_property_name, -+ ...) ++int ++atomic_fetch_or_ACQUIRE (int a) +{ -+ return (GtkCssStyleProperty *) __builtin_malloc (sizeof (GtkCssStyleProperty)); ++ return __atomic_fetch_or (&v, a, __ATOMIC_ACQUIRE); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.c +@@ -0,0 +1,28 @@ + -+typedef enum { -+ INHERIT = (1 << 0), -+ ANIMATED = (1 << 1), -+ RESIZE = (1 << 2), -+ FONT = (1 << 3) -+} GtkStylePropertyFlags; -+ -+int t = 0; -+void -+gtk_css_style_property_register (const char * name, -+ int expected_id, -+ int value_type, -+ int flags, -+ int *parse_value, -+ int *query_value, -+ int *assign_value, -+ int *initial_value) -+{ -+ GtkCssStyleProperty *node; -+ -+ do -+ { -+ if (__builtin_expect (__extension__ ( -+ { -+ int _g_boolean_var_; -+ if (initial_value != ((void *)0)) -+ _g_boolean_var_ = 1; -+ else -+ _g_boolean_var_ = 0; -+ _g_boolean_var_; -+ }), -+ 1)) -+ ; -+ else -+ g_assertion_message_expr ("Gtk", -+ "gtkcssstylepropertyimpl.c", -+ 85, -+ ((const char*) (__PRETTY_FUNCTION__)), -+ "initial_value != NULL"); -+ } while (0); -+ -+ do -+ { -+ if (__builtin_expect (__extension__ ( -+ { -+ int _g_boolean_var_; -+ if (parse_value != ((void *)0)) -+ _g_boolean_var_ = 1; -+ else -+ _g_boolean_var_ = 0; -+ _g_boolean_var_; -+ }), -+ 1)) -+ ; -+ else -+ g_assertion_message_expr ("Gtk", -+ "gtkcssstylepropertyimpl.c", -+ 86, -+ ((const char*) (__PRETTY_FUNCTION__)), -+ "parse_value != NULL"); -+ } while (0); -+ -+ do -+ { -+ if (__builtin_expect (__extension__ ( -+ { -+ int _g_boolean_var_; -+ if (value_type == ((int) ((1) << (2))) -+ || query_value != ((void *)0)) -+ _g_boolean_var_ = 1; -+ else -+ _g_boolean_var_ = 0; -+ _g_boolean_var_; -+ }), -+ 1)) -+ ; -+ else -+ g_assertion_message_expr ("Gtk", -+ "gtkcssstylepropertyimpl.c", -+ 87, ((const char*) (__PRETTY_FUNCTION__)), -+ "value_type == NONE || query_value != NULL"); -+ } while (0); -+ -+ /* FLAGS is changed in a cond_exec instruction with pr57637. */ -+ if (flags == 15) -+ t = 15; -+ -+ do -+ { -+ if (__builtin_expect (__extension__ ( -+ { -+ int _g_boolean_var_; -+ if (value_type == ((1) << (2)) -+ || assign_value != ((void *)0)) -+ _g_boolean_var_ = 1; -+ else -+ _g_boolean_var_ = 0; -+ _g_boolean_var_; -+ }), -+ 1)) -+ ; -+ else -+ g_assertion_message_expr ("Gtk", -+ "gtkcssstylepropertyimpl.c", -+ 88, ((const char*) (__PRETTY_FUNCTION__)), -+ "value_type == NONE || assign_value != NULL"); -+ } while (0); -+ -+ node = g_object_new ((_gtk_css_style_property_get_type ()), -+ "value-type", value_type, -+ "affects-size", (flags & RESIZE) ? (0) : (!(0)), -+ "affects-font", (flags & FONT) ? (!(0)) : (0), -+ "animated", (flags & ANIMATED) ? (!(0)) : (0), -+ "inherit", (flags & INHERIT) ? (!(0)) : (0), -+ "initial-value", initial_value, -+ "name", name, -+ ((void *)0)); -+ -+ node->parse_value = parse_value; -+ node->query_value = query_value; -+ node->assign_value = assign_value; -+ -+ do -+ { -+ if (__builtin_expect (__extension__ ( -+ { -+ int _g_boolean_var_; -+ if (get_id (node) == expected_id) -+ _g_boolean_var_ = 1; -+ else -+ _g_boolean_var_ = 0; -+ _g_boolean_var_; -+ }), -+ 1)) -+ ; -+ else -+ g_assertion_message_expr ("Gtk", -+ "gtkcssstylepropertyimpl.c", -+ 106, -+ ((const char*) (__PRETTY_FUNCTION__)), -+ "get_id (node) == expected_id"); -+ } while (0); -+} -+ -+int main () -+{ -+ gtk_css_style_property_register ("test", 1, 4, 15, &t, &t, &t, &t); ++/* { dg-do run } */ ++/* { dg-options "-O3" } */ + -+ if (t != 15) -+ __builtin_abort (); -+ return 0; -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/insv_2.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/insv_2.c -@@ -0,0 +1,85 @@ -+/* { dg-do run { target aarch64*-*-* } } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+/* { dg-require-effective-target aarch64_big_endian } */ ++#include "arm_neon.h" + +extern void abort (void); + -+typedef struct bitfield -+{ -+ unsigned short eight: 8; -+ unsigned short four: 4; -+ unsigned short five: 5; -+ unsigned short seven: 7; -+ unsigned int sixteen: 16; -+} bitfield; -+ -+bitfield -+bfi1 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 56, 8" } } */ -+ a.eight = 3; -+ return a; -+} -+ -+bitfield -+bfi2 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 43, 5" } } */ -+ a.five = 7; -+ return a; -+} -+ -+bitfield -+movk (bitfield a) -+{ -+ /* { dg-final { scan-assembler "movk\tx\[0-9\]+, 0x1d6b, lsl 16" } } */ -+ a.sixteen = 7531; -+ return a; -+} -+ -+bitfield -+set1 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "orr\tx\[0-9\]+, x\[0-9\]+, 272678883688448" } } */ -+ a.five = 0x1f; -+ return a; -+} -+ -+bitfield -+set0 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -272678883688449" } } */ -+ a.five = 0; -+ return a; -+} -+ ++#include "vaddv-intrinsic.x" + +int -+main (int argc, char** argv) ++main (void) +{ -+ static bitfield a; -+ bitfield b = bfi1 (a); -+ bitfield c = bfi2 (b); -+ bitfield d = movk (c); -+ -+ if (d.eight != 3) -+ abort (); -+ -+ if (d.five != 7) -+ abort (); ++ const float32_t pool_v2sf[] = {4.0f, 9.0f}; ++ const float32_t pool_v4sf[] = {4.0f, 9.0f, 16.0f, 25.0f}; ++ const float64_t pool_v2df[] = {4.0, 9.0}; + -+ if (d.sixteen != 7531) ++ if (test_vaddv_v2sf (pool_v2sf) != 13.0f) + abort (); + -+ d = set1 (d); -+ if (d.five != 0x1f) ++ if (test_vaddv_v4sf (pool_v4sf) != 54.0f) + abort (); + -+ d = set0 (d); -+ if (d.five != 0) ++ if (test_vaddv_v2df (pool_v2df) != 13.0) + abort (); + + return 0; +} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vrecps.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vrecps.c -@@ -0,0 +1,144 @@ +--- a/src/gcc/testsuite/gcc.target/aarch64/sbc.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/sbc.c +@@ -0,0 +1,41 @@ +/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps" } */ -+ -+#include -+#include -+#include -+ -+int -+test_frecps_float32_t (void) -+{ -+ int i; -+ float32_t value = 0.2; -+ float32_t reciprocal = 5.0; -+ float32_t step = vrecpes_f32 (value); -+ /* 3 steps should give us within ~0.001 accuracy. */ -+ for (i = 0; i < 3; i++) -+ step = step * vrecpss_f32 (step, value); -+ -+ return fabs (step - reciprocal) < 0.001; -+} -+ -+/* { dg-final { scan-assembler "frecpe\\ts\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "frecps\\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" } } */ -+ -+int -+test_frecps_float32x2_t (void) -+{ -+ int i; -+ int ret = 1; -+ -+ const float32_t value_pool[] = {0.2, 0.4}; -+ const float32_t reciprocal_pool[] = {5.0, 2.5}; -+ float32x2_t value = vld1_f32 (value_pool); -+ float32x2_t reciprocal = vld1_f32 (reciprocal_pool); -+ -+ float32x2_t step = vrecpe_f32 (value); -+ /* 3 steps should give us within ~0.001 accuracy. */ -+ for (i = 0; i < 3; i++) -+ step = step * vrecps_f32 (step, value); -+ -+ ret &= fabs (vget_lane_f32 (step, 0) -+ - vget_lane_f32 (reciprocal, 0)) < 0.001; -+ ret &= fabs (vget_lane_f32 (step, 1) -+ - vget_lane_f32 (reciprocal, 1)) < 0.001; -+ -+ return ret; -+} -+ -+/* { dg-final { scan-assembler "frecpe\\tv\[0-9\]+.2s, v\[0-9\]+.2s" } } */ -+/* { dg-final { scan-assembler "frecps\\tv\[0-9\]+.2s, v\[0-9\]+.2s, v\[0-9\]+.2s" } } */ -+ -+int -+test_frecps_float32x4_t (void) -+{ -+ int i; -+ int ret = 1; -+ -+ const float32_t value_pool[] = {0.2, 0.4, 0.5, 0.8}; -+ const float32_t reciprocal_pool[] = {5.0, 2.5, 2.0, 1.25}; -+ float32x4_t value = vld1q_f32 (value_pool); -+ float32x4_t reciprocal = vld1q_f32 (reciprocal_pool); -+ -+ float32x4_t step = vrecpeq_f32 (value); -+ /* 3 steps should give us within ~0.001 accuracy. */ -+ for (i = 0; i < 3; i++) -+ step = step * vrecpsq_f32 (step, value); -+ -+ ret &= fabs (vgetq_lane_f32 (step, 0) -+ - vgetq_lane_f32 (reciprocal, 0)) < 0.001; -+ ret &= fabs (vgetq_lane_f32 (step, 1) -+ - vgetq_lane_f32 (reciprocal, 1)) < 0.001; -+ ret &= fabs (vgetq_lane_f32 (step, 2) -+ - vgetq_lane_f32 (reciprocal, 2)) < 0.001; -+ ret &= fabs (vgetq_lane_f32 (step, 3) -+ - vgetq_lane_f32 (reciprocal, 3)) < 0.001; ++/* { dg-options "-O2 --save-temps" } */ + -+ return ret; -+} ++extern void abort (void); + -+/* { dg-final { scan-assembler "frecpe\\tv\[0-9\]+.4s, v\[0-9\]+.4s" } } */ -+/* { dg-final { scan-assembler "frecps\\tv\[0-9\]+.4s, v\[0-9\]+.4s, v\[0-9\]+.4s" } } */ ++typedef unsigned int u32int; ++typedef unsigned long long u64int; + -+int -+test_frecps_float64_t (void) ++u32int ++test_si (u32int w1, u32int w2, u32int w3, u32int w4) +{ -+ int i; -+ float64_t value = 0.2; -+ float64_t reciprocal = 5.0; -+ float64_t step = vrecped_f64 (value); -+ /* 3 steps should give us within ~0.001 accuracy. */ -+ for (i = 0; i < 3; i++) -+ step = step * vrecpsd_f64 (step, value); -+ -+ return fabs (step - reciprocal) < 0.001; ++ u32int w0; ++ /* { dg-final { scan-assembler "sbc\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+\n" } } */ ++ w0 = w1 - w2 - (w3 < w4); ++ return w0; +} + -+/* { dg-final { scan-assembler "frecpe\\td\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "frecps\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" } } */ -+ -+int -+test_frecps_float64x2_t (void) ++u64int ++test_di (u64int x1, u64int x2, u64int x3, u64int x4) +{ -+ int i; -+ int ret = 1; -+ -+ const float64_t value_pool[] = {0.2, 0.4}; -+ const float64_t reciprocal_pool[] = {5.0, 2.5}; -+ float64x2_t value = vld1q_f64 (value_pool); -+ float64x2_t reciprocal = vld1q_f64 (reciprocal_pool); -+ -+ float64x2_t step = vrecpeq_f64 (value); -+ /* 3 steps should give us within ~0.001 accuracy. */ -+ for (i = 0; i < 3; i++) -+ step = step * vrecpsq_f64 (step, value); -+ -+ ret &= fabs (vgetq_lane_f64 (step, 0) -+ - vgetq_lane_f64 (reciprocal, 0)) < 0.001; -+ ret &= fabs (vgetq_lane_f64 (step, 1) -+ - vgetq_lane_f64 (reciprocal, 1)) < 0.001; -+ -+ return ret; ++ u64int x0; ++ /* { dg-final { scan-assembler "sbc\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+\n" } } */ ++ x0 = x1 - x2 - (x3 < x4); ++ return x0; +} + -+/* { dg-final { scan-assembler "frecpe\\tv\[0-9\]+.2d, v\[0-9\]+.2d" } } */ -+/* { dg-final { scan-assembler "frecps\\tv\[0-9\]+.2d, v\[0-9\]+.2d, v\[0-9\]+.2d" } } */ -+ +int -+main (int argc, char **argv) ++main () +{ -+ if (!test_frecps_float32_t ()) -+ abort (); -+ if (!test_frecps_float32x2_t ()) -+ abort (); -+ if (!test_frecps_float32x4_t ()) -+ abort (); -+ if (!test_frecps_float64_t ()) -+ abort (); -+ if (!test_frecps_float64x2_t ()) -+ abort (); -+ ++ u32int x; ++ u64int y; ++ x = test_si (7, 8, 12, 15); ++ if (x != -2) ++ abort(); ++ y = test_di (0x987654321ll, 0x123456789ll, 0x345345345ll, 0x123123123ll); ++ if (y != 0x8641fdb98ll) ++ abort(); + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/ands_2.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/ands_2.c -@@ -0,0 +1,157 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.x +@@ -0,0 +1,36 @@ + -+extern void abort (void); ++#define STRONG 0 ++#define WEAK 1 ++int v = 0; + +int -+ands_si_test1 (int a, int b, int c) ++atomic_compare_exchange_STRONG_RELEASE_ACQUIRE (int a, int b) +{ -+ int d = a & b; -+ -+ /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler-times "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; ++ return __atomic_compare_exchange (&v, &a, &b, ++ STRONG, __ATOMIC_RELEASE, ++ __ATOMIC_ACQUIRE); +} + +int -+ands_si_test2 (int a, int b, int c) ++atomic_compare_exchange_WEAK_RELEASE_ACQUIRE (int a, int b) +{ -+ int d = a & 0x99999999; -+ -+ /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ -+ /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; ++ return __atomic_compare_exchange (&v, &a, &b, ++ WEAK, __ATOMIC_RELEASE, ++ __ATOMIC_ACQUIRE); +} + +int -+ands_si_test3 (int a, int b, int c) ++atomic_compare_exchange_n_STRONG_RELEASE_ACQUIRE (int a, int b) +{ -+ int d = a & (b << 3); -+ -+ /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; ++ return __atomic_compare_exchange_n (&v, &a, b, ++ STRONG, __ATOMIC_RELEASE, ++ __ATOMIC_ACQUIRE); +} + -+typedef long long s64; -+ -+s64 -+ands_di_test1 (s64 a, s64 b, s64 c) ++int ++atomic_compare_exchange_n_WEAK_RELEASE_ACQUIRE (int a, int b) +{ -+ s64 d = a & b; -+ -+ /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler-times "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; ++ return __atomic_compare_exchange_n (&v, &a, b, ++ WEAK, __ATOMIC_RELEASE, ++ __ATOMIC_ACQUIRE); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c +@@ -1,8 +1,14 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2" } */ ++/* { dg-options "-O2 -dp" } */ + +-#include "../../../config/aarch64/arm_neon.h" ++#include + ++/* Used to force a variable to a SIMD register. */ ++#define force_simd(V1) asm volatile ("mov %d0, %1.d[0]" \ ++ : "=w"(V1) \ ++ : "w"(V1) \ ++ : /* No clobbers */); + -+s64 -+ands_di_test2 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a & 0xaaaaaaaaaaaaaaaall; -+ -+ /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ -+ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} + /* { dg-final { scan-assembler-times "\\tadd\\tx\[0-9\]+" 2 } } */ + + uint64x1_t +@@ -26,12 +32,29 @@ + vqaddd_s64 (a, d)); + } + ++/* { dg-final { scan-assembler-times "\\tabs\\td\[0-9\]+, d\[0-9\]+" 1 } } */ + -+s64 -+ands_di_test3 (s64 a, s64 b, s64 c) ++int64x1_t ++test_vabs_s64 (int64x1_t a) +{ -+ s64 d = a & (b << 3); -+ -+ /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; ++ uint64x1_t res; ++ force_simd (a); ++ res = vabs_s64 (a); ++ force_simd (res); ++ return res; +} + -+int -+main () -+{ -+ int x; -+ s64 y; -+ -+ x = ands_si_test1 (29, 4, 5); -+ if (x != 13) -+ abort (); -+ -+ x = ands_si_test1 (5, 2, 20); -+ if (x != 25) -+ abort (); -+ -+ x = ands_si_test2 (29, 4, 5); -+ if (x != 34) -+ abort (); -+ -+ x = ands_si_test2 (1024, 2, 20); -+ if (x != 1044) -+ abort (); -+ -+ x = ands_si_test3 (35, 4, 5); -+ if (x != 41) -+ abort (); -+ -+ x = ands_si_test3 (5, 2, 20); -+ if (x != 25) -+ abort (); -+ -+ y = ands_di_test1 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ -+ if (y != ((0x130000029ll & 0x320000004ll) + 0x320000004ll + 0x505050505ll)) -+ abort (); -+ -+ y = ands_di_test1 (0x5000500050005ll, -+ 0x2111211121112ll, -+ 0x0000000002020ll); -+ if (y != 0x5000500052025ll) -+ abort (); -+ -+ y = ands_di_test2 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != ((0x130000029ll & 0xaaaaaaaaaaaaaaaall) + 0x320000004ll + 0x505050505ll)) -+ abort (); -+ -+ y = ands_di_test2 (0x540004100ll, -+ 0x320000004ll, -+ 0x805050205ll); -+ if (y != (0x540004100ll + 0x805050205ll)) -+ abort (); -+ -+ y = ands_di_test3 (0x130000029ll, -+ 0x064000008ll, -+ 0x505050505ll); -+ if (y != ((0x130000029ll & (0x064000008ll << 3)) -+ + 0x064000008ll + 0x505050505ll)) -+ abort (); -+ -+ y = ands_di_test3 (0x130002900ll, -+ 0x088000008ll, -+ 0x505050505ll); -+ if (y != (0x130002900ll + 0x505050505ll)) -+ abort (); -+ -+ return 0; -+} + /* { dg-final { scan-assembler-times "\\tcmeq\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */ + + uint64x1_t + test_vceqd_s64 (int64x1_t a, int64x1_t b) + { +- return vceqd_s64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vceqd_s64 (a, b); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\tcmeq\\td\[0-9\]+, d\[0-9\]+, #?0" 1 } } */ +@@ -39,7 +62,11 @@ + uint64x1_t + test_vceqzd_s64 (int64x1_t a) + { +- return vceqzd_s64 (a); ++ uint64x1_t res; ++ force_simd (a); ++ res = vceqzd_s64 (a); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\tcmge\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 2 } } */ +@@ -47,21 +74,36 @@ + uint64x1_t + test_vcged_s64 (int64x1_t a, int64x1_t b) + { +- return vcged_s64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vcged_s64 (a, b); ++ force_simd (res); ++ return res; + } + + uint64x1_t + test_vcled_s64 (int64x1_t a, int64x1_t b) + { +- return vcled_s64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vcled_s64 (a, b); ++ force_simd (res); ++ return res; + } + +-/* { dg-final { scan-assembler-times "\\tcmge\\td\[0-9\]+, d\[0-9\]+, #?0" 1 } } */ ++/* Idiom recognition will cause this testcase not to generate ++ the expected cmge instruction, so do not check for it. */ + + uint64x1_t + test_vcgezd_s64 (int64x1_t a) + { +- return vcgezd_s64 (a); ++ uint64x1_t res; ++ force_simd (a); ++ res = vcgezd_s64 (a); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\tcmhs\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */ +@@ -69,7 +111,12 @@ + uint64x1_t + test_vcged_u64 (uint64x1_t a, uint64x1_t b) + { +- return vcged_u64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vcged_u64 (a, b); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\tcmgt\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 2 } } */ +@@ -77,13 +124,23 @@ + uint64x1_t + test_vcgtd_s64 (int64x1_t a, int64x1_t b) + { +- return vcgtd_s64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vcgtd_s64 (a, b); ++ force_simd (res); ++ return res; + } + + uint64x1_t + test_vcltd_s64 (int64x1_t a, int64x1_t b) + { +- return vcltd_s64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vcltd_s64 (a, b); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\tcmgt\\td\[0-9\]+, d\[0-9\]+, #?0" 1 } } */ +@@ -91,7 +148,11 @@ + uint64x1_t + test_vcgtzd_s64 (int64x1_t a) + { +- return vcgtzd_s64 (a); ++ uint64x1_t res; ++ force_simd (a); ++ res = vcgtzd_s64 (a); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\tcmhi\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */ +@@ -99,7 +160,12 @@ + uint64x1_t + test_vcgtd_u64 (uint64x1_t a, uint64x1_t b) + { +- return vcgtd_u64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vcgtd_u64 (a, b); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\tcmle\\td\[0-9\]+, d\[0-9\]+, #?0" 1 } } */ +@@ -107,18 +173,27 @@ + uint64x1_t + test_vclezd_s64 (int64x1_t a) + { +- return vclezd_s64 (a); ++ uint64x1_t res; ++ force_simd (a); ++ res = vclezd_s64 (a); ++ force_simd (res); ++ return res; + } + +-/* { dg-final { scan-assembler-times "\\tcmlt\\td\[0-9\]+, d\[0-9\]+, #?0" 1 } } */ ++/* Idiom recognition will cause this testcase not to generate ++ the expected cmlt instruction, so do not check for it. */ + + uint64x1_t + test_vcltzd_s64 (int64x1_t a) + { +- return vcltzd_s64 (a); ++ uint64x1_t res; ++ force_simd (a); ++ res = vcltzd_s64 (a); ++ force_simd (res); ++ return res; + } + +-/* { dg-final { scan-assembler-times "\\tdup\\tb\[0-9\]+, v\[0-9\]+\.b" 2 } } */ ++/* { dg-final { scan-assembler-times "aarch64_get_lanev16qi" 2 } } */ + + int8x1_t + test_vdupb_lane_s8 (int8x16_t a) +@@ -132,7 +207,7 @@ + return vdupb_lane_u8 (a, 2); + } + +-/* { dg-final { scan-assembler-times "\\tdup\\th\[0-9\]+, v\[0-9\]+\.h" 2 } } */ ++/* { dg-final { scan-assembler-times "aarch64_get_lanev8hi" 2 } } */ + + int16x1_t + test_vduph_lane_s16 (int16x8_t a) +@@ -146,7 +221,7 @@ + return vduph_lane_u16 (a, 2); + } + +-/* { dg-final { scan-assembler-times "\\tdup\\ts\[0-9\]+, v\[0-9\]+\.s" 2 } } */ ++/* { dg-final { scan-assembler-times "aarch64_get_lanev4si" 2 } } */ + + int32x1_t + test_vdups_lane_s32 (int32x4_t a) +@@ -160,18 +235,18 @@ + return vdups_lane_u32 (a, 2); + } + +-/* { dg-final { scan-assembler-times "\\tdup\\td\[0-9\]+, v\[0-9\]+\.d" 2 } } */ ++/* { dg-final { scan-assembler-times "aarch64_get_lanev2di" 2 } } */ + + int64x1_t + test_vdupd_lane_s64 (int64x2_t a) + { +- return vdupd_lane_s64 (a, 2); ++ return vdupd_lane_s64 (a, 1); + } + + uint64x1_t + test_vdupd_lane_u64 (uint64x2_t a) + { +- return vdupd_lane_u64 (a, 2); ++ return vdupd_lane_u64 (a, 1); + } + + /* { dg-final { scan-assembler-times "\\tcmtst\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 2 } } */ +@@ -179,13 +254,23 @@ + int64x1_t + test_vtst_s64 (int64x1_t a, int64x1_t b) + { +- return vtstd_s64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vtstd_s64 (a, b); ++ force_simd (res); ++ return res; + } + + uint64x1_t + test_vtst_u64 (uint64x1_t a, uint64x1_t b) + { +- return vtstd_u64 (a, b); ++ uint64x1_t res; ++ force_simd (a); ++ force_simd (b); ++ res = vtstd_s64 (a, b); ++ force_simd (res); ++ return res; + } + + /* { dg-final { scan-assembler-times "\\taddp\\td\[0-9\]+, v\[0-9\]+\.2d" 1 } } */ +@@ -722,8 +807,11 @@ + return vrshld_u64 (a, b); + } + +-/* { dg-final { scan-assembler-times "\\tasr\\tx\[0-9\]+" 1 } } */ ++/* Other intrinsics can generate an asr instruction (vcltzd, vcgezd), ++ so we cannot check scan-assembler-times. */ + ++/* { dg-final { scan-assembler "\\tasr\\tx\[0-9\]+" } } */ + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/scalar-vca.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/scalar-vca.c -@@ -0,0 +1,72 @@ + int64x1_t + test_vshrd_n_s64 (int64x1_t a) + { +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.c +@@ -1,43 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ + +-int v = 0; ++#include "atomic-op-int.x" + +-int +-atomic_fetch_add_RELAXED (int a) +-{ +- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_sub_RELAXED (int a) +-{ +- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_and_RELAXED (int a) +-{ +- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_nand_RELAXED (int a) +-{ +- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_xor_RELAXED (int a) +-{ +- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +-} +- +-int +-atomic_fetch_or_RELAXED (int a) +-{ +- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); +-} +- + /* { dg-final { scan-assembler-times "ldxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ + /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/cmn-neg.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/cmn-neg.c +@@ -0,0 +1,33 @@ +/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps" } */ -+ -+#include ++/* { dg-options "-O2 --save-temps" } */ + +extern void abort (void); -+extern float fabsf (float); -+extern double fabs (double); + -+#define NUM_TESTS 8 -+ -+float input_s1[] = {0.1f, -0.1f, 0.4f, 10.3f, 200.0f, -800.0f, -13.0f, -0.5f}; -+float input_s2[] = {-0.2f, 0.4f, 0.04f, -100.3f, 2.0f, -80.0f, 13.0f, -0.5f}; -+double input_d1[] = {0.1, -0.1, 0.4, 10.3, 200.0, -800.0, -13.0, -0.5}; -+double input_d2[] = {-0.2, 0.4, 0.04, -100.3, 2.0, -80.0, 13.0, -0.5}; ++void __attribute__ ((noinline)) ++foo_s32 (int a, int b) ++{ ++ if (a < -b) ++ abort (); ++} ++/* { dg-final { scan-assembler "cmn\tw\[0-9\]" } } */ + -+#define TEST(TEST, CMP, SUFFIX, WIDTH, F) \ -+int \ -+test_fca##TEST##SUFFIX##_float##WIDTH##_t (void) \ -+{ \ -+ int ret = 0; \ -+ int i = 0; \ -+ uint##WIDTH##_t output[NUM_TESTS]; \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ { \ -+ float##WIDTH##_t f1 = fabs##F (input_##SUFFIX##1[i]); \ -+ float##WIDTH##_t f2 = fabs##F (input_##SUFFIX##2[i]); \ -+ /* Inhibit optimization of our linear test loop. */ \ -+ asm volatile ("" : : : "memory"); \ -+ output[i] = f1 CMP f2 ? -1 : 0; \ -+ } \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ { \ -+ output[i] = vca##TEST##SUFFIX##_f##WIDTH (input_##SUFFIX##1[i], \ -+ input_##SUFFIX##2[i]) \ -+ ^ output[i]; \ -+ /* Inhibit autovectorization of our scalar test loop. */ \ -+ asm volatile ("" : : : "memory"); \ -+ } \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ ret |= output[i]; \ -+ \ -+ return ret; \ ++void __attribute__ ((noinline)) ++foo_s64 (long long a, long long b) ++{ ++ if (a < -b) ++ abort (); +} ++/* { dg-final { scan-assembler "cmn\tx\[0-9\]" } } */ + -+TEST (ge, >=, s, 32, f) -+/* { dg-final { scan-assembler "facge\\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" } } */ -+TEST (ge, >=, d, 64, ) -+/* { dg-final { scan-assembler "facge\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" } } */ -+TEST (gt, >, s, 32, f) -+/* { dg-final { scan-assembler "facgt\\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" } } */ -+TEST (gt, >, d, 64, ) -+/* { dg-final { scan-assembler "facgt\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" } } */ + +int -+main (int argc, char **argv) ++main (void) +{ -+ if (test_fcages_float32_t ()) -+ abort (); -+ if (test_fcaged_float64_t ()) -+ abort (); -+ if (test_fcagts_float32_t ()) -+ abort (); -+ if (test_fcagtd_float64_t ()) -+ abort (); ++ int a = 30; ++ int b = 42; ++ foo_s32 (a, b); ++ foo_s64 (a, b); + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.x -@@ -0,0 +1,37 @@ -+int v = 0; +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.c +@@ -1,43 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ + +-int v = 0; ++#include "atomic-op-seq_cst.x" + +-int +-atomic_fetch_add_SEQ_CST (int a) +-{ +- return __atomic_fetch_add (&v, a, __ATOMIC_SEQ_CST); +-} +- +-int +-atomic_fetch_sub_SEQ_CST (int a) +-{ +- return __atomic_fetch_sub (&v, a, __ATOMIC_SEQ_CST); +-} +- +-int +-atomic_fetch_and_SEQ_CST (int a) +-{ +- return __atomic_fetch_and (&v, a, __ATOMIC_SEQ_CST); +-} +- +-int +-atomic_fetch_nand_SEQ_CST (int a) +-{ +- return __atomic_fetch_nand (&v, a, __ATOMIC_SEQ_CST); +-} +- +-int +-atomic_fetch_xor_SEQ_CST (int a) +-{ +- return __atomic_fetch_xor (&v, a, __ATOMIC_SEQ_CST); +-} +- +-int +-atomic_fetch_or_SEQ_CST (int a) +-{ +- return __atomic_fetch_or (&v, a, __ATOMIC_SEQ_CST); +-} +- + /* { dg-final { scan-assembler-times "ldaxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ + /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.x +@@ -0,0 +1,27 @@ + -+int -+atomic_fetch_add_ACQ_REL (int a) ++float32_t ++test_vaddv_v2sf (const float32_t *pool) +{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_ACQ_REL); -+} ++ float32x2_t val; + -+int -+atomic_fetch_sub_ACQ_REL (int a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_ACQ_REL); ++ val = vld1_f32 (pool); ++ return vaddv_f32 (val); +} + -+int -+atomic_fetch_and_ACQ_REL (int a) ++float32_t ++test_vaddv_v4sf (const float32_t *pool) +{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_ACQ_REL); ++ float32x4_t val; ++ ++ val = vld1q_f32 (pool); ++ return vaddvq_f32 (val); +} + -+int -+atomic_fetch_nand_ACQ_REL (int a) ++float64_t ++test_vaddv_v2df (const float64_t *pool) +{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_ACQ_REL); ++ float64x2_t val; ++ ++ val = vld1q_f64 (pool); ++ return vaddvq_f64 (val); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/negs.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/negs.c +@@ -0,0 +1,108 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps" } */ ++ ++extern void abort (void); ++int z; + +int -+atomic_fetch_xor_ACQ_REL (int a) ++negs_si_test1 (int a, int b, int c) +{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_ACQ_REL); ++ int d = -b; ++ ++ /* { dg-final { scan-assembler "negs\tw\[0-9\]+, w\[0-9\]+" } } */ ++ if (d < 0) ++ return a + c; ++ ++ z = d; ++ return b + c + d; +} + +int -+atomic_fetch_or_ACQ_REL (int a) ++negs_si_test3 (int a, int b, int c) +{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_ACQ_REL); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/vect_smlal_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect_smlal_1.c -@@ -0,0 +1,325 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 -fno-inline -save-temps -fno-vect-cost-model" } */ -+ -+typedef signed char S8_t; -+typedef signed short S16_t; -+typedef signed int S32_t; -+typedef signed long S64_t; -+typedef signed char *__restrict__ pS8_t; -+typedef signed short *__restrict__ pS16_t; -+typedef signed int *__restrict__ pS32_t; -+typedef signed long *__restrict__ pS64_t; -+typedef unsigned char U8_t; -+typedef unsigned short U16_t; -+typedef unsigned int U32_t; -+typedef unsigned long U64_t; -+typedef unsigned char *__restrict__ pU8_t; -+typedef unsigned short *__restrict__ pU16_t; -+typedef unsigned int *__restrict__ pU32_t; -+typedef unsigned long *__restrict__ pU64_t; ++ int d = -(b) << 3; + -+extern void abort (); ++ /* { dg-final { scan-assembler "negs\tw\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; + -+void -+test_addS64_tS32_t4 (pS64_t a, pS32_t b, pS32_t c) -+{ -+ int i; -+ for (i = 0; i < 4; i++) -+ a[i] += (S64_t) b[i] * (S64_t) c[i]; ++ z = d; ++ return b + c + d; +} + -+/* { dg-final { scan-assembler "smlal\tv\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "smlal2\tv\[0-9\]+\.2d" } } */ ++typedef long long s64; ++s64 zz; + -+void -+test_addS32_tS16_t8 (pS32_t a, pS16_t b, pS16_t c) ++s64 ++negs_di_test1 (s64 a, s64 b, s64 c) +{ -+ int i; -+ for (i = 0; i < 8; i++) -+ a[i] += (S32_t) b[i] * (S32_t) c[i]; -+} ++ s64 d = -b; + -+/* { dg-final { scan-assembler "smlal\tv\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "smlal2\tv\[0-9\]+\.4s" } } */ ++ /* { dg-final { scan-assembler "negs\tx\[0-9\]+, x\[0-9\]+" } } */ ++ if (d < 0) ++ return a + c; + -+void -+test_addS16_tS8_t16 (pS16_t a, pS8_t b, pS8_t c) -+{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] += (S16_t) b[i] * (S16_t) c[i]; ++ zz = d; ++ return b + c + d; +} + -+void -+test_addS16_tS8_t16_neg0 (pS16_t a, pS8_t b, pS8_t c) ++s64 ++negs_di_test3 (s64 a, s64 b, s64 c) +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] += (S16_t) -b[i] * (S16_t) -c[i]; -+} ++ s64 d = -(b) << 3; + -+void -+test_addS16_tS8_t16_neg1 (pS16_t a, pS8_t b, pS8_t c) -+{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] -= (S16_t) b[i] * (S16_t) -c[i]; ++ /* { dg-final { scan-assembler "negs\tx\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; ++ ++ zz = d; ++ return b + c + d; +} + -+void -+test_addS16_tS8_t16_neg2 (pS16_t a, pS8_t b, pS8_t c) ++int main () +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] -= (S16_t) -b[i] * (S16_t) c[i]; ++ int x; ++ s64 y; ++ ++ x = negs_si_test1 (2, 12, 5); ++ if (x != 7) ++ abort (); ++ ++ x = negs_si_test1 (1, 2, 32); ++ if (x != 33) ++ abort (); ++ ++ x = negs_si_test3 (13, 14, 5); ++ if (x != -93) ++ abort (); ++ ++ x = negs_si_test3 (15, 21, 2); ++ if (x != -145) ++ abort (); ++ ++ y = negs_di_test1 (0x20202020ll, ++ 0x65161611ll, ++ 0x42434243ll); ++ if (y != 0x62636263ll) ++ abort (); ++ ++ y = negs_di_test1 (0x1010101010101ll, ++ 0x123456789abcdll, ++ 0x5555555555555ll); ++ if (y != 0x6565656565656ll) ++ abort (); ++ ++ y = negs_di_test3 (0x62523781ll, ++ 0x64234978ll, ++ 0x12345123ll); ++ if (y != 0xfffffffd553d4edbll) ++ abort (); ++ ++ y = negs_di_test3 (0x763526268ll, ++ 0x101010101ll, ++ 0x222222222ll); ++ if (y != 0xfffffffb1b1b1b1bll) ++ abort (); ++ ++ return 0; +} +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.c +@@ -1,43 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ + +-int v = 0; ++#include "atomic-op-consume.x" + +-int +-atomic_fetch_add_CONSUME (int a) +-{ +- return __atomic_fetch_add (&v, a, __ATOMIC_CONSUME); +-} +- +-int +-atomic_fetch_sub_CONSUME (int a) +-{ +- return __atomic_fetch_sub (&v, a, __ATOMIC_CONSUME); +-} +- +-int +-atomic_fetch_and_CONSUME (int a) +-{ +- return __atomic_fetch_and (&v, a, __ATOMIC_CONSUME); +-} +- +-int +-atomic_fetch_nand_CONSUME (int a) +-{ +- return __atomic_fetch_nand (&v, a, __ATOMIC_CONSUME); +-} +- +-int +-atomic_fetch_xor_CONSUME (int a) +-{ +- return __atomic_fetch_xor (&v, a, __ATOMIC_CONSUME); +-} +- +-int +-atomic_fetch_or_CONSUME (int a) +-{ +- return __atomic_fetch_or (&v, a, __ATOMIC_CONSUME); +-} +- + /* { dg-final { scan-assembler-times "ldxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ + /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-vaddv.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vaddv.c +@@ -0,0 +1,128 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps -ffast-math" } */ + -+/* { dg-final { scan-assembler-times "smlal\tv\[0-9\]+\.8h" 4 } } */ -+/* { dg-final { scan-assembler-times "smlal2\tv\[0-9\]+\.8h" 4 } } */ ++#include + -+void -+test_subS64_tS32_t4 (pS64_t a, pS32_t b, pS32_t c) -+{ -+ int i; -+ for (i = 0; i < 4; i++) -+ a[i] -= (S64_t) b[i] * (S64_t) c[i]; ++extern void abort (void); ++extern float fabsf (float); ++extern double fabs (double); ++ ++#define NUM_TESTS 16 ++#define DELTA 0.000001 ++ ++int8_t input_int8[] = {1, 56, 2, -9, -90, 23, 54, 76, ++ -4, 34, 110, -110, 6, 4, 75, -34}; ++int16_t input_int16[] = {1, 56, 2, -9, -90, 23, 54, 76, ++ -4, 34, 110, -110, 6, 4, 75, -34}; ++int32_t input_int32[] = {1, 56, 2, -9, -90, 23, 54, 76, ++ -4, 34, 110, -110, 6, 4, 75, -34}; ++int64_t input_int64[] = {1, 56, 2, -9, -90, 23, 54, 76, ++ -4, 34, 110, -110, 6, 4, 75, -34}; ++ ++uint8_t input_uint8[] = {1, 56, 2, 9, 90, 23, 54, 76, ++ 4, 34, 110, 110, 6, 4, 75, 34}; ++uint16_t input_uint16[] = {1, 56, 2, 9, 90, 23, 54, 76, ++ 4, 34, 110, 110, 6, 4, 75, 34}; ++uint32_t input_uint32[] = {1, 56, 2, 9, 90, 23, 54, 76, ++ 4, 34, 110, 110, 6, 4, 75, 34}; ++ ++uint64_t input_uint64[] = {1, 56, 2, 9, 90, 23, 54, 76, ++ 4, 34, 110, 110, 6, 4, 75, 34}; ++ ++float input_float32[] = {0.1f, -0.1f, 0.4f, 10.3f, ++ 200.0f, -800.0f, -13.0f, -0.5f, ++ 7.9f, -870.0f, 10.4f, 310.11f, ++ 0.0f, -865.0f, -2213.0f, -1.5f}; ++ ++double input_float64[] = {0.1, -0.1, 0.4, 10.3, ++ 200.0, -800.0, -13.0, -0.5, ++ 7.9, -870.0, 10.4, 310.11, ++ 0.0, -865.0, -2213.0, -1.5}; ++ ++#define EQUALF(a, b) (fabsf (a - b) < DELTA) ++#define EQUALD(a, b) (fabs (a - b) < DELTA) ++#define EQUALL(a, b) (a == b) ++ ++#define TEST(SUFFIX, Q, TYPE, LANES, FLOAT) \ ++int \ ++test_vaddv##SUFFIX##_##TYPE##x##LANES##_t (void) \ ++{ \ ++ int i, j; \ ++ int moves = (NUM_TESTS - LANES) + 1; \ ++ TYPE##_t out_l[NUM_TESTS]; \ ++ TYPE##_t out_v[NUM_TESTS]; \ ++ \ ++ /* Calculate linearly. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ out_l[i] = input_##TYPE[i]; \ ++ for (j = 1; j < LANES; j++) \ ++ out_l[i] += input_##TYPE[i + j]; \ ++ } \ ++ \ ++ /* Calculate using vector reduction intrinsics. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ ++ out_v[i] = vaddv##Q##_##SUFFIX (t1); \ ++ } \ ++ \ ++ /* Compare. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ if (!EQUAL##FLOAT (out_v[i], out_l[i])) \ ++ return 0; \ ++ } \ ++ return 1; \ +} + -+/* { dg-final { scan-assembler "smlsl\tv\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "smlsl2\tv\[0-9\]+\.2d" } } */ ++#define BUILD_VARIANTS(TYPE, STYPE, W32, W64, F) \ ++TEST (STYPE, , TYPE, W32, F) \ ++TEST (STYPE, q, TYPE, W64, F) \ + -+void -+test_subS32_tS16_t8 (pS32_t a, pS16_t b, pS16_t c) ++BUILD_VARIANTS (int8, s8, 8, 16, L) ++BUILD_VARIANTS (uint8, u8, 8, 16, L) ++/* { dg-final { scan-assembler "addv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ ++/* { dg-final { scan-assembler "addv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ ++BUILD_VARIANTS (int16, s16, 4, 8, L) ++BUILD_VARIANTS (uint16, u16, 4, 8, L) ++/* { dg-final { scan-assembler "addv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ ++/* { dg-final { scan-assembler "addv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ ++BUILD_VARIANTS (int32, s32, 2, 4, L) ++BUILD_VARIANTS (uint32, u32, 2, 4, L) ++/* { dg-final { scan-assembler "addp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "addv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++TEST (s64, q, int64, 2, D) ++TEST (u64, q, uint64, 2, D) ++/* { dg-final { scan-assembler "addp\\td\[0-9\]+\, v\[0-9\]+\.2d" } } */ ++ ++BUILD_VARIANTS (float32, f32, 2, 4, F) ++/* { dg-final { scan-assembler "faddp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "faddp\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++TEST (f64, q, float64, 2, D) ++/* { dg-final { scan-assembler "faddp\\td\[0-9\]+\, v\[0-9\]+\.2d" } } */ ++ ++#undef TEST ++#define TEST(SUFFIX, Q, TYPE, LANES, FLOAT) \ ++{ \ ++ if (!test_vaddv##SUFFIX##_##TYPE##x##LANES##_t ()) \ ++ abort (); \ ++} ++ ++int ++main (int argc, char **argv) +{ -+ int i; -+ for (i = 0; i < 8; i++) -+ a[i] -= (S32_t) b[i] * (S32_t) c[i]; ++BUILD_VARIANTS (int8, s8, 8, 16, L) ++BUILD_VARIANTS (uint8, u8, 8, 16, L) ++BUILD_VARIANTS (int16, s16, 4, 8, L) ++BUILD_VARIANTS (uint16, u16, 4, 8, L) ++BUILD_VARIANTS (int32, s32, 2, 4, L) ++BUILD_VARIANTS (uint32, u32, 2, 4, L) ++ ++BUILD_VARIANTS (float32, f32, 2, 4, F) ++TEST (f64, q, float64, 2, D) ++ ++ return 0; +} + -+/* { dg-final { scan-assembler "smlsl\tv\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "smlsl2\tv\[0-9\]+\.4s" } } */ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.c +@@ -1,43 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ + +-char v = 0; ++#include "atomic-op-char.x" + +-char +-atomic_fetch_add_RELAXED (char a) +-{ +- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); +-} +- +-char +-atomic_fetch_sub_RELAXED (char a) +-{ +- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); +-} +- +-char +-atomic_fetch_and_RELAXED (char a) +-{ +- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +-} +- +-char +-atomic_fetch_nand_RELAXED (char a) +-{ +- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +-} +- +-char +-atomic_fetch_xor_RELAXED (char a) +-{ +- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +-} +- +-char +-atomic_fetch_or_RELAXED (char a) +-{ +- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); +-} +- + /* { dg-final { scan-assembler-times "ldxrb\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ + /* { dg-final { scan-assembler-times "stxrb\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.x +@@ -0,0 +1,37 @@ ++int v = 0; + -+void -+test_subS16_tS8_t16 (pS16_t a, pS8_t b, pS8_t c) ++int ++atomic_fetch_add_RELAXED (int a) +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] -= (S16_t) b[i] * (S16_t) c[i]; ++ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); +} + -+void -+test_subS16_tS8_t16_neg0 (pS16_t a, pS8_t b, pS8_t c) ++int ++atomic_fetch_sub_RELAXED (int a) +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] += (S16_t) -b[i] * (S16_t) c[i]; ++ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); +} + -+void -+test_subS16_tS8_t16_neg1 (pS16_t a, pS8_t b, pS8_t c) ++int ++atomic_fetch_and_RELAXED (int a) +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] += (S16_t) b[i] * (S16_t) -c[i]; ++ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +} + -+void -+test_subS16_tS8_t16_neg2 (pS16_t a, pS8_t b, pS8_t c) ++int ++atomic_fetch_nand_RELAXED (int a) +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] += -((S16_t) b[i] * (S16_t) c[i]); ++ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +} + -+void -+test_subS16_tS8_t16_neg3 (pS16_t a, pS8_t b, pS8_t c) ++int ++atomic_fetch_xor_RELAXED (int a) +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] -= (S16_t) -b[i] * (S16_t) -c[i]; ++ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +} + -+/* { dg-final { scan-assembler-times "smlsl\tv\[0-9\]+\.8h" 5 } } */ -+/* { dg-final { scan-assembler-times "smlsl2\tv\[0-9\]+\.8h" 5 } } */ -+ -+void -+test_addU64_tU32_t4 (pU64_t a, pU32_t b, pU32_t c) ++int ++atomic_fetch_or_RELAXED (int a) +{ -+ int i; -+ for (i = 0; i < 4; i++) -+ a[i] += (U64_t) b[i] * (U64_t) c[i]; ++ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.x +@@ -0,0 +1,37 @@ ++int v = 0; + -+/* { dg-final { scan-assembler "umlal\tv\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "umlal2\tv\[0-9\]+\.2d" } } */ -+ -+void -+test_addU32_tU16_t8 (pU32_t a, pU16_t b, pU16_t c) ++int ++atomic_fetch_add_SEQ_CST (int a) +{ -+ int i; -+ for (i = 0; i < 8; i++) -+ a[i] += (U32_t) b[i] * (U32_t) c[i]; ++ return __atomic_fetch_add (&v, a, __ATOMIC_SEQ_CST); +} + -+/* { dg-final { scan-assembler "umlal\tv\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "umlal2\tv\[0-9\]+\.4s" } } */ -+ -+void -+test_addU16_tU8_t16 (pU16_t a, pU8_t b, pU8_t c) ++int ++atomic_fetch_sub_SEQ_CST (int a) +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] += (U16_t) b[i] * (U16_t) c[i]; ++ return __atomic_fetch_sub (&v, a, __ATOMIC_SEQ_CST); +} + -+/* { dg-final { scan-assembler "umlal\tv\[0-9\]+\.8h" } } */ -+/* { dg-final { scan-assembler "umlal2\tv\[0-9\]+\.8h" } } */ ++int ++atomic_fetch_and_SEQ_CST (int a) ++{ ++ return __atomic_fetch_and (&v, a, __ATOMIC_SEQ_CST); ++} + -+void -+test_subU64_tU32_t4 (pU64_t a, pU32_t b, pU32_t c) ++int ++atomic_fetch_nand_SEQ_CST (int a) +{ -+ int i; -+ for (i = 0; i < 4; i++) -+ a[i] -= (U64_t) b[i] * (U64_t) c[i]; ++ return __atomic_fetch_nand (&v, a, __ATOMIC_SEQ_CST); +} + -+/* { dg-final { scan-assembler "umlsl\tv\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "umlsl2\tv\[0-9\]+\.2d" } } */ ++int ++atomic_fetch_xor_SEQ_CST (int a) ++{ ++ return __atomic_fetch_xor (&v, a, __ATOMIC_SEQ_CST); ++} + -+void -+test_subU32_tU16_t8 (pU32_t a, pU16_t b, pU16_t c) ++int ++atomic_fetch_or_SEQ_CST (int a) +{ -+ int i; -+ for (i = 0; i < 8; i++) -+ a[i] -= (U32_t) b[i] * (U32_t) c[i]; ++ return __atomic_fetch_or (&v, a, __ATOMIC_SEQ_CST); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/bfxil_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/bfxil_1.c +@@ -0,0 +1,40 @@ ++/* { dg-do run { target aarch64*-*-* } } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ ++/* { dg-require-effective-target aarch64_little_endian } */ + -+/* { dg-final { scan-assembler "umlsl\tv\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "umlsl2\tv\[0-9\]+\.4s" } } */ ++extern void abort (void); + -+void -+test_subU16_tU8_t16 (pU16_t a, pU8_t b, pU8_t c) ++typedef struct bitfield +{ -+ int i; -+ for (i = 0; i < 16; i++) -+ a[i] -= (U16_t) b[i] * (U16_t) c[i]; ++ unsigned short eight1: 8; ++ unsigned short four: 4; ++ unsigned short eight2: 8; ++ unsigned short seven: 7; ++ unsigned int sixteen: 16; ++} bitfield; ++ ++bitfield ++bfxil (bitfield a) ++{ ++ /* { dg-final { scan-assembler "bfxil\tx\[0-9\]+, x\[0-9\]+, 16, 8" } } */ ++ a.eight1 = a.eight2; ++ return a; +} + -+/* { dg-final { scan-assembler "umlsl\tv\[0-9\]+\.8h" } } */ -+/* { dg-final { scan-assembler "umlsl2\tv\[0-9\]+\.8h" } } */ ++int ++main (void) ++{ ++ static bitfield a; ++ bitfield b; + ++ a.eight1 = 9; ++ a.eight2 = 57; ++ b = bfxil (a); + -+S64_t add_rS64[4] = { 6, 7, -4, -3 }; -+S32_t add_rS32[8] = { 6, 7, -4, -3, 10, 11, 0, 1 }; -+S16_t add_rS16[16] = -+ { 6, 7, -4, -3, 10, 11, 0, 1, 14, 15, 4, 5, 18, 19, 8, 9 }; ++ if (b.eight1 != a.eight2) ++ abort (); + -+S64_t sub_rS64[4] = { 0, 1, 2, 3 }; -+S32_t sub_rS32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -+S16_t sub_rS16[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; ++ return 0; ++} + -+U64_t add_rU64[4] = { 0x6, 0x7, 0x2fffffffc, 0x2fffffffd }; ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.x +@@ -0,0 +1,37 @@ ++int v = 0; + -+U32_t add_rU32[8] = ++int ++atomic_fetch_add_CONSUME (int a) +{ -+ 0x6, 0x7, 0x2fffc, 0x2fffd, -+ 0xa, 0xb, 0x30000, 0x30001 -+}; ++ return __atomic_fetch_add (&v, a, __ATOMIC_CONSUME); ++} + -+U16_t add_rU16[16] = ++int ++atomic_fetch_sub_CONSUME (int a) +{ -+ 0x6, 0x7, 0x2fc, 0x2fd, 0xa, 0xb, 0x300, 0x301, -+ 0xe, 0xf, 0x304, 0x305, 0x12, 0x13, 0x308, 0x309 -+}; ++ return __atomic_fetch_sub (&v, a, __ATOMIC_CONSUME); ++} + -+U64_t sub_rU64[4] = { 0, 1, 2, 3 }; -+U32_t sub_rU32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -+U16_t sub_rU16[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; -+ -+S8_t neg_r[16] = { -6, -5, 8, 9, -2, -1, 12, 13, 2, 3, 16, 17, 6, 7, 20, 21 }; -+ -+S64_t S64_ta[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; -+S32_t S32_tb[16] = { 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2 }; -+S32_t S32_tc[16] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; -+ -+S32_t S32_ta[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; -+S16_t S16_tb[16] = { 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2 }; -+S16_t S16_tc[16] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; -+ -+S16_t S16_ta[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; -+S8_t S8_tb[16] = { 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2, 2, 2, -2, -2 }; -+S8_t S8_tc[16] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; -+ -+ -+#define CHECK(T,N,AS,US) \ -+do \ -+ { \ -+ for (i = 0; i < N; i++) \ -+ if (S##T##_ta[i] != AS##_r##US##T[i]) \ -+ abort (); \ -+ } \ -+while (0) -+ -+#define SCHECK(T,N,AS) CHECK(T,N,AS,S) -+#define UCHECK(T,N,AS) CHECK(T,N,AS,U) -+ -+#define NCHECK(RES) \ -+do \ -+ { \ -+ for (i = 0; i < 16; i++) \ -+ if (S16_ta[i] != RES[i]) \ -+ abort (); \ -+ } \ -+while (0) ++int ++atomic_fetch_and_CONSUME (int a) ++{ ++ return __atomic_fetch_and (&v, a, __ATOMIC_CONSUME); ++} + ++int ++atomic_fetch_nand_CONSUME (int a) ++{ ++ return __atomic_fetch_nand (&v, a, __ATOMIC_CONSUME); ++} + +int -+main () ++atomic_fetch_xor_CONSUME (int a) +{ -+ int i; -+ -+ test_addS64_tS32_t4 (S64_ta, S32_tb, S32_tc); -+ SCHECK (64, 4, add); -+ test_addS32_tS16_t8 (S32_ta, S16_tb, S16_tc); -+ SCHECK (32, 8, add); -+ test_addS16_tS8_t16 (S16_ta, S8_tb, S8_tc); -+ SCHECK (16, 16, add); -+ test_subS64_tS32_t4 (S64_ta, S32_tb, S32_tc); -+ SCHECK (64, 4, sub); -+ test_subS32_tS16_t8 (S32_ta, S16_tb, S16_tc); -+ SCHECK (32, 8, sub); -+ test_subS16_tS8_t16 (S16_ta, S8_tb, S8_tc); -+ SCHECK (16, 16, sub); -+ -+ test_addU64_tU32_t4 (S64_ta, S32_tb, S32_tc); -+ UCHECK (64, 4, add); -+ test_addU32_tU16_t8 (S32_ta, S16_tb, S16_tc); -+ UCHECK (32, 8, add); -+ test_addU16_tU8_t16 (S16_ta, S8_tb, S8_tc); -+ UCHECK (16, 16, add); -+ test_subU64_tU32_t4 (S64_ta, S32_tb, S32_tc); -+ UCHECK (64, 4, sub); -+ test_subU32_tU16_t8 (S32_ta, S16_tb, S16_tc); -+ UCHECK (32, 8, sub); -+ test_subU16_tU8_t16 (S16_ta, S8_tb, S8_tc); -+ UCHECK (16, 16, sub); -+ -+ test_addS16_tS8_t16_neg0 (S16_ta, S8_tb, S8_tc); -+ NCHECK (add_rS16); -+ test_subS16_tS8_t16_neg0 (S16_ta, S8_tb, S8_tc); -+ NCHECK (sub_rS16); -+ test_addS16_tS8_t16_neg1 (S16_ta, S8_tb, S8_tc); -+ NCHECK (add_rS16); -+ test_subS16_tS8_t16_neg1 (S16_ta, S8_tb, S8_tc); -+ NCHECK (sub_rS16); -+ test_addS16_tS8_t16_neg2 (S16_ta, S8_tb, S8_tc); -+ NCHECK (add_rS16); -+ test_subS16_tS8_t16_neg2 (S16_ta, S8_tb, S8_tc); -+ NCHECK (sub_rS16); -+ test_subS16_tS8_t16_neg3 (S16_ta, S8_tb, S8_tc); -+ NCHECK (neg_r); ++ return __atomic_fetch_xor (&v, a, __ATOMIC_CONSUME); ++} + -+ return 0; ++int ++atomic_fetch_or_CONSUME (int a) ++{ ++ return __atomic_fetch_or (&v, a, __ATOMIC_CONSUME); +} +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.c +@@ -1,43 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2" } */ + +-short v = 0; ++#include "atomic-op-short.x" + +-short +-atomic_fetch_add_RELAXED (short a) +-{ +- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); +-} +- +-short +-atomic_fetch_sub_RELAXED (short a) +-{ +- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); +-} +- +-short +-atomic_fetch_and_RELAXED (short a) +-{ +- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +-} +- +-short +-atomic_fetch_nand_RELAXED (short a) +-{ +- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +-} +- +-short +-atomic_fetch_xor_RELAXED (short a) +-{ +- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +-} +- +-short +-atomic_fetch_or_RELAXED (short a) +-{ +- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); +-} +- + /* { dg-final { scan-assembler-times "ldxrh\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ + /* { dg-final { scan-assembler-times "stxrh\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.x +@@ -0,0 +1,37 @@ ++char v = 0; + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/extr.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/extr.c -@@ -0,0 +1,34 @@ -+/* { dg-options "-O2 --save-temps" } */ -+/* { dg-do run } */ ++char ++atomic_fetch_add_RELAXED (char a) ++{ ++ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); ++} + -+extern void abort (void); ++char ++atomic_fetch_sub_RELAXED (char a) ++{ ++ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); ++} + -+int -+test_si (int a, int b) ++char ++atomic_fetch_and_RELAXED (char a) +{ -+ /* { dg-final { scan-assembler "extr\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, 27\n" } } */ -+ return (a << 5) | ((unsigned int) b >> 27); ++ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +} + -+long long -+test_di (long long a, long long b) ++char ++atomic_fetch_nand_RELAXED (char a) +{ -+ /* { dg-final { scan-assembler "extr\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, 45\n" } } */ -+ return (a << 19) | ((unsigned long long) b >> 45); ++ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +} + -+int -+main () ++char ++atomic_fetch_xor_RELAXED (char a) +{ -+ int v; -+ long long w; -+ v = test_si (0x00000004, 0x30000000); -+ if (v != 0x00000086) -+ abort(); -+ w = test_di (0x0001040040040004ll, 0x0070050066666666ll); -+ if (w != 0x2002002000200380ll) -+ abort(); -+ return 0; ++ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-compile.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-compile.c -@@ -16,5 +16,7 @@ - /* { dg-final { scan-assembler "uminv" } } */ - /* { dg-final { scan-assembler "smaxv" } } */ - /* { dg-final { scan-assembler "sminv" } } */ -+/* { dg-final { scan-assembler "sabd" } } */ -+/* { dg-final { scan-assembler "saba" } } */ - /* { dg-final { scan-assembler-times "addv" 2} } */ - /* { dg-final { scan-assembler-times "addp" 2} } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c ++char ++atomic_fetch_or_RELAXED (char a) ++{ ++ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); ++} +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c @@ -2,12 +2,13 @@ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ - #define FTYPE double -+#define ITYPE long + #define FTYPE float ++#define ITYPE int #define OP == #define INV_OP != @@ -10601,23 +9016,30 @@ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ - /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ - /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ + /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */ + /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/adds3.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/adds3.c -@@ -0,0 +1,61 @@ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fp-compile.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fp-compile.c +@@ -11,3 +11,4 @@ + /* { dg-final { scan-assembler "fdiv\\tv" } } */ + /* { dg-final { scan-assembler "fneg\\tv" } } */ + /* { dg-final { scan-assembler "fabs\\tv" } } */ ++/* { dg-final { scan-assembler "fabd\\tv" } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/adds1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/adds1.c +@@ -0,0 +1,149 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ + +extern void abort (void); -+typedef long long s64; + +int -+adds_ext (s64 a, int b, int c) ++adds_si_test1 (int a, int b, int c) +{ -+ s64 d = a + b; ++ int d = a + b; + ++ /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ + if (d == 0) + return a + c; + else @@ -10625,91 +9047,24 @@ +} + +int -+adds_shift_ext (s64 a, int b, int c) ++adds_si_test2 (int a, int b, int c) +{ -+ s64 d = (a + ((s64)b << 3)); ++ int d = a + 0xff; + ++ /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, 255" } } */ + if (d == 0) + return a + c; + else + return b + d + c; +} + -+int main () -+{ -+ int x; -+ s64 y; -+ -+ x = adds_ext (0x13000002ll, 41, 15); -+ if (x != 318767203) -+ abort (); -+ -+ x = adds_ext (0x50505050ll, 29, 4); -+ if (x != 1347440782) -+ abort (); -+ -+ x = adds_ext (0x12121212121ll, 2, 14); -+ if (x != 555819315) -+ abort (); -+ -+ x = adds_shift_ext (0x123456789ll, 4, 12); -+ if (x != 591751097) -+ abort (); -+ -+ x = adds_shift_ext (0x02020202ll, 9, 8); -+ if (x != 33686107) -+ abort (); -+ -+ x = adds_shift_ext (0x987987987987ll, 23, 41); -+ if (x != -2020050305) -+ abort (); -+ -+ return 0; -+} -+ -+/* { dg-final { scan-assembler-times "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw" 2 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/subs2.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/subs2.c -@@ -0,0 +1,155 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+ -+extern void abort (void); -+ -+int -+subs_si_test1 (int a, int b, int c) -+{ -+ int d = a - b; -+ -+ /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} -+ -+int -+subs_si_test2 (int a, int b, int c) -+{ -+ int d = a - 0xfff; -+ -+ /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, #4095" } } */ -+ /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, #4095" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} -+ +int -+subs_si_test3 (int a, int b, int c) ++adds_si_test3 (int a, int b, int c) +{ -+ int d = a - (b << 3); ++ int d = a + (b << 3); + -+ /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d <= 0) ++ /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d == 0) + return a + c; + else + return b + d + c; @@ -10718,39 +9073,36 @@ +typedef long long s64; + +s64 -+subs_di_test1 (s64 a, s64 b, s64 c) ++adds_di_test1 (s64 a, s64 b, s64 c) +{ -+ s64 d = a - b; ++ s64 d = a + b; + -+ /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ if (d <= 0) ++ /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ ++ if (d == 0) + return a + c; + else + return b + d + c; +} + +s64 -+subs_di_test2 (s64 a, s64 b, s64 c) ++adds_di_test2 (s64 a, s64 b, s64 c) +{ -+ s64 d = a - 0x1000ll; ++ s64 d = a + 0xff; + -+ /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, #4096" } } */ -+ /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, #4096" } } */ -+ if (d <= 0) ++ /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, 255" } } */ ++ if (d == 0) + return a + c; + else + return b + d + c; +} + +s64 -+subs_di_test3 (s64 a, s64 b, s64 c) ++adds_di_test3 (s64 a, s64 b, s64 c) +{ -+ s64 d = a - (b << 3); ++ s64 d = a + (b << 3); + -+ /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d <= 0) ++ /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d == 0) + return a + c; + else + return b + d + c; @@ -10761,1032 +9113,992 @@ + int x; + s64 y; + -+ x = subs_si_test1 (29, 4, 5); -+ if (x != 34) ++ x = adds_si_test1 (29, 4, 5); ++ if (x != 42) + abort (); + -+ x = subs_si_test1 (5, 2, 20); -+ if (x != 25) ++ x = adds_si_test1 (5, 2, 20); ++ if (x != 29) + abort (); + -+ x = subs_si_test2 (29, 4, 5); -+ if (x != 34) ++ x = adds_si_test2 (29, 4, 5); ++ if (x != 293) + abort (); + -+ x = subs_si_test2 (1024, 2, 20); -+ if (x != 1044) ++ x = adds_si_test2 (1024, 2, 20); ++ if (x != 1301) + abort (); + -+ x = subs_si_test3 (35, 4, 5); -+ if (x != 12) ++ x = adds_si_test3 (35, 4, 5); ++ if (x != 76) + abort (); + -+ x = subs_si_test3 (5, 2, 20); -+ if (x != 25) ++ x = adds_si_test3 (5, 2, 20); ++ if (x != 43) + abort (); + -+ y = subs_di_test1 (0x130000029ll, ++ y = adds_di_test1 (0x130000029ll, + 0x320000004ll, + 0x505050505ll); + -+ if (y != 0x63505052e) ++ if (y != 0xc75050536) + abort (); + -+ y = subs_di_test1 (0x5000500050005ll, ++ y = adds_di_test1 (0x5000500050005ll, + 0x2111211121112ll, + 0x0000000002020ll); -+ if (y != 0x5000500052025) ++ if (y != 0x9222922294249) + abort (); + -+ y = subs_di_test2 (0x130000029ll, ++ y = adds_di_test2 (0x130000029ll, + 0x320000004ll, + 0x505050505ll); -+ if (y != 0x95504f532) ++ if (y != 0x955050631) + abort (); + -+ y = subs_di_test2 (0x540004100ll, ++ y = adds_di_test2 (0x130002900ll, + 0x320000004ll, -+ 0x805050205ll); -+ if (y != 0x1065053309) ++ 0x505050505ll); ++ if (y != 0x955052f08) + abort (); + -+ y = subs_di_test3 (0x130000029ll, ++ y = adds_di_test3 (0x130000029ll, + 0x064000008ll, + 0x505050505ll); -+ if (y != 0x63505052e) ++ if (y != 0x9b9050576) + abort (); + -+ y = subs_di_test3 (0x130002900ll, ++ y = adds_di_test3 (0x130002900ll, + 0x088000008ll, + 0x505050505ll); -+ if (y != 0x635052e05) ++ if (y != 0xafd052e4d) + abort (); + + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/bics_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/bics_1.c -@@ -0,0 +1,107 @@ -+/* { dg-do run } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/insv_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/insv_1.c +@@ -0,0 +1,85 @@ ++/* { dg-do run { target aarch64*-*-* } } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ ++/* { dg-require-effective-target aarch64_little_endian } */ + +extern void abort (void); + -+int -+bics_si_test1 (int a, int b, int c) ++typedef struct bitfield +{ -+ int d = a & ~b; ++ unsigned short eight: 8; ++ unsigned short four: 4; ++ unsigned short five: 5; ++ unsigned short seven: 7; ++ unsigned int sixteen: 16; ++} bitfield; + -+ /* { dg-final { scan-assembler-times "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; ++bitfield ++bfi1 (bitfield a) ++{ ++ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 0, 8" } } */ ++ a.eight = 3; ++ return a; +} + -+int -+bics_si_test2 (int a, int b, int c) ++bitfield ++bfi2 (bitfield a) +{ -+ int d = a & ~(b << 3); -+ -+ /* { dg-final { scan-assembler "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; ++ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 16, 5" } } */ ++ a.five = 7; ++ return a; +} + -+typedef long long s64; -+ -+s64 -+bics_di_test1 (s64 a, s64 b, s64 c) ++bitfield ++movk (bitfield a) +{ -+ s64 d = a & ~b; -+ -+ /* { dg-final { scan-assembler-times "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; ++ /* { dg-final { scan-assembler "movk\tx\[0-9\]+, 0x1d6b, lsl 32" } } */ ++ a.sixteen = 7531; ++ return a; +} + -+s64 -+bics_di_test2 (s64 a, s64 b, s64 c) ++bitfield ++set1 (bitfield a) +{ -+ s64 d = a & ~(b << 3); -+ -+ /* { dg-final { scan-assembler "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; ++ /* { dg-final { scan-assembler "orr\tx\[0-9\]+, x\[0-9\]+, 2031616" } } */ ++ a.five = 0x1f; ++ return a; +} + -+int -+main () ++bitfield ++set0 (bitfield a) +{ -+ int x; -+ s64 y; -+ -+ x = bics_si_test1 (29, ~4, 5); -+ if (x != ((29 & 4) + ~4 + 5)) -+ abort (); ++ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -2031617" } } */ ++ a.five = 0; ++ return a; ++} + -+ x = bics_si_test1 (5, ~2, 20); -+ if (x != 25) -+ abort (); + -+ x = bics_si_test2 (35, ~4, 5); -+ if (x != ((35 & ~(~4 << 3)) + ~4 + 5)) -+ abort (); ++int ++main (int argc, char** argv) ++{ ++ static bitfield a; ++ bitfield b = bfi1 (a); ++ bitfield c = bfi2 (b); ++ bitfield d = movk (c); + -+ x = bics_si_test2 (96, ~2, 20); -+ if (x != 116) ++ if (d.eight != 3) + abort (); + -+ y = bics_di_test1 (0x130000029ll, -+ ~0x320000004ll, -+ 0x505050505ll); -+ -+ if (y != ((0x130000029ll & 0x320000004ll) + ~0x320000004ll + 0x505050505ll)) ++ if (d.five != 7) + abort (); + -+ y = bics_di_test1 (0x5000500050005ll, -+ ~0x2111211121112ll, -+ 0x0000000002020ll); -+ if (y != 0x5000500052025ll) ++ if (d.sixteen != 7531) + abort (); + -+ y = bics_di_test2 (0x130000029ll, -+ ~0x064000008ll, -+ 0x505050505ll); -+ if (y != ((0x130000029ll & ~(~0x064000008ll << 3)) -+ + ~0x064000008ll + 0x505050505ll)) ++ d = set1 (d); ++ if (d.five != 0x1f) + abort (); + -+ y = bics_di_test2 (0x130002900ll, -+ ~0x088000008ll, -+ 0x505050505ll); -+ if (y != (0x130002900ll + 0x505050505ll)) ++ d = set0 (d); ++ if (d.five != 0) + abort (); + + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-vmaxv.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vmaxv.c -@@ -0,0 +1,117 @@ +--- a/src/gcc/testsuite/gcc.target/aarch64/ror.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/ror.c +@@ -0,0 +1,34 @@ ++/* { dg-options "-O2 --save-temps" } */ +/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps -ffast-math" } */ -+ -+#include + +extern void abort (void); + -+#define NUM_TESTS 16 -+#define DELTA 0.000001 -+ -+int8_t input_int8[] = {1, 56, 2, -9, -90, 23, 54, 76, -+ -4, 34, 110, -110, 6, 4, 75, -34}; -+int16_t input_int16[] = {1, 56, 2, -9, -90, 23, 54, 76, -+ -4, 34, 110, -110, 6, 4, 75, -34}; -+int32_t input_int32[] = {1, 56, 2, -9, -90, 23, 54, 76, -+ -4, 34, 110, -110, 6, 4, 75, -34}; -+ -+uint8_t input_uint8[] = {1, 56, 2, 9, 90, 23, 54, 76, -+ 4, 34, 110, 110, 6, 4, 75, 34}; -+uint16_t input_uint16[] = {1, 56, 2, 9, 90, 23, 54, 76, -+ 4, 34, 110, 110, 6, 4, 75, 34}; -+uint32_t input_uint32[] = {1, 56, 2, 9, 90, 23, 54, 76, -+ 4, 34, 110, 110, 6, 4, 75, 34}; -+ -+#define EQUAL(a, b) (a == b) -+ -+#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES) \ -+int \ -+test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t (void) \ -+{ \ -+ int i, j; \ -+ int moves = (NUM_TESTS - LANES) + 1; \ -+ TYPE##_t out_l[NUM_TESTS]; \ -+ TYPE##_t out_v[NUM_TESTS]; \ -+ \ -+ /* Calculate linearly. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ out_l[i] = input_##TYPE[i]; \ -+ for (j = 0; j < LANES; j++) \ -+ out_l[i] = input_##TYPE[i + j] CMP_OP out_l[i] ? \ -+ input_##TYPE[i + j] : out_l[i]; \ -+ } \ -+ \ -+ /* Calculate using vector reduction intrinsics. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ -+ out_v[i] = v##MAXMIN##v##Q##_##SUFFIX (t1); \ -+ } \ -+ \ -+ /* Compare. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ if (!EQUAL (out_v[i], out_l[i])) \ -+ return 0; \ -+ } \ -+ return 1; \ ++int ++test_si (int a) ++{ ++ /* { dg-final { scan-assembler "ror\tw\[0-9\]+, w\[0-9\]+, 27\n" } } */ ++ return (a << 5) | ((unsigned int) a >> 27); +} + -+#define BUILD_VARIANTS(TYPE, STYPE, W32, W64) \ -+TEST (max, >, STYPE, , TYPE, W32) \ -+TEST (max, >, STYPE, q, TYPE, W64) \ -+TEST (min, <, STYPE, , TYPE, W32) \ -+TEST (min, <, STYPE, q, TYPE, W64) -+ -+BUILD_VARIANTS (int8, s8, 8, 16) -+/* { dg-final { scan-assembler "smaxv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ -+/* { dg-final { scan-assembler "sminv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ -+/* { dg-final { scan-assembler "smaxv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ -+/* { dg-final { scan-assembler "sminv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ -+BUILD_VARIANTS (uint8, u8, 8, 16) -+/* { dg-final { scan-assembler "umaxv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ -+/* { dg-final { scan-assembler "uminv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ -+/* { dg-final { scan-assembler "umaxv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ -+/* { dg-final { scan-assembler "uminv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ -+BUILD_VARIANTS (int16, s16, 4, 8) -+/* { dg-final { scan-assembler "smaxv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ -+/* { dg-final { scan-assembler "sminv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ -+/* { dg-final { scan-assembler "smaxv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ -+/* { dg-final { scan-assembler "sminv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ -+BUILD_VARIANTS (uint16, u16, 4, 8) -+/* { dg-final { scan-assembler "umaxv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ -+/* { dg-final { scan-assembler "uminv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ -+/* { dg-final { scan-assembler "umaxv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ -+/* { dg-final { scan-assembler "uminv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ -+BUILD_VARIANTS (int32, s32, 2, 4) -+/* { dg-final { scan-assembler "smaxp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "sminp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "smaxv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "sminv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+BUILD_VARIANTS (uint32, u32, 2, 4) -+/* { dg-final { scan-assembler "umaxp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "uminp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "umaxv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "uminv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+ -+#undef TEST -+#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES) \ -+{ \ -+ if (!test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t ()) \ -+ abort (); \ ++long long ++test_di (long long a) ++{ ++ /* { dg-final { scan-assembler "ror\tx\[0-9\]+, x\[0-9\]+, 45\n" } } */ ++ return (a << 19) | ((unsigned long long) a >> 45); +} + +int -+main (int argc, char **argv) ++main () +{ -+ BUILD_VARIANTS (int8, s8, 8, 16) -+ BUILD_VARIANTS (uint8, u8, 8, 16) -+ BUILD_VARIANTS (int16, s16, 4, 8) -+ BUILD_VARIANTS (uint16, u16, 4, 8) -+ BUILD_VARIANTS (int32, s32, 2, 4) -+ BUILD_VARIANTS (uint32, u32, 2, 4) ++ int v; ++ long long w; ++ v = test_si (0x0203050); ++ if (v != 0x4060a00) ++ abort(); ++ w = test_di (0x0000020506010304ll); ++ if (w != 0x1028300818200000ll) ++ abort(); + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vrecpx.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vrecpx.c -@@ -0,0 +1,54 @@ +--- a/src/gcc/testsuite/gcc.target/aarch64/ands_1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/ands_1.c +@@ -0,0 +1,151 @@ +/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps" } */ -+ -+#include -+#include -+#include ++/* { dg-options "-O2 --save-temps -fno-inline" } */ + -+float32_t in_f[] = -+{2.0, 4.0, 8.0, 16.0, 1.0, 0.5, 0.25, 0.125}; -+float32_t rec_f[] = -+{1.0, 0.5, 0.25, 0.125, 2.0, 4.0, 8.0, 16.0}; -+float64_t in_d[] = -+{2.0, 4.0, 8.0, 16.0, 1.0, 0.5, 0.25, 0.125}; -+float32_t rec_d[] = -+{1.0, 0.5, 0.25, 0.125, 2.0, 4.0, 8.0, 16.0}; ++extern void abort (void); + +int -+test_frecpx_float32_t (void) ++ands_si_test1 (int a, int b, int c) +{ -+ int i = 0; -+ int ret = 1; -+ for (i = 0; i < 8; i++) -+ ret &= fabs (vrecpxs_f32 (in_f[i]) - rec_f[i]) < 0.001; ++ int d = a & b; + -+ return ret; ++ /* { dg-final { scan-assembler-times "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "frecpx\\ts\[0-9\]+, s\[0-9\]+" } } */ -+ +int -+test_frecpx_float64_t (void) ++ands_si_test2 (int a, int b, int c) +{ -+ int i = 0; -+ int ret = 1; -+ for (i = 0; i < 8; i++) -+ ret &= fabs (vrecpxd_f64 (in_d[i]) - rec_d[i]) < 0.001; ++ int d = a & 0xff; + -+ return ret; ++ /* { dg-final { scan-assembler "ands\tw\[0-9\]+, w\[0-9\]+, 255" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { scan-assembler "frecpx\\td\[0-9\]+, d\[0-9\]+" } } */ -+ +int -+main (int argc, char **argv) ++ands_si_test3 (int a, int b, int c) +{ -+ if (!test_frecpx_float32_t ()) -+ abort (); -+ if (!test_frecpx_float64_t ()) -+ abort (); ++ int d = a & (b << 3); + -+ return 0; ++ /* { dg-final { scan-assembler "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-vca.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vca.c -@@ -0,0 +1,89 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps" } */ -+ -+#include -+ -+extern void abort (void); -+extern float fabsf (float); -+extern double fabs (double); -+ -+#define NUM_TESTS 8 ++typedef long long s64; + -+float input_s1[] = {0.1f, -0.1f, 0.4f, 10.3f, 200.0f, -800.0f, -13.0f, -0.5f}; -+float input_s2[] = {-0.2f, 0.4f, 0.04f, -100.3f, 2.0f, -80.0f, 13.0f, -0.5f}; -+double input_d1[] = {0.1, -0.1, 0.4, 10.3, 200.0, -800.0, -13.0, -0.5}; -+double input_d2[] = {-0.2, 0.4, 0.04, -100.3, 2.0, -80.0, 13.0, -0.5}; ++s64 ++ands_di_test1 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a & b; + -+#define TEST(T, CMP, SUFFIX, WIDTH, LANES, Q, F) \ -+int \ -+test_vca##T##_float##WIDTH##x##LANES##_t (void) \ -+{ \ -+ int ret = 0; \ -+ int i = 0; \ -+ uint##WIDTH##_t output[NUM_TESTS]; \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ { \ -+ float##WIDTH##_t f1 = fabs##F (input_##SUFFIX##1[i]); \ -+ float##WIDTH##_t f2 = fabs##F (input_##SUFFIX##2[i]); \ -+ /* Inhibit optimization of our linear test loop. */ \ -+ asm volatile ("" : : : "memory"); \ -+ output[i] = f1 CMP f2 ? -1 : 0; \ -+ } \ -+ \ -+ for (i = 0; i < NUM_TESTS; i += LANES) \ -+ { \ -+ float##WIDTH##x##LANES##_t in1 = \ -+ vld1##Q##_f##WIDTH (input_##SUFFIX##1 + i); \ -+ float##WIDTH##x##LANES##_t in2 = \ -+ vld1##Q##_f##WIDTH (input_##SUFFIX##2 + i); \ -+ uint##WIDTH##x##LANES##_t expected_out = \ -+ vld1##Q##_u##WIDTH (output + i); \ -+ uint##WIDTH##x##LANES##_t out = \ -+ veor##Q##_u##WIDTH (vca##T##Q##_f##WIDTH (in1, in2), \ -+ expected_out); \ -+ vst1##Q##_u##WIDTH (output + i, out); \ -+ } \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ ret |= output[i]; \ -+ \ -+ return ret; \ ++ /* { dg-final { scan-assembler-times "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+#define BUILD_VARIANTS(T, CMP) \ -+TEST (T, CMP, s, 32, 2, , f) \ -+TEST (T, CMP, s, 32, 4, q, f) \ -+TEST (T, CMP, d, 64, 2, q, ) -+ -+BUILD_VARIANTS (ge, >=) -+/* { dg-final { scan-assembler "facge\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "facge\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "facge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++s64 ++ands_di_test2 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a & 0xff; + -+BUILD_VARIANTS (gt, >) -+/* { dg-final { scan-assembler "facgt\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "facgt\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "facgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++ /* { dg-final { scan-assembler "ands\tx\[0-9\]+, x\[0-9\]+, 255" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} + -+/* No need for another scan-assembler as these tests -+ also generate facge, facgt instructions. */ -+BUILD_VARIANTS (le, <=) -+BUILD_VARIANTS (lt, <) ++s64 ++ands_di_test3 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a & (b << 3); + -+#undef TEST -+#define TEST(T, CMP, SUFFIX, WIDTH, LANES, Q, F) \ -+if (test_vca##T##_float##WIDTH##x##LANES##_t ()) \ -+ abort (); ++ /* { dg-final { scan-assembler "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} + +int -+main (int argc, char **argv) ++main () +{ -+BUILD_VARIANTS (ge, >=) -+BUILD_VARIANTS (gt, >) -+BUILD_VARIANTS (le, <=) -+BUILD_VARIANTS (lt, <) -+ return 0; -+} ++ int x; ++ s64 y; + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-vrnd.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vrnd.c -@@ -0,0 +1,117 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps" } */ ++ x = ands_si_test1 (29, 4, 5); ++ if (x != 13) ++ abort (); + -+#include ++ x = ands_si_test1 (5, 2, 20); ++ if (x != 25) ++ abort (); + -+extern void abort (void); -+extern float fabsf (float); -+extern double fabs (double); ++ x = ands_si_test2 (29, 4, 5); ++ if (x != 38) ++ abort (); + -+extern double trunc (double); -+extern double round (double); -+extern double nearbyint (double); -+extern double floor (double); -+extern double ceil (double); -+extern double rint (double); ++ x = ands_si_test2 (1024, 2, 20); ++ if (x != 1044) ++ abort (); + -+extern float truncf (float); -+extern float roundf (float); -+extern float nearbyintf (float); -+extern float floorf (float); -+extern float ceilf (float); -+extern float rintf (float); ++ x = ands_si_test3 (35, 4, 5); ++ if (x != 41) ++ abort (); + -+#define NUM_TESTS 8 -+#define DELTA 0.000001 ++ x = ands_si_test3 (5, 2, 20); ++ if (x != 25) ++ abort (); + -+float input_f32[] = {0.1f, -0.1f, 0.4f, 10.3f, -+ 200.0f, -800.0f, -13.0f, -0.5f}; -+double input_f64[] = {0.1, -0.1, 0.4, 10.3, -+ 200.0, -800.0, -13.0, -0.5}; ++ y = ands_di_test1 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); + -+#define TEST(SUFFIX, Q, WIDTH, LANES, C_FN, F) \ -+int \ -+test_vrnd##SUFFIX##_float##WIDTH##x##LANES##_t (void) \ -+{ \ -+ int ret = 1; \ -+ int i = 0; \ -+ int nlanes = LANES; \ -+ float##WIDTH##_t expected_out[NUM_TESTS]; \ -+ float##WIDTH##_t actual_out[NUM_TESTS]; \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ { \ -+ expected_out[i] = C_FN##F (input_f##WIDTH[i]); \ -+ /* Don't vectorize this. */ \ -+ asm volatile ("" : : : "memory"); \ -+ } \ -+ \ -+ /* Prevent the compiler from noticing these two loops do the same \ -+ thing and optimizing away the comparison. */ \ -+ asm volatile ("" : : : "memory"); \ -+ \ -+ for (i = 0; i < NUM_TESTS; i+=nlanes) \ -+ { \ -+ float##WIDTH##x##LANES##_t out = \ -+ vrnd##SUFFIX##Q##_f##WIDTH \ -+ (vld1##Q##_f##WIDTH (input_f##WIDTH + i)); \ -+ vst1##Q##_f##WIDTH (actual_out + i, out); \ -+ } \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ ret &= fabs##F (expected_out[i] - actual_out[i]) < DELTA; \ -+ \ -+ return ret; \ -+} \ ++ if (y != ((0x130000029ll & 0x320000004ll) + 0x320000004ll + 0x505050505ll)) ++ abort (); + ++ y = ands_di_test1 (0x5000500050005ll, ++ 0x2111211121112ll, ++ 0x0000000002020ll); ++ if (y != 0x5000500052025ll) ++ abort (); + -+#define BUILD_VARIANTS(SUFFIX, C_FN) \ -+TEST (SUFFIX, , 32, 2, C_FN, f) \ -+TEST (SUFFIX, q, 32, 4, C_FN, f) \ -+TEST (SUFFIX, q, 64, 2, C_FN, ) \ ++ y = ands_di_test2 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); ++ if (y != ((0x130000029ll & 0xff) + 0x320000004ll + 0x505050505ll)) ++ abort (); + -+BUILD_VARIANTS ( , trunc) -+/* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (a, round) -+/* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (i, nearbyint) -+/* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (m, floor) -+/* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (p, ceil) -+/* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (x, rint) -+/* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++ y = ands_di_test2 (0x130002900ll, ++ 0x320000004ll, ++ 0x505050505ll); ++ if (y != (0x130002900ll + 0x505050505ll)) ++ abort (); + -+#undef TEST -+#define TEST(SUFFIX, Q, WIDTH, LANES, C_FN, F) \ -+{ \ -+ if (!test_vrnd##SUFFIX##_float##WIDTH##x##LANES##_t ()) \ -+ abort (); \ -+} ++ y = ands_di_test3 (0x130000029ll, ++ 0x064000008ll, ++ 0x505050505ll); ++ if (y != ((0x130000029ll & (0x064000008ll << 3)) ++ + 0x064000008ll + 0x505050505ll)) ++ abort (); ++ ++ y = ands_di_test3 (0x130002900ll, ++ 0x088000008ll, ++ 0x505050505ll); ++ if (y != (0x130002900ll + 0x505050505ll)) ++ abort (); + -+int -+main (int argc, char **argv) -+{ -+ BUILD_VARIANTS ( , trunc) -+ BUILD_VARIANTS (a, round) -+ BUILD_VARIANTS (i, nearbyint) -+ BUILD_VARIANTS (m, floor) -+ BUILD_VARIANTS (p, ceil) -+ BUILD_VARIANTS (x, rint) + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.c +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.c @@ -1,43 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ -int v = 0; -+#include "atomic-op-relaxed.x" ++#include "atomic-op-release.x" -int --atomic_fetch_add_RELAXED (int a) +-atomic_fetch_add_RELEASE (int a) -{ -- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); +- return __atomic_fetch_add (&v, a, __ATOMIC_RELEASE); -} - -int --atomic_fetch_sub_RELAXED (int a) +-atomic_fetch_sub_RELEASE (int a) -{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); +- return __atomic_fetch_sub (&v, a, __ATOMIC_RELEASE); -} - -int --atomic_fetch_and_RELAXED (int a) +-atomic_fetch_and_RELEASE (int a) -{ -- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +- return __atomic_fetch_and (&v, a, __ATOMIC_RELEASE); -} - -int --atomic_fetch_nand_RELAXED (int a) +-atomic_fetch_nand_RELEASE (int a) -{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +- return __atomic_fetch_nand (&v, a, __ATOMIC_RELEASE); -} - -int --atomic_fetch_xor_RELAXED (int a) +-atomic_fetch_xor_RELEASE (int a) -{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +- return __atomic_fetch_xor (&v, a, __ATOMIC_RELEASE); -} - -int --atomic_fetch_or_RELAXED (int a) +-atomic_fetch_or_RELEASE (int a) -{ -- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); +- return __atomic_fetch_or (&v, a, __ATOMIC_RELEASE); -} - /* { dg-final { scan-assembler-times "ldxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/aes_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/aes_1.c -@@ -0,0 +1,40 @@ -+ -+/* { dg-do compile } */ -+/* { dg-options "-march=armv8-a+crypto" } */ -+ -+#include "arm_neon.h" -+ -+uint8x16_t -+test_vaeseq_u8 (uint8x16_t data, uint8x16_t key) -+{ -+ return vaeseq_u8 (data, key); -+} -+ -+/* { dg-final { scan-assembler-times "aese\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */ + /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-vfmaxv.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vfmaxv.c +@@ -0,0 +1,169 @@ ++/* { dg-do run } */ ++/* { dg-options "-O3 --save-temps -ffast-math" } */ + -+uint8x16_t -+test_vaesdq_u8 (uint8x16_t data, uint8x16_t key) -+{ -+ return vaesdq_u8 (data, key); -+} ++#include + -+/* { dg-final { scan-assembler-times "aesd\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */ ++extern void abort (void); + -+uint8x16_t -+test_vaesmcq_u8 (uint8x16_t data) -+{ -+ return vaesmcq_u8 (data); ++extern float fabsf (float); ++extern double fabs (double); ++extern int isnan (double); ++extern float fmaxf (float, float); ++extern float fminf (float, float); ++extern double fmax (double, double); ++extern double fmin (double, double); ++ ++#define NUM_TESTS 16 ++#define DELTA 0.000001 ++#define NAN (0.0 / 0.0) ++ ++float input_float32[] = {0.1f, -0.1f, 0.4f, 10.3f, ++ 200.0f, -800.0f, -13.0f, -0.5f, ++ NAN, -870.0f, 10.4f, 310.11f, ++ 0.0f, -865.0f, -2213.0f, -1.5f}; ++ ++double input_float64[] = {0.1, -0.1, 0.4, 10.3, ++ 200.0, -800.0, -13.0, -0.5, ++ NAN, -870.0, 10.4, 310.11, ++ 0.0, -865.0, -2213.0, -1.5}; ++ ++#define EQUALF(a, b) (fabsf (a - b) < DELTA) ++#define EQUALD(a, b) (fabs (a - b) < DELTA) ++ ++/* Floating point 'unordered' variants. */ ++ ++#undef TEST ++#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT) \ ++int \ ++test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t (void) \ ++{ \ ++ int i, j; \ ++ int moves = (NUM_TESTS - LANES) + 1; \ ++ TYPE##_t out_l[NUM_TESTS]; \ ++ TYPE##_t out_v[NUM_TESTS]; \ ++ \ ++ /* Calculate linearly. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ out_l[i] = input_##TYPE[i]; \ ++ for (j = 0; j < LANES; j++) \ ++ { \ ++ if (isnan (out_l[i])) \ ++ continue; \ ++ if (isnan (input_##TYPE[i + j]) \ ++ || input_##TYPE[i + j] CMP_OP out_l[i]) \ ++ out_l[i] = input_##TYPE[i + j]; \ ++ } \ ++ } \ ++ \ ++ /* Calculate using vector reduction intrinsics. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ ++ out_v[i] = v##MAXMIN##v##Q##_##SUFFIX (t1); \ ++ } \ ++ \ ++ /* Compare. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ if (!EQUAL##FLOAT (out_v[i], out_l[i]) \ ++ && !(isnan (out_v[i]) && isnan (out_l[i]))) \ ++ return 0; \ ++ } \ ++ return 1; \ ++} ++ ++#define BUILD_VARIANTS(TYPE, STYPE, W32, W64, F) \ ++TEST (max, >, STYPE, , TYPE, W32, F) \ ++TEST (max, >, STYPE, q, TYPE, W64, F) \ ++TEST (min, <, STYPE, , TYPE, W32, F) \ ++TEST (min, <, STYPE, q, TYPE, W64, F) ++ ++BUILD_VARIANTS (float32, f32, 2, 4, F) ++/* { dg-final { scan-assembler "fmaxp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fminp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fmaxv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fminv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++TEST (max, >, f64, q, float64, 2, D) ++/* { dg-final { scan-assembler "fmaxp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ ++TEST (min, <, f64, q, float64, 2, D) ++/* { dg-final { scan-assembler "fminp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ ++ ++/* Floating point 'nm' variants. */ ++ ++#undef TEST ++#define TEST(MAXMIN, F, SUFFIX, Q, TYPE, LANES, FLOAT) \ ++int \ ++test_v##MAXMIN##nmv##SUFFIX##_##TYPE##x##LANES##_t (void) \ ++{ \ ++ int i, j; \ ++ int moves = (NUM_TESTS - LANES) + 1; \ ++ TYPE##_t out_l[NUM_TESTS]; \ ++ TYPE##_t out_v[NUM_TESTS]; \ ++ \ ++ /* Calculate linearly. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ out_l[i] = input_##TYPE[i]; \ ++ for (j = 0; j < LANES; j++) \ ++ out_l[i] = f##MAXMIN##F (input_##TYPE[i + j], out_l[i]); \ ++ } \ ++ \ ++ /* Calculate using vector reduction intrinsics. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ ++ out_v[i] = v##MAXMIN##nmv##Q##_##SUFFIX (t1); \ ++ } \ ++ \ ++ /* Compare. */ \ ++ for (i = 0; i < moves; i++) \ ++ { \ ++ if (!EQUAL##FLOAT (out_v[i], out_l[i])) \ ++ return 0; \ ++ } \ ++ return 1; \ +} + -+/* { dg-final { scan-assembler-times "aesmc\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */ ++TEST (max, f, f32, , float32, 2, D) ++/* { dg-final { scan-assembler "fmaxnmp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ ++TEST (min, f, f32, , float32, 2, D) ++/* { dg-final { scan-assembler "fminnmp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ ++TEST (max, f, f32, q, float32, 4, D) ++/* { dg-final { scan-assembler "fmaxnmv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++TEST (min, f, f32, q, float32, 4, D) ++/* { dg-final { scan-assembler "fminnmv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ ++TEST (max, , f64, q, float64, 2, D) ++/* { dg-final { scan-assembler "fmaxnmp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ ++TEST (min, , f64, q, float64, 2, D) ++/* { dg-final { scan-assembler "fminnmp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ ++ ++#undef TEST ++#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT) \ ++{ \ ++ if (!test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t ()) \ ++ abort (); \ ++} + -+uint8x16_t -+test_vaesimcq_u8 (uint8x16_t data) ++int ++main (int argc, char **argv) +{ -+ return vaesimcq_u8 (data); ++ BUILD_VARIANTS (float32, f32, 2, 4, F) ++ TEST (max, >, f64, q, float64, 2, D) ++ TEST (min, <, f64, q, float64, 2, D) ++ ++#undef TEST ++#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT) \ ++{ \ ++ if (!test_v##MAXMIN##nmv##SUFFIX##_##TYPE##x##LANES##_t ()) \ ++ abort (); \ +} + -+/* { dg-final { scan-assembler-times "aesimc\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */ ++ BUILD_VARIANTS (float32, f32, 2, 4, F) ++ TEST (max, >, f64, q, float64, 2, D) ++ TEST (min, <, f64, q, float64, 2, D) + ++ return 0; ++} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm.x -@@ -13,6 +13,8 @@ - 2.0, -4.0, 8.0, -16.0, - -2.125, 4.25, -8.5, 17.0}; - -+/* Float comparisons, float results. */ -+ - void - foo (FTYPE *in1, FTYPE *in2, FTYPE *output) - { -@@ -49,11 +51,52 @@ - output[i] = (in1[i] INV_OP 0.0) ? 4.0 : 2.0; - } - -+/* Float comparisons, int results. */ +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.x +@@ -0,0 +1,37 @@ ++short v = 0; + -+void -+foo_int (FTYPE *in1, FTYPE *in2, ITYPE *output) ++short ++atomic_fetch_add_RELAXED (short a) +{ -+ int i = 0; -+ /* Vectorizable. */ -+ for (i = 0; i < N; i++) -+ output[i] = (in1[i] OP in2[i]) ? 2 : 4; ++ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); +} + -+void -+bar_int (FTYPE *in1, FTYPE *in2, ITYPE *output) ++short ++atomic_fetch_sub_RELAXED (short a) +{ -+ int i = 0; -+ /* Vectorizable. */ -+ for (i = 0; i < N; i++) -+ output[i] = (in1[i] INV_OP in2[i]) ? 4 : 2; ++ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); +} + -+void -+foobar_int (FTYPE *in1, FTYPE *in2, ITYPE *output) ++short ++atomic_fetch_and_RELAXED (short a) +{ -+ int i = 0; -+ /* Vectorizable. */ -+ for (i = 0; i < N; i++) -+ output[i] = (in1[i] OP 0.0) ? 4 : 2; ++ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); +} + -+void -+foobarbar_int (FTYPE *in1, FTYPE *in2, ITYPE *output) ++short ++atomic_fetch_nand_RELAXED (short a) +{ -+ int i = 0; -+ /* Vectorizable. */ -+ for (i = 0; i < N; i++) -+ output[i] = (in1[i] INV_OP 0.0) ? 4 : 2; ++ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); +} + - int - main (int argc, char **argv) - { - FTYPE out1[N]; - FTYPE out2[N]; -+ ITYPE outi1[N]; -+ ITYPE outi2[N]; -+ - int i = 0; - foo (input1, input2, out1); - bar (input1, input2, out2); -@@ -65,6 +108,17 @@ - for (i = 0; i < N; i++) - if (out1[i] == out2[i]) - abort (); -+ -+ foo_int (input1, input2, outi1); -+ bar_int (input1, input2, outi2); -+ for (i = 0; i < N; i++) -+ if (outi1[i] != outi2[i]) -+ abort (); -+ foobar_int (input1, input2, outi1); -+ foobarbar_int (input1, input2, outi2); -+ for (i = 0; i < N; i++) -+ if (outi1[i] == outi2[i]) -+ abort (); - return 0; - } - ---- a/src/gcc/testsuite/gcc.target/aarch64/movi_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/movi_1.c -@@ -0,0 +1,13 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O2" } */ -+ -+void -+dummy (short* b) ++short ++atomic_fetch_xor_RELAXED (short a) +{ -+ /* { dg-final { scan-assembler "movi\tv\[0-9\]+\.4h, 0x4, lsl 8" } } */ -+ /* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 0x400" } } */ -+ /* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 1024" } } */ -+ register short x asm ("h8") = 1024; -+ asm volatile ("" : : "w" (x)); -+ *b = x; ++ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); +} ---- a/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic-compile.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic-compile.c -@@ -0,0 +1,11 @@ -+ -+/* { dg-do compile } */ -+/* { dg-options "-O3" } */ -+ -+#include "arm_neon.h" + -+#include "vaddv-intrinsic.x" -+ -+/* { dg-final { scan-assembler "faddp\\ts\[0-9\]+"} } */ -+/* { dg-final { scan-assembler-times "faddp\\tv\[0-9\]+\.4s" 2} } */ -+/* { dg-final { scan-assembler "faddp\\td\[0-9\]+"} } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c -@@ -0,0 +1,101 @@ ++short ++atomic_fetch_or_RELAXED (short a) ++{ ++ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); ++} +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-vcvt.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vcvt.c +@@ -0,0 +1,132 @@ +/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps" } */ ++/* { dg-options "-O3 --save-temps -ffast-math" } */ + +#include + +extern void abort (void); ++extern double fabs (double); + -+#define ETYPE(size) int##size##_t -+#define VTYPE(size, lanes) int##size##x##lanes##_t ++#define NUM_TESTS 8 ++#define DELTA 0.000001 + -+#define TEST_VABS(q, size, lanes) \ -+static void \ -+test_vabs##q##_##size (ETYPE (size) * res, \ -+ const ETYPE (size) *in1) \ -+{ \ -+ VTYPE (size, lanes) a = vld1##q##_s##size (res); \ -+ VTYPE (size, lanes) b = vld1##q##_s##size (in1); \ -+ a = vabs##q##_s##size (b); \ -+ vst1##q##_s##size (res, a); \ -+} ++float input_f32[] = {0.1f, -0.1f, 0.4f, 10.3f, ++ 200.0f, -800.0f, -13.0f, -0.5f}; ++double input_f64[] = {0.1, -0.1, 0.4, 10.3, ++ 200.0, -800.0, -13.0, -0.5}; + -+#define BUILD_VARS(width, n_lanes, n_half_lanes) \ -+TEST_VABS (, width, n_half_lanes) \ -+TEST_VABS (q, width, n_lanes) \ ++#define TEST(SUFFIX, Q, WIDTH, LANES, S, U, D) \ ++int \ ++test_vcvt##SUFFIX##_##S##WIDTH##_f##WIDTH##x##LANES##_t (void) \ ++{ \ ++ int ret = 1; \ ++ int i = 0; \ ++ int nlanes = LANES; \ ++ U##int##WIDTH##_t expected_out[NUM_TESTS]; \ ++ U##int##WIDTH##_t actual_out[NUM_TESTS]; \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ { \ ++ expected_out[i] \ ++ = vcvt##SUFFIX##D##_##S##WIDTH##_f##WIDTH (input_f##WIDTH[i]); \ ++ /* Don't vectorize this. */ \ ++ asm volatile ("" : : : "memory"); \ ++ } \ ++ \ ++ for (i = 0; i < NUM_TESTS; i+=nlanes) \ ++ { \ ++ U##int##WIDTH##x##LANES##_t out = \ ++ vcvt##SUFFIX##Q##_##S##WIDTH##_f##WIDTH \ ++ (vld1##Q##_f##WIDTH (input_f##WIDTH + i)); \ ++ vst1##Q##_##S##WIDTH (actual_out + i, out); \ ++ } \ ++ \ ++ for (i = 0; i < NUM_TESTS; i++) \ ++ ret &= fabs (expected_out[i] - actual_out[i]) < DELTA; \ ++ \ ++ return ret; \ ++} \ + -+BUILD_VARS (64, 2, 1) -+BUILD_VARS (32, 4, 2) -+BUILD_VARS (16, 8, 4) -+BUILD_VARS (8, 16, 8) + -+#define POOL1 {-10} -+#define POOL2 {2, -10} -+#define POOL4 {0, -10, 2, -3} -+#define POOL8 {0, -10, 2, -3, 4, -50, 6, -70} -+#define POOL16 {0, -10, 2, -3, 4, -50, 6, -70, \ -+ -5, 10, -2, 3, -4, 50, -6, 70} ++#define BUILD_VARIANTS(SUFFIX) \ ++TEST (SUFFIX, , 32, 2, s, ,s) \ ++TEST (SUFFIX, q, 32, 4, s, ,s) \ ++TEST (SUFFIX, q, 64, 2, s, ,d) \ ++TEST (SUFFIX, , 32, 2, u,u,s) \ ++TEST (SUFFIX, q, 32, 4, u,u,s) \ ++TEST (SUFFIX, q, 64, 2, u,u,d) \ + -+#define EXPECTED1 {10} -+#define EXPECTED2 {2, 10} -+#define EXPECTED4 {0, 10, 2, 3} -+#define EXPECTED8 {0, 10, 2, 3, 4, 50, 6, 70} -+#define EXPECTED16 {0, 10, 2, 3, 4, 50, 6, 70, \ -+ 5, 10, 2, 3, 4, 50, 6, 70} ++BUILD_VARIANTS ( ) ++/* { dg-final { scan-assembler "fcvtzs\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtzs\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtzs\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtzs\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtzs\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "fcvtzu\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtzu\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtzu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtzu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtzu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (a) ++/* { dg-final { scan-assembler "fcvtas\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtas\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtas\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtas\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtas\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "fcvtau\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtau\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtau\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtau\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtau\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (m) ++/* { dg-final { scan-assembler "fcvtms\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtms\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtms\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtms\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtms\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "fcvtmu\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtmu\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtmu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtmu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtmu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (n) ++/* { dg-final { scan-assembler "fcvtns\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtns\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtns\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtns\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtns\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "fcvtnu\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtnu\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtnu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtnu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtnu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++BUILD_VARIANTS (p) ++/* { dg-final { scan-assembler "fcvtps\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtps\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtps\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtps\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtps\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++/* { dg-final { scan-assembler "fcvtpu\\tw\[0-9\]+, s\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtpu\\tx\[0-9\]+, d\[0-9\]+" } } */ ++/* { dg-final { scan-assembler "fcvtpu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ ++/* { dg-final { scan-assembler "fcvtpu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ ++/* { dg-final { scan-assembler "fcvtpu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ + -+#define BUILD_TEST(size, lanes_64, lanes_128) \ -+static void \ -+test_##size (void) \ -+{ \ -+ int i; \ -+ ETYPE (size) pool1[lanes_64] = POOL##lanes_64; \ -+ ETYPE (size) res1[lanes_64] = {0}; \ -+ ETYPE (size) expected1[lanes_64] = EXPECTED##lanes_64; \ -+ ETYPE (size) pool2[lanes_128] = POOL##lanes_128; \ -+ ETYPE (size) res2[lanes_128] = {0}; \ -+ ETYPE (size) expected2[lanes_128] = EXPECTED##lanes_128; \ -+ \ -+ /* Forcefully avoid optimization. */ \ -+ asm volatile ("" : : : "memory"); \ -+ test_vabs_##size (res1, pool1); \ -+ for (i = 0; i < lanes_64; i++) \ -+ if (res1[i] != expected1[i]) \ -+ abort (); \ -+ \ -+ /* Forcefully avoid optimization. */ \ -+ asm volatile ("" : : : "memory"); \ -+ test_vabsq_##size (res2, pool2); \ -+ for (i = 0; i < lanes_128; i++) \ -+ if (res2[i] != expected2[i]) \ -+ abort (); \ ++#undef TEST ++#define TEST(SUFFIX, Q, WIDTH, LANES, S, U, D) \ ++{ \ ++ if (!test_vcvt##SUFFIX##_##S##WIDTH##_f##WIDTH##x##LANES##_t ()) \ ++ abort (); \ +} + -+/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.8b, v\[0-9\]+\.8b" 1 } } */ -+/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */ -+BUILD_TEST (8 , 8, 16) -+ -+/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.4h, v\[0-9\]+\.4h" 1 } } */ -+/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h" 1 } } */ -+BUILD_TEST (16, 4, 8) -+ -+/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" 1 } } */ -+/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" 1 } } */ -+BUILD_TEST (32, 2, 4) -+ -+/* { dg-final { scan-assembler-times "abs\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" 1 } } */ -+BUILD_TEST (64, 1, 2) -+ -+#undef BUILD_TEST -+ -+#define BUILD_TEST(size) test_##size () -+ +int +main (int argc, char **argv) +{ -+ BUILD_TEST (8); -+ BUILD_TEST (16); -+ BUILD_TEST (32); -+ BUILD_TEST (64); ++ BUILD_VARIANTS ( ) ++ BUILD_VARIANTS (a) ++ BUILD_VARIANTS (m) ++ BUILD_VARIANTS (n) ++ BUILD_VARIANTS (p) + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-relaxed.x +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.x @@ -0,0 +1,37 @@ +int v = 0; + +int -+atomic_fetch_add_RELAXED (int a) ++atomic_fetch_add_RELEASE (int a) +{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); ++ return __atomic_fetch_add (&v, a, __ATOMIC_RELEASE); +} + +int -+atomic_fetch_sub_RELAXED (int a) ++atomic_fetch_sub_RELEASE (int a) +{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); ++ return __atomic_fetch_sub (&v, a, __ATOMIC_RELEASE); +} + +int -+atomic_fetch_and_RELAXED (int a) ++atomic_fetch_and_RELEASE (int a) +{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); ++ return __atomic_fetch_and (&v, a, __ATOMIC_RELEASE); +} + +int -+atomic_fetch_nand_RELAXED (int a) ++atomic_fetch_nand_RELEASE (int a) +{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); ++ return __atomic_fetch_nand (&v, a, __ATOMIC_RELEASE); +} + +int -+atomic_fetch_xor_RELAXED (int a) ++atomic_fetch_xor_RELEASE (int a) +{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); ++ return __atomic_fetch_xor (&v, a, __ATOMIC_RELEASE); +} + +int -+atomic_fetch_or_RELAXED (int a) ++atomic_fetch_or_RELEASE (int a) +{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); ++ return __atomic_fetch_or (&v, a, __ATOMIC_RELEASE); +} ---- a/src/gcc/testsuite/gcc.target/aarch64/vect.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect.c -@@ -55,6 +55,8 @@ - int smin_vector[] = {0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}; - unsigned int umax_vector[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - unsigned int umin_vector[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -+ int sabd_vector[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ int saba_vector[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int reduce_smax_value = 0; - int reduce_smin_value = -15; - unsigned int reduce_umax_value = 15; -@@ -81,6 +83,8 @@ - TEST (smin, s); - TEST (umax, u); - TEST (umin, u); -+ TEST (sabd, s); -+ TEST (saba, s); - TESTV (reduce_smax, s); - TESTV (reduce_smin, s); - TESTV (reduce_umax, u); ---- a/src/gcc/testsuite/gcc.target/aarch64/scalar-mov.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/scalar-mov.c -@@ -0,0 +1,9 @@ -+/* { dg-do compile } */ -+/* { dg-options "-g -mgeneral-regs-only" } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/fabd.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/fabd.c +@@ -0,0 +1,38 @@ ++/* { dg-do run } */ ++/* { dg-options "-O1 -fno-inline --save-temps" } */ ++ ++extern double fabs (double); ++extern float fabsf (float); ++extern void abort (); ++extern void exit (int); + +void -+foo (const char *c, ...) ++fabd_d (double x, double y, double d) +{ -+ char buf[256]; -+ buf[256 - 1] = '\0'; ++ if ((fabs (x - y) - d) > 0.00001) ++ abort (); +} ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-movi.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-movi.c -@@ -0,0 +1,74 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps -fno-inline" } */ -+ -+extern void abort (void); + -+#define N 16 ++/* { dg-final { scan-assembler "fabd\td\[0-9\]+" } } */ + -+static void -+movi_msl8 (int *__restrict a) ++void ++fabd_f (float x, float y, float d) +{ -+ int i; -+ -+ /* { dg-final { scan-assembler "movi\\tv\[0-9\]+\.4s, 0xab, msl 8" } } */ -+ for (i = 0; i < N; i++) -+ a[i] = 0xabff; ++ if ((fabsf (x - y) - d) > 0.00001) ++ abort (); +} + -+static void -+movi_msl16 (int *__restrict a) ++/* { dg-final { scan-assembler "fabd\ts\[0-9\]+" } } */ ++ ++int ++main () +{ -+ int i; ++ fabd_d (10.0, 5.0, 5.0); ++ fabd_d (5.0, 10.0, 5.0); ++ fabd_f (10.0, 5.0, 5.0); ++ fabd_f (5.0, 10.0, 5.0); + -+ /* { dg-final { scan-assembler "movi\\tv\[0-9\]+\.4s, 0xab, msl 16" } } */ -+ for (i = 0; i < N; i++) -+ a[i] = 0xabffff; ++ return 0; +} + -+static void -+mvni_msl8 (int *__restrict a) -+{ -+ int i; ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fp.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fp.c +@@ -117,6 +117,16 @@ + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0 }; + ++ F32 fabd_F32_vector[] = { 1.0f, 1.0f, 1.0f, 1.0f, ++ 1.0f, 1.0f, 1.0f, 1.0f, ++ 1.0f, 1.0f, 1.0f, 1.0f, ++ 1.0f, 1.0f, 1.0f, 1.0f }; + -+ /* { dg-final { scan-assembler "mvni\\tv\[0-9\]+\.4s, 0xab, msl 8" } } */ -+ for (i = 0; i < N; i++) -+ a[i] = 0xffff5400; ++ F64 fabd_F64_vector[] = { 1.0, 1.0, 1.0, 1.0, ++ 1.0, 1.0, 1.0, 1.0, ++ 1.0, 1.0, 1.0, 1.0, ++ 1.0, 1.0, 1.0, 1.0 }; ++ + /* Setup input vectors. */ + for (i=1; i<=16; i++) + { +@@ -132,6 +142,7 @@ + TEST (div, 3); + TEST (neg, 2); + TEST (abs, 2); ++ TEST (fabd, 3); + + return 0; + } +--- a/src/gcc/testsuite/gcc.target/aarch64/ngc.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/ngc.c +@@ -0,0 +1,66 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ ++ ++extern void abort (void); ++typedef unsigned int u32; ++ ++u32 ++ngc_si (u32 a, u32 b, u32 c, u32 d) ++{ ++ a = -b - (c < d); ++ return a; +} + -+static void -+mvni_msl16 (int *__restrict a) ++typedef unsigned long long u64; ++ ++u64 ++ngc_si_tst (u64 a, u32 b, u32 c, u32 d) +{ -+ int i; ++ a = -b - (c < d); ++ return a; ++} + -+ /* { dg-final { scan-assembler "mvni\\tv\[0-9\]+\.4s, 0xab, msl 16" } } */ -+ for (i = 0; i < N; i++) -+ a[i] = 0xff540000; ++u64 ++ngc_di (u64 a, u64 b, u64 c, u64 d) ++{ ++ a = -b - (c < d); ++ return a; +} + +int -+main (void) ++main () +{ -+ int a[N] = { 0 }; -+ int i; ++ int x; ++ u64 y; + -+#define CHECK_ARRAY(a, val) \ -+ for (i = 0; i < N; i++) \ -+ if (a[i] != val) \ -+ abort (); ++ x = ngc_si (29, 4, 5, 4); ++ if (x != -4) ++ abort (); + -+ movi_msl8 (a); -+ CHECK_ARRAY (a, 0xabff); ++ x = ngc_si (1024, 2, 20, 13); ++ if (x != -2) ++ abort (); + -+ movi_msl16 (a); -+ CHECK_ARRAY (a, 0xabffff); ++ y = ngc_si_tst (0x130000029ll, 32, 50, 12); ++ if (y != 0xffffffe0) ++ abort (); + -+ mvni_msl8 (a); -+ CHECK_ARRAY (a, 0xffff5400); ++ y = ngc_si_tst (0x5000500050005ll, 21, 2, 14); ++ if (y != 0xffffffea) ++ abort (); + -+ mvni_msl16 (a); -+ CHECK_ARRAY (a, 0xff540000); ++ y = ngc_di (0x130000029ll, 0x320000004ll, 0x505050505ll, 0x123123123ll); ++ if (y != 0xfffffffcdffffffc) ++ abort (); ++ ++ y = ngc_di (0x5000500050005ll, ++ 0x2111211121112ll, 0x0000000002020ll, 0x1414575046477ll); ++ if (y != 0xfffdeeedeeedeeed) ++ abort (); + + return 0; +} + ++/* { dg-final { scan-assembler-times "ngc\tw\[0-9\]+, w\[0-9\]+" 2 } } */ ++/* { dg-final { scan-assembler-times "ngc\tx\[0-9\]+, x\[0-9\]+" 1 } } */ +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c +--- a/src/gcc/testsuite/gcc.target/aarch64/cmp.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/cmp.c +@@ -0,0 +1,61 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2" } */ ++ ++int ++cmp_si_test1 (int a, int b, int c) ++{ ++ if (a > b) ++ return a + c; ++ else ++ return a + b + c; ++} ++ ++int ++cmp_si_test2 (int a, int b, int c) ++{ ++ if ((a >> 3) > b) ++ return a + c; ++ else ++ return a + b + c; ++} ++ ++typedef long long s64; ++ ++s64 ++cmp_di_test1 (s64 a, s64 b, s64 c) ++{ ++ if (a > b) ++ return a + c; ++ else ++ return a + b + c; ++} ++ ++s64 ++cmp_di_test2 (s64 a, s64 b, s64 c) ++{ ++ if ((a >> 3) > b) ++ return a + c; ++ else ++ return a + b + c; ++} ++ ++int ++cmp_di_test3 (int a, s64 b, s64 c) ++{ ++ if (a > b) ++ return a + c; ++ else ++ return a + b + c; ++} ++ ++int ++cmp_di_test4 (int a, s64 b, s64 c) ++{ ++ if (((s64)a << 3) > b) ++ return a + c; ++ else ++ return a + b + c; ++} ++ ++/* { dg-final { scan-assembler-times "cmp\tw\[0-9\]+, w\[0-9\]+" 2 } } */ ++/* { dg-final { scan-assembler-times "cmp\tx\[0-9\]+, x\[0-9\]+" 4 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c @@ -2,12 +2,13 @@ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ - #define FTYPE double -+#define ITYPE long + #define FTYPE float ++#define ITYPE int #define OP >= #define INV_OP < @@ -11794,382 +10106,372 @@ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ - /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ - /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ - /* { dg-final { scan-assembler "fcmlt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.c + /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */ + /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ + /* { dg-final { scan-assembler "fcmlt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/bfxil_2.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/bfxil_2.c +@@ -0,0 +1,42 @@ ++/* { dg-do run { target aarch64*-*-* } } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ ++/* { dg-require-effective-target aarch64_big_endian } */ ++ ++extern void abort (void); ++ ++typedef struct bitfield ++{ ++ unsigned short eight1: 8; ++ unsigned short four: 4; ++ unsigned short eight2: 8; ++ unsigned short seven: 7; ++ unsigned int sixteen: 16; ++ unsigned short eight3: 8; ++ unsigned short eight4: 8; ++} bitfield; ++ ++bitfield ++bfxil (bitfield a) ++{ ++ /* { dg-final { scan-assembler "bfxil\tx\[0-9\]+, x\[0-9\]+, 40, 8" } } */ ++ a.eight4 = a.eight2; ++ return a; ++} ++ ++int ++main (void) ++{ ++ static bitfield a; ++ bitfield b; ++ ++ a.eight4 = 9; ++ a.eight2 = 57; ++ b = bfxil (a); ++ ++ if (b.eight4 != a.eight2) ++ abort (); ++ ++ return 0; ++} ++ ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fp.x ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fp.x +@@ -7,13 +7,23 @@ + extern float fabsf (float); + extern double fabs (double); + ++#define DEF3a(fname, type, op) \ ++ void fname##_##type (pR##type a, \ ++ pR##type b, \ ++ pR##type c) \ ++ { \ ++ int i; \ ++ for (i = 0; i < 16; i++) \ ++ a[i] = op (b[i] - c[i]); \ ++ } ++ + #define DEF3(fname, type, op) \ + void fname##_##type (pR##type a, \ + pR##type b, \ + pR##type c) \ + { \ + int i; \ +- for (i=0; i<16; i++) \ ++ for (i = 0; i < 16; i++) \ + a[i] = b[i] op c[i]; \ + } + +@@ -22,11 +32,15 @@ + pR##type b) \ + { \ + int i; \ +- for (i=0; i<16; i++) \ ++ for (i = 0; i < 16; i++) \ + a[i] = op(b[i]); \ + } + + ++#define DEFN3a(fname, op) \ ++ DEF3a (fname, F32, op) \ ++ DEF3a (fname, F64, op) ++ + #define DEFN3(fname, op) \ + DEF3 (fname, F32, op) \ + DEF3 (fname, F64, op) +@@ -42,3 +56,5 @@ + DEFN2 (neg, -) + DEF2 (abs, F32, fabsf) + DEF2 (abs, F64, fabs) ++DEF3a (fabd, F32, fabsf) ++DEF3a (fabd, F64, fabs) +--- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.c @@ -1,43 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ -int v = 0; -+#include "atomic-op-acquire.x" ++#include "atomic-op-acq_rel.x" -int --atomic_fetch_add_ACQUIRE (int a) +-atomic_fetch_add_ACQ_REL (int a) -{ -- return __atomic_fetch_add (&v, a, __ATOMIC_ACQUIRE); +- return __atomic_fetch_add (&v, a, __ATOMIC_ACQ_REL); -} - -int --atomic_fetch_sub_ACQUIRE (int a) +-atomic_fetch_sub_ACQ_REL (int a) -{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_ACQUIRE); +- return __atomic_fetch_sub (&v, a, __ATOMIC_ACQ_REL); -} - -int --atomic_fetch_and_ACQUIRE (int a) +-atomic_fetch_and_ACQ_REL (int a) -{ -- return __atomic_fetch_and (&v, a, __ATOMIC_ACQUIRE); +- return __atomic_fetch_and (&v, a, __ATOMIC_ACQ_REL); -} - -int --atomic_fetch_nand_ACQUIRE (int a) +-atomic_fetch_nand_ACQ_REL (int a) -{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_ACQUIRE); +- return __atomic_fetch_nand (&v, a, __ATOMIC_ACQ_REL); -} - -int --atomic_fetch_xor_ACQUIRE (int a) +-atomic_fetch_xor_ACQ_REL (int a) -{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_ACQUIRE); +- return __atomic_fetch_xor (&v, a, __ATOMIC_ACQ_REL); -} - -int --atomic_fetch_or_ACQUIRE (int a) +-atomic_fetch_or_ACQ_REL (int a) -{ -- return __atomic_fetch_or (&v, a, __ATOMIC_ACQUIRE); +- return __atomic_fetch_or (&v, a, __ATOMIC_ACQ_REL); -} - /* { dg-final { scan-assembler-times "ldaxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/abs_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/abs_1.c -@@ -0,0 +1,53 @@ + /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/subs1.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/subs1.c +@@ -0,0 +1,149 @@ +/* { dg-do run } */ -+/* { dg-options "-O2 -fno-inline --save-temps" } */ ++/* { dg-options "-O2 --save-temps -fno-inline" } */ + -+extern long long llabs (long long); +extern void abort (void); + -+long long -+abs64 (long long a) ++int ++subs_si_test1 (int a, int b, int c) +{ -+ /* { dg-final { scan-assembler "eor\t" } } */ -+ /* { dg-final { scan-assembler "sub\t" } } */ -+ return llabs (a); ++ int d = a - c; ++ ++ /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + -+long long -+abs64_in_dreg (long long a) ++int ++subs_si_test2 (int a, int b, int c) +{ -+ /* { dg-final { scan-assembler "abs\td\[0-9\]+, d\[0-9\]+" } } */ -+ register long long x asm ("d8") = a; -+ register long long y asm ("d9"); -+ asm volatile ("" : : "w" (x)); -+ y = llabs (x); -+ asm volatile ("" : : "w" (y)); -+ return y; ++ int d = a - 0xff; ++ ++ /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, #255" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; +} + +int -+main (void) ++subs_si_test3 (int a, int b, int c) +{ -+ volatile long long ll0 = 0LL, ll1 = 1LL, llm1 = -1LL; ++ int d = a - (b << 3); + -+ if (abs64 (ll0) != 0LL) ++ /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} ++ ++typedef long long s64; ++ ++s64 ++subs_di_test1 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a - c; ++ ++ /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} ++ ++s64 ++subs_di_test2 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a - 0xff; ++ ++ /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, #255" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} ++ ++s64 ++subs_di_test3 (s64 a, s64 b, s64 c) ++{ ++ s64 d = a - (b << 3); ++ ++ /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ if (d == 0) ++ return a + c; ++ else ++ return b + d + c; ++} ++ ++int main () ++{ ++ int x; ++ s64 y; ++ ++ x = subs_si_test1 (29, 4, 5); ++ if (x != 33) + abort (); + -+ if (abs64 (ll1) != 1LL) ++ x = subs_si_test1 (5, 2, 20); ++ if (x != 7) + abort (); + -+ if (abs64 (llm1) != 1LL) ++ x = subs_si_test2 (29, 4, 5); ++ if (x != -217) + abort (); + -+ if (abs64_in_dreg (ll0) != 0LL) ++ x = subs_si_test2 (1024, 2, 20); ++ if (x != 791) + abort (); + -+ if (abs64_in_dreg (ll1) != 1LL) ++ x = subs_si_test3 (35, 4, 5); ++ if (x != 12) + abort (); + -+ if (abs64_in_dreg (llm1) != 1LL) ++ x = subs_si_test3 (5, 2, 20); ++ if (x != 11) + abort (); + -+ return 0; -+} ++ y = subs_di_test1 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.c -@@ -1,41 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ - --#define STRONG 0 --#define WEAK 1 --int v = 0; -+#include "atomic-comp-swap-release-acquire.x" - --int --atomic_compare_exchange_STRONG_RELEASE_ACQUIRE (int a, int b) --{ -- return __atomic_compare_exchange (&v, &a, &b, -- STRONG, __ATOMIC_RELEASE, -- __ATOMIC_ACQUIRE); --} -- --int --atomic_compare_exchange_WEAK_RELEASE_ACQUIRE (int a, int b) --{ -- return __atomic_compare_exchange (&v, &a, &b, -- WEAK, __ATOMIC_RELEASE, -- __ATOMIC_ACQUIRE); --} -- --int --atomic_compare_exchange_n_STRONG_RELEASE_ACQUIRE (int a, int b) --{ -- return __atomic_compare_exchange_n (&v, &a, b, -- STRONG, __ATOMIC_RELEASE, -- __ATOMIC_ACQUIRE); --} -- --int --atomic_compare_exchange_n_WEAK_RELEASE_ACQUIRE (int a, int b) --{ -- return __atomic_compare_exchange_n (&v, &a, b, -- WEAK, __ATOMIC_RELEASE, -- __ATOMIC_ACQUIRE); --} -- - /* { dg-final { scan-assembler-times "ldaxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 4 } } */ - /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 4 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect.x -@@ -138,3 +138,17 @@ - - return s; - } -+ -+void sabd (pRINT a, pRINT b, pRINT c) -+{ -+ int i; -+ for (i = 0; i < 16; i++) -+ c[i] = abs (a[i] - b[i]); -+} -+ -+void saba (pRINT a, pRINT b, pRINT c) -+{ -+ int i; -+ for (i = 0; i < 16; i++) -+ c[i] += abs (a[i] - b[i]); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-clz.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-clz.c -@@ -0,0 +1,35 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 -save-temps -fno-inline" } */ -+ -+extern void abort (); -+ -+void -+count_lz_v4si (unsigned *__restrict a, int *__restrict b) -+{ -+ int i; ++ if (y != 0x45000002d) ++ abort (); + -+ for (i = 0; i < 4; i++) -+ b[i] = __builtin_clz (a[i]); -+} ++ y = subs_di_test1 (0x5000500050005ll, ++ 0x2111211121112ll, ++ 0x0000000002020ll); ++ if (y != 0x7111711171117) ++ abort (); + -+/* { dg-final { scan-assembler "clz\tv\[0-9\]+\.4s" } } */ ++ y = subs_di_test2 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); ++ if (y != 0x955050433) ++ abort (); + -+int -+main () -+{ -+ unsigned int x[4] = { 0x0, 0xFFFF, 0x1FFFF, 0xFFFFFFFF }; -+ int r[4] = { 32, 16, 15, 0 }; -+ int d[4], i; ++ y = subs_di_test2 (0x130002900ll, ++ 0x320000004ll, ++ 0x505050505ll); ++ if (y != 0x955052d0a) ++ abort (); + -+ count_lz_v4si (x, d); ++ y = subs_di_test3 (0x130000029ll, ++ 0x064000008ll, ++ 0x505050505ll); ++ if (y != 0x3790504f6) ++ abort (); + -+ for (i = 0; i < 4; i++) -+ { -+ if (d[i] != r[i]) -+ abort (); -+ } ++ y = subs_di_test3 (0x130002900ll, ++ 0x088000008ll, ++ 0x505050505ll); ++ if (y != 0x27d052dcd) ++ abort (); + + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/sha256_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/sha256_1.c -@@ -0,0 +1,40 @@ -+ -+/* { dg-do compile } */ -+/* { dg-options "-march=armv8-a+crypto" } */ -+ -+#include "arm_neon.h" -+ -+uint32x4_t -+test_vsha256hq_u32 (uint32x4_t hash_abcd, uint32x4_t hash_efgh, uint32x4_t wk) -+{ -+ return vsha256hq_u32 (hash_abcd, hash_efgh, wk); -+} -+ -+/* { dg-final { scan-assembler-times "sha256h\\tq" 1 } } */ -+ -+uint32x4_t -+test_vsha256h2q_u32 (uint32x4_t hash_efgh, uint32x4_t hash_abcd, uint32x4_t wk) -+{ -+ return vsha256h2q_u32 (hash_efgh, hash_abcd, wk); -+} -+ -+/* { dg-final { scan-assembler-times "sha256h2\\tq" 1 } } */ -+ -+uint32x4_t -+test_vsha256su0q_u32 (uint32x4_t w0_3, uint32x4_t w4_7) -+{ -+ return vsha256su0q_u32 (w0_3, w4_7); -+} -+ -+/* { dg-final { scan-assembler-times "sha256su0\\tv" 1 } } */ -+ -+uint32x4_t -+test_vsha256su1q_u32 (uint32x4_t tw0_3, uint32x4_t w8_11, uint32x4_t w12_15) -+{ -+ return vsha256su1q_u32 (tw0_3, w8_11, w12_15); -+} -+ -+/* { dg-final { scan-assembler-times "sha256su1\\tv" 1 } } */ -+ -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c -@@ -2,12 +2,13 @@ - /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ - - #define FTYPE float -+#define ITYPE int - #define OP > - #define INV_OP <= - - #include "vect-fcm.x" - --/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ - /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */ - /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ - /* { dg-final { scan-assembler "fcmle\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/subs3.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/subs3.c -@@ -0,0 +1,61 @@ +--- a/src/gcc/testsuite/gcc.target/aarch64/adds2.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/adds2.c +@@ -0,0 +1,155 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ + +extern void abort (void); -+typedef long long s64; + +int -+subs_ext (s64 a, int b, int c) ++adds_si_test1 (int a, int b, int c) +{ -+ s64 d = a - b; ++ int d = a + b; + -+ if (d == 0) ++ /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ ++ if (d <= 0) + return a + c; + else + return b + d + c; +} + +int -+subs_shift_ext (s64 a, int b, int c) ++adds_si_test2 (int a, int b, int c) +{ -+ s64 d = (a - ((s64)b << 3)); ++ int d = a + 0xfff; + -+ if (d == 0) ++ /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, 4095" } } */ ++ /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, 4095" } } */ ++ if (d <= 0) + return a + c; + else + return b + d + c; +} + -+int main () -+{ -+ int x; -+ s64 y; -+ -+ x = subs_ext (0x13000002ll, 41, 15); -+ if (x != 318767121) -+ abort (); -+ -+ x = subs_ext (0x50505050ll, 29, 4); -+ if (x != 1347440724) -+ abort (); -+ -+ x = subs_ext (0x12121212121ll, 2, 14); -+ if (x != 555819311) -+ abort (); -+ -+ x = subs_shift_ext (0x123456789ll, 4, 12); -+ if (x != 591751033) -+ abort (); -+ -+ x = subs_shift_ext (0x02020202ll, 9, 8); -+ if (x != 33685963) -+ abort (); -+ -+ x = subs_shift_ext (0x987987987987ll, 23, 41); -+ if (x != -2020050673) -+ abort (); -+ -+ return 0; -+} -+ -+/* { dg-final { scan-assembler-times "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw" 2 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/bics_2.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/bics_2.c -@@ -0,0 +1,111 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+ -+extern void abort (void); -+ +int -+bics_si_test1 (int a, int b, int c) ++adds_si_test3 (int a, int b, int c) +{ -+ int d = a & ~b; ++ int d = a + (b << 3); + -+ /* { dg-final { scan-assembler-not "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler-times "bic\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ ++ /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ + if (d <= 0) + return a + c; + else + return b + d + c; +} + -+int -+bics_si_test2 (int a, int b, int c) ++typedef long long s64; ++ ++s64 ++adds_di_test1 (s64 a, s64 b, s64 c) +{ -+ int d = a & ~(b << 3); ++ s64 d = a + b; + -+ /* { dg-final { scan-assembler-not "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "bic\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ ++ /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ + if (d <= 0) + return a + c; + else + return b + d + c; +} + -+typedef long long s64; -+ +s64 -+bics_di_test1 (s64 a, s64 b, s64 c) ++adds_di_test2 (s64 a, s64 b, s64 c) +{ -+ s64 d = a & ~b; ++ s64 d = a + 0x1000ll; + -+ /* { dg-final { scan-assembler-not "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler-times "bic\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ ++ /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, 4096" } } */ ++ /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, 4096" } } */ + if (d <= 0) + return a + c; + else @@ -12177,8467 +10479,5303 @@ +} + +s64 -+bics_di_test2 (s64 a, s64 b, s64 c) ++adds_di_test3 (s64 a, s64 b, s64 c) +{ -+ s64 d = a & ~(b << 3); ++ s64 d = a + (b << 3); + -+ /* { dg-final { scan-assembler-not "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "bic\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ ++ /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ + if (d <= 0) + return a + c; + else + return b + d + c; +} + -+int -+main () ++int main () +{ + int x; + s64 y; + -+ x = bics_si_test1 (29, ~4, 5); -+ if (x != ((29 & 4) + ~4 + 5)) ++ x = adds_si_test1 (29, 4, 5); ++ if (x != 42) + abort (); + -+ x = bics_si_test1 (5, ~2, 20); -+ if (x != 25) ++ x = adds_si_test1 (5, 2, 20); ++ if (x != 29) + abort (); + -+ x = bics_si_test2 (35, ~4, 5); -+ if (x != ((35 & ~(~4 << 3)) + ~4 + 5)) ++ x = adds_si_test2 (29, 4, 5); ++ if (x != 4133) + abort (); + -+ x = bics_si_test2 (96, ~2, 20); -+ if (x != 116) ++ x = adds_si_test2 (1024, 2, 20); ++ if (x != 5141) + abort (); + -+ y = bics_di_test1 (0x130000029ll, -+ ~0x320000004ll, -+ 0x505050505ll); -+ -+ if (y != ((0x130000029ll & 0x320000004ll) + ~0x320000004ll + 0x505050505ll)) ++ x = adds_si_test3 (35, 4, 5); ++ if (x != 76) + abort (); + -+ y = bics_di_test1 (0x5000500050005ll, -+ ~0x2111211121112ll, -+ 0x0000000002020ll); -+ if (y != 0x5000500052025ll) ++ x = adds_si_test3 (5, 2, 20); ++ if (x != 43) + abort (); + -+ y = bics_di_test2 (0x130000029ll, -+ ~0x064000008ll, -+ 0x505050505ll); -+ if (y != ((0x130000029ll & ~(~0x064000008ll << 3)) -+ + ~0x064000008ll + 0x505050505ll)) -+ abort (); ++ y = adds_di_test1 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); + -+ y = bics_di_test2 (0x130002900ll, -+ ~0x088000008ll, -+ 0x505050505ll); -+ if (y != (0x130002900ll + 0x505050505ll)) ++ if (y != 0xc75050536) + abort (); + -+ return 0; -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.c -@@ -0,0 +1,28 @@ -+ -+/* { dg-do run } */ -+/* { dg-options "-O3" } */ -+ -+#include "arm_neon.h" -+ -+extern void abort (void); -+ -+#include "vaddv-intrinsic.x" ++ y = adds_di_test1 (0x5000500050005ll, ++ 0x2111211121112ll, ++ 0x0000000002020ll); ++ if (y != 0x9222922294249) ++ abort (); + -+int -+main (void) -+{ -+ const float32_t pool_v2sf[] = {4.0f, 9.0f}; -+ const float32_t pool_v4sf[] = {4.0f, 9.0f, 16.0f, 25.0f}; -+ const float64_t pool_v2df[] = {4.0, 9.0}; ++ y = adds_di_test2 (0x130000029ll, ++ 0x320000004ll, ++ 0x505050505ll); ++ if (y != 0x955051532) ++ abort (); + -+ if (test_vaddv_v2sf (pool_v2sf) != 13.0f) ++ y = adds_di_test2 (0x540004100ll, ++ 0x320000004ll, ++ 0x805050205ll); ++ if (y != 0x1065055309) + abort (); + -+ if (test_vaddv_v4sf (pool_v4sf) != 54.0f) ++ y = adds_di_test3 (0x130000029ll, ++ 0x064000008ll, ++ 0x505050505ll); ++ if (y != 0x9b9050576) + abort (); + -+ if (test_vaddv_v2df (pool_v2df) != 13.0) ++ y = adds_di_test3 (0x130002900ll, ++ 0x088000008ll, ++ 0x505050505ll); ++ if (y != 0xafd052e4d) + abort (); + + return 0; +} ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acquire.x -@@ -0,0 +1,37 @@ -+int v = 0; + -+int -+atomic_fetch_add_ACQUIRE (int a) -+{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_ACQUIRE); ++/* { dg-final { cleanup-saved-temps } } */ +--- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c ++++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c +@@ -2,12 +2,13 @@ + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ + + #define FTYPE double ++#define ITYPE long + #define OP > + #define INV_OP <= + + #include "vect-fcm.x" + +-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ ++/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ + /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ + /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ + /* { dg-final { scan-assembler "fcmle\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ +--- a/src/gcc/testsuite/lib/target-supports.exp ++++ b/src/gcc/testsuite/lib/target-supports.exp +@@ -487,13 +487,6 @@ + return 0 + } + +- # We don't yet support profiling for AArch64. +- if { [istarget aarch64*-*-*] +- && ([lindex $test_what 1] == "-p" +- || [lindex $test_what 1] == "-pg") } { +- return 0 +- } +- + # cygwin does not support -p. + if { [istarget *-*-cygwin*] && $test_what == "-p" } { + return 0 +@@ -2012,6 +2005,7 @@ + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget x86_64-*-*] ++ || [istarget aarch64*-*-*] + || ([istarget arm*-*-*] + && [check_effective_target_arm_neon_ok])} { + set et_vect_uintfloat_cvt_saved 1 +@@ -2078,6 +2072,15 @@ + }] + } + ++# Return 1 if this is a AArch64 target supporting little endian ++proc check_effective_target_aarch64_little_endian { } { ++ return [check_no_compiler_messages aarch64_little_endian assembly { ++ #if !defined(__aarch64__) || defined(__AARCH64EB__) ++ #error FOO ++ #endif ++ }] +} + -+int -+atomic_fetch_sub_ACQUIRE (int a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_ACQUIRE); -+} + # Return 1 is this is an arm target using 32-bit instructions + proc check_effective_target_arm32 { } { + return [check_no_compiler_messages arm32 assembly { +@@ -2147,22 +2150,6 @@ + } + } + +-# Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8 +-# -mfloat-abi=softfp +-proc check_effective_target_arm_v8_neon_ok {} { +- if { [check_effective_target_arm32] } { +- return [check_no_compiler_messages arm_v8_neon_ok object { +- int foo (void) +- { +- __asm__ volatile ("vrintn.f32 q0, q0"); +- return 0; +- } +- } "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"] +- } else { +- return 0 +- } +-} +- + # Return 1 if this is an ARM target supporting -mfpu=vfp + # -mfloat-abi=hard. Some multilibs may be incompatible with these + # options. +@@ -2226,7 +2213,8 @@ + if { ! [check_effective_target_arm_v8_neon_ok] } { + return "$flags" + } +- return "$flags -march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=softfp" ++ global et_arm_v8_neon_flags ++ return "$flags $et_arm_v8_neon_flags -march=armv8-a" + } + + # Add the options needed for NEON. We need either -mfloat-abi=softfp +@@ -2270,6 +2258,79 @@ + check_effective_target_arm_neon_ok_nocache] + } + ++# Return 1 if this is an ARM target supporting -mfpu=neon-fp16 ++# -mfloat-abi=softfp or equivalent options. Some multilibs may be ++# incompatible with these options. Also set et_arm_neon_flags to the ++# best options to add. + -+int -+atomic_fetch_and_ACQUIRE (int a) -+{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_ACQUIRE); -+} ++proc check_effective_target_arm_neon_fp16_ok_nocache { } { ++ global et_arm_neon_fp16_flags ++ set et_arm_neon_fp16_flags "" ++ if { [check_effective_target_arm32] } { ++ foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" ++ "-mfpu=neon-fp16 -mfloat-abi=softfp"} { ++ if { [check_no_compiler_messages_nocache arm_neon_fp_16_ok object { ++ #include "arm_neon.h" ++ float16x4_t ++ foo (float32x4_t arg) ++ { ++ return vcvt_f16_f32 (arg); ++ } ++ } "$flags"] } { ++ set et_arm_neon_fp16_flags $flags ++ return 1 ++ } ++ } ++ } + -+int -+atomic_fetch_nand_ACQUIRE (int a) -+{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_ACQUIRE); ++ return 0 +} + -+int -+atomic_fetch_xor_ACQUIRE (int a) -+{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_ACQUIRE); ++proc check_effective_target_arm_neon_fp16_ok { } { ++ return [check_cached_effective_target arm_neon_fp16_ok \ ++ check_effective_target_arm_neon_fp16_ok_nocache] +} + -+int -+atomic_fetch_or_ACQUIRE (int a) -+{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_ACQUIRE); ++proc add_options_for_arm_neon_fp16 { flags } { ++ if { ! [check_effective_target_arm_neon_fp16_ok] } { ++ return "$flags" ++ } ++ global et_arm_neon_fp16_flags ++ return "$flags $et_arm_neon_fp16_flags" +} ---- a/src/gcc/testsuite/gcc.target/aarch64/sbc.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/sbc.c -@@ -0,0 +1,41 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps" } */ -+ -+extern void abort (void); -+ -+typedef unsigned int u32int; -+typedef unsigned long long u64int; + -+u32int -+test_si (u32int w1, u32int w2, u32int w3, u32int w4) -+{ -+ u32int w0; -+ /* { dg-final { scan-assembler "sbc\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+\n" } } */ -+ w0 = w1 - w2 - (w3 < w4); -+ return w0; -+} ++# Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8 ++# -mfloat-abi=softfp or equivalent options. Some multilibs may be ++# incompatible with these options. Also set et_arm_v8_neon_flags to the ++# best options to add. + -+u64int -+test_di (u64int x1, u64int x2, u64int x3, u64int x4) -+{ -+ u64int x0; -+ /* { dg-final { scan-assembler "sbc\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+\n" } } */ -+ x0 = x1 - x2 - (x3 < x4); -+ return x0; ++proc check_effective_target_arm_v8_neon_ok_nocache { } { ++ global et_arm_v8_neon_flags ++ set et_arm_v8_neon_flags "" ++ if { [check_effective_target_arm32] } { ++ foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { ++ if { [check_no_compiler_messages_nocache arm_v8_neon_ok object { ++ #include "arm_neon.h" ++ void ++ foo () ++ { ++ __asm__ volatile ("vrintn.f32 q0, q0"); ++ } ++ } "$flags"] } { ++ set et_arm_v8_neon_flags $flags ++ return 1 ++ } ++ } ++ } ++ ++ return 0 +} + -+int -+main () -+{ -+ u32int x; -+ u64int y; -+ x = test_si (7, 8, 12, 15); -+ if (x != -2) -+ abort(); -+ y = test_di (0x987654321ll, 0x123456789ll, 0x345345345ll, 0x123123123ll); -+ if (y != 0x8641fdb98ll) -+ abort(); -+ return 0; ++proc check_effective_target_arm_v8_neon_ok { } { ++ return [check_cached_effective_target arm_v8_neon_ok \ ++ check_effective_target_arm_v8_neon_ok_nocache] +} + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/pmull_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/pmull_1.c -@@ -0,0 +1,23 @@ + # Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4 + # -mfloat-abi=softfp or equivalent options. Some multilibs may be + # incompatible with these options. Also set et_arm_neonv2_flags to the +@@ -2509,6 +2570,24 @@ + } [add_options_for_arm_neonv2 ""]] + } + ++# Return 1 if the target supports executing ARMv8 NEON instructions, 0 ++# otherwise. + -+/* { dg-do compile } */ -+/* { dg-options "-march=armv8-a+crypto" } */ ++proc check_effective_target_arm_v8_neon_hw { } { ++ return [check_runtime arm_v8_neon_hw_available { ++ #include "arm_neon.h" ++ int ++ main (void) ++ { ++ float32x2_t a; ++ asm ("vrinta.f32 %P0, %P1" ++ : "=w" (a) ++ : "0" (a)); ++ return 0; ++ } ++ } [add_options_for_arm_v8_neon ""]] ++} + -+#include "arm_neon.h" + # Return 1 if this is a ARM target with NEON enabled. + + proc check_effective_target_arm_neon { } { +@@ -4591,6 +4670,33 @@ + return 0 + } + ++# Return 1 if programs are intended to be run on hardware rather than ++# on a simulator + -+poly128_t -+test_vmull_p64 (poly64_t a, poly64_t b) -+{ -+ return vmull_p64 (a, b); -+} ++proc check_effective_target_hw { } { + -+/* { dg-final { scan-assembler-times "pmull\\tv" 1 } } */ ++ # All "src/sim" simulators set this one. ++ if [board_info target exists is_simulator] { ++ if [board_info target is_simulator] { ++ return 0 ++ } else { ++ return 1 ++ } ++ } + -+poly128_t -+test_vmull_high_p64 (poly64x2_t a, poly64x2_t b) -+{ -+ return vmull_high_p64 (a, b); ++ # The "sid" simulators don't set that one, but at least they set ++ # this one. ++ if [board_info target exists slow_simulator] { ++ if [board_info target slow_simulator] { ++ return 0 ++ } else { ++ return 1 ++ } ++ } ++ ++ return 1 +} + -+/* { dg-final { scan-assembler-times "pmull2\\tv" 1 } } */ + # Return 1 if the target is a VxWorks kernel. + + proc check_effective_target_vxworks_kernel { } { +--- a/src/gcc/testsuite/ChangeLog.linaro ++++ b/src/gcc/testsuite/ChangeLog.linaro +@@ -0,0 +1,712 @@ ++2013-11-06 Christophe Lyon + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-comp-swap-release-acquire.x -@@ -0,0 +1,36 @@ ++ Revert backport from trunk r197526. ++ 2013-04-05 Greta Yorsh + -+#define STRONG 0 -+#define WEAK 1 -+int v = 0; ++ * gcc.target/arm/negdi-1.c: New test. ++ * gcc.target/arm/negdi-2.c: Likewise. ++ * gcc.target/arm/negdi-3.c: Likewise. ++ * gcc.target/arm/negdi-4.c: Likewise. + -+int -+atomic_compare_exchange_STRONG_RELEASE_ACQUIRE (int a, int b) -+{ -+ return __atomic_compare_exchange (&v, &a, &b, -+ STRONG, __ATOMIC_RELEASE, -+ __ATOMIC_ACQUIRE); -+} ++2013-11-05 Zhenqiang Chen + -+int -+atomic_compare_exchange_WEAK_RELEASE_ACQUIRE (int a, int b) -+{ -+ return __atomic_compare_exchange (&v, &a, &b, -+ WEAK, __ATOMIC_RELEASE, -+ __ATOMIC_ACQUIRE); -+} ++ Backport from trunk r204247. ++ 2013-10-31 Zhenqiang Chen + -+int -+atomic_compare_exchange_n_STRONG_RELEASE_ACQUIRE (int a, int b) -+{ -+ return __atomic_compare_exchange_n (&v, &a, b, -+ STRONG, __ATOMIC_RELEASE, -+ __ATOMIC_ACQUIRE); -+} ++ * gcc.target/arm/lp1243022.c: New test. + -+int -+atomic_compare_exchange_n_WEAK_RELEASE_ACQUIRE (int a, int b) -+{ -+ return __atomic_compare_exchange_n (&v, &a, b, -+ WEAK, __ATOMIC_RELEASE, -+ __ATOMIC_ACQUIRE); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c -@@ -1,5 +1,5 @@ - /* { dg-do compile } */ --/* { dg-options "-O2" } */ -+/* { dg-options "-O2 -dp" } */ - - #include - -@@ -32,6 +32,18 @@ - vqaddd_s64 (a, d)); - } - -+/* { dg-final { scan-assembler-times "\\tabs\\td\[0-9\]+, d\[0-9\]+" 1 } } */ ++2013-11-04 Kugan Vivekanandarajah + -+int64x1_t -+test_vabs_s64 (int64x1_t a) -+{ -+ uint64x1_t res; -+ force_simd (a); -+ res = vabs_s64 (a); -+ force_simd (res); -+ return res; -+} ++ Backport from trunk r204336 ++ 2013-11-03 Kugan Vivekanandarajah + - /* { dg-final { scan-assembler-times "\\tcmeq\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */ - - uint64x1_t -@@ -181,7 +193,7 @@ - return res; - } - --/* { dg-final { scan-assembler-times "\\tdup\\tb\[0-9\]+, v\[0-9\]+\.b" 2 } } */ -+/* { dg-final { scan-assembler-times "aarch64_get_lanev16qi" 2 } } */ - - int8x1_t - test_vdupb_lane_s8 (int8x16_t a) -@@ -195,7 +207,7 @@ - return vdupb_lane_u8 (a, 2); - } - --/* { dg-final { scan-assembler-times "\\tdup\\th\[0-9\]+, v\[0-9\]+\.h" 2 } } */ -+/* { dg-final { scan-assembler-times "aarch64_get_lanev8hi" 2 } } */ - - int16x1_t - test_vduph_lane_s16 (int16x8_t a) -@@ -209,7 +221,7 @@ - return vduph_lane_u16 (a, 2); - } - --/* { dg-final { scan-assembler-times "\\tdup\\ts\[0-9\]+, v\[0-9\]+\.s" 2 } } */ -+/* { dg-final { scan-assembler-times "aarch64_get_lanev4si" 2 } } */ - - int32x1_t - test_vdups_lane_s32 (int32x4_t a) -@@ -223,18 +235,18 @@ - return vdups_lane_u32 (a, 2); - } - --/* { dg-final { scan-assembler-times "\\tdup\\td\[0-9\]+, v\[0-9\]+\.d" 2 } } */ -+/* { dg-final { scan-assembler-times "aarch64_get_lanev2di" 2 } } */ - - int64x1_t - test_vdupd_lane_s64 (int64x2_t a) - { -- return vdupd_lane_s64 (a, 2); -+ return vdupd_lane_s64 (a, 1); - } - - uint64x1_t - test_vdupd_lane_u64 (uint64x2_t a) - { -- return vdupd_lane_u64 (a, 2); -+ return vdupd_lane_u64 (a, 1); - } - - /* { dg-final { scan-assembler-times "\\tcmtst\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 2 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.c -@@ -1,43 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ - --int v = 0; -+#include "atomic-op-int.x" - --int --atomic_fetch_add_RELAXED (int a) --{ -- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); --} -- --int --atomic_fetch_sub_RELAXED (int a) --{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); --} -- --int --atomic_fetch_and_RELAXED (int a) --{ -- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); --} -- --int --atomic_fetch_nand_RELAXED (int a) --{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); --} -- --int --atomic_fetch_xor_RELAXED (int a) --{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); --} -- --int --atomic_fetch_or_RELAXED (int a) --{ -- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); --} -- - /* { dg-final { scan-assembler-times "ldxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/cmn-neg.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/cmn-neg.c -@@ -0,0 +1,33 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps" } */ ++ * gcc.target/arm/neon-vcond-gt.c: Scan for vbsl or vbit or vbif. ++ * gcc.target/arm/neon-vcond-ltgt.c: Scan for vbsl or vbit or vbif. ++ * gcc.target/arm/neon-vcond-unordered.c: Scan for vbsl or vbit or ++ vbif. + -+extern void abort (void); ++2013-10-15 Christophe Lyon + -+void __attribute__ ((noinline)) -+foo_s32 (int a, int b) -+{ -+ if (a < -b) -+ abort (); -+} -+/* { dg-final { scan-assembler "cmn\tw\[0-9\]" } } */ ++ GCC Linaro 4.8-2013.10 released. + -+void __attribute__ ((noinline)) -+foo_s64 (long long a, long long b) -+{ -+ if (a < -b) -+ abort (); -+} -+/* { dg-final { scan-assembler "cmn\tx\[0-9\]" } } */ ++2013-10-09 Christophe Lyon + ++ Backport from trunk r198526,200595,200597. ++ 2013-05-02 Ian Bolton + -+int -+main (void) -+{ -+ int a = 30; -+ int b = 42; -+ foo_s32 (a, b); -+ foo_s64 (a, b); -+ return 0; -+} ++ * gcc.target/aarch64/bics_1.c: New test. ++ * gcc.target/aarch64/bics_2.c: Likewise. + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.c -@@ -1,43 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ - --int v = 0; -+#include "atomic-op-seq_cst.x" - --int --atomic_fetch_add_SEQ_CST (int a) --{ -- return __atomic_fetch_add (&v, a, __ATOMIC_SEQ_CST); --} -- --int --atomic_fetch_sub_SEQ_CST (int a) --{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_SEQ_CST); --} -- --int --atomic_fetch_and_SEQ_CST (int a) --{ -- return __atomic_fetch_and (&v, a, __ATOMIC_SEQ_CST); --} -- --int --atomic_fetch_nand_SEQ_CST (int a) --{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_SEQ_CST); --} -- --int --atomic_fetch_xor_SEQ_CST (int a) --{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_SEQ_CST); --} -- --int --atomic_fetch_or_SEQ_CST (int a) --{ -- return __atomic_fetch_or (&v, a, __ATOMIC_SEQ_CST); --} -- - /* { dg-final { scan-assembler-times "ldaxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/vaddv-intrinsic.x -@@ -0,0 +1,27 @@ ++ 2013-07-02 Ian Bolton + -+float32_t -+test_vaddv_v2sf (const float32_t *pool) -+{ -+ float32x2_t val; ++ * gcc.target/aarch64/bfxil_1.c: New test. ++ * gcc.target/aarch64/bfxil_2.c: Likewise. + -+ val = vld1_f32 (pool); -+ return vaddv_f32 (val); -+} ++ 2013-07-02 Ian Bolton + -+float32_t -+test_vaddv_v4sf (const float32_t *pool) -+{ -+ float32x4_t val; ++ * gcc.target/config/aarch64/insv_1.c: Update to show it doesn't work ++ on big endian. ++ * gcc.target/config/aarch64/insv_2.c: New test for big endian. ++ * lib/target-supports.exp: Define aarch64_little_endian. + -+ val = vld1q_f32 (pool); -+ return vaddvq_f32 (val); -+} ++2013-10-03 Christophe Lyon + -+float64_t -+test_vaddv_v2df (const float64_t *pool) -+{ -+ float64x2_t val; ++ Backport from trunk r202400. ++ 2013-09-09 Kyrylo Tkachov + -+ val = vld1q_f64 (pool); -+ return vaddvq_f64 (val); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/negs.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/negs.c -@@ -0,0 +1,108 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps" } */ ++ * gcc.target/aarch64/cmn-neg.c: New test. + -+extern void abort (void); -+int z; ++2013-10-03 Christophe Lyon + -+int -+negs_si_test1 (int a, int b, int c) -+{ -+ int d = -b; ++ Backport from trunk r202164. ++ 2013-09-02 Bin Cheng + -+ /* { dg-final { scan-assembler "negs\tw\[0-9\]+, w\[0-9\]+" } } */ -+ if (d < 0) -+ return a + c; ++ * gcc.target/arm/ivopts-orig_biv-inc.c: New testcase. + -+ z = d; -+ return b + c + d; -+} ++2013-10-01 Kugan Vivekanandarajah + -+int -+negs_si_test3 (int a, int b, int c) -+{ -+ int d = -(b) << 3; ++ Backport from trunk r203059,203116. ++ 2013-10-01 Kugan Vivekanandarajah + -+ /* { dg-final { scan-assembler "negs\tw\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; ++ PR Target/58578 ++ * gcc.target/arm/pr58578.c: New test. + -+ z = d; -+ return b + c + d; -+} ++2013-09-10 Christophe Lyon + -+typedef long long s64; -+s64 zz; ++ GCC Linaro 4.8-2013.09 released. + -+s64 -+negs_di_test1 (s64 a, s64 b, s64 c) -+{ -+ s64 d = -b; ++2013-09-06 Venkataramanan Kumar + -+ /* { dg-final { scan-assembler "negs\tx\[0-9\]+, x\[0-9\]+" } } */ -+ if (d < 0) -+ return a + c; ++ Backport from trunk r201411. ++ 2013-08-01 Kyrylo Tkachov + -+ zz = d; -+ return b + c + d; -+} ++ * gcc.target/arm/pr46972-2.c: New test. + -+s64 -+negs_di_test3 (s64 a, s64 b, s64 c) -+{ -+ s64 d = -(b) << 3; ++2013-09-05 Yvan Roux + -+ /* { dg-final { scan-assembler "negs\tx\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; ++ Backport from trunk r201267. ++ 2013-07-26 Kyrylo Tkachov + -+ zz = d; -+ return b + c + d; -+} ++ * gcc.target/arm/minmax_minus.c: Scan for absence of mov. + -+int main () -+{ -+ int x; -+ s64 y; ++2013-09-05 Christophe Lyon + -+ x = negs_si_test1 (2, 12, 5); -+ if (x != 7) -+ abort (); ++ Backport from trunk r199527,199814,201435. ++ 2013-05-31 Kyrylo Tkachov + -+ x = negs_si_test1 (1, 2, 32); -+ if (x != 33) -+ abort (); ++ PR target/56315 ++ * gcc.target/arm/iordi3-opt.c: New test. + -+ x = negs_si_test3 (13, 14, 5); -+ if (x != -93) -+ abort (); ++ 2013-06-07 Kyrylo Tkachov + -+ x = negs_si_test3 (15, 21, 2); -+ if (x != -145) -+ abort (); ++ PR target/56315 ++ * gcc.target/arm/xordi3-opt.c: New test. + -+ y = negs_di_test1 (0x20202020ll, -+ 0x65161611ll, -+ 0x42434243ll); -+ if (y != 0x62636263ll) -+ abort (); ++ 2013-08-02 Kyrylo Tkachov + -+ y = negs_di_test1 (0x1010101010101ll, -+ 0x123456789abcdll, -+ 0x5555555555555ll); -+ if (y != 0x6565656565656ll) -+ abort (); ++ * gcc.target/arm/neon-for-64bits-2.c: Delete. + -+ y = negs_di_test3 (0x62523781ll, -+ 0x64234978ll, -+ 0x12345123ll); -+ if (y != 0xfffffffd553d4edbll) -+ abort (); ++2013-09-05 Christophe Lyon + -+ y = negs_di_test3 (0x763526268ll, -+ 0x101010101ll, -+ 0x222222222ll); -+ if (y != 0xfffffffb1b1b1b1bll) -+ abort (); ++ Backport from trunk r201730,201731. + -+ return 0; -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.c -@@ -1,43 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ - --int v = 0; -+#include "atomic-op-consume.x" - --int --atomic_fetch_add_CONSUME (int a) --{ -- return __atomic_fetch_add (&v, a, __ATOMIC_CONSUME); --} -- --int --atomic_fetch_sub_CONSUME (int a) --{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_CONSUME); --} -- --int --atomic_fetch_and_CONSUME (int a) --{ -- return __atomic_fetch_and (&v, a, __ATOMIC_CONSUME); --} -- --int --atomic_fetch_nand_CONSUME (int a) --{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_CONSUME); --} -- --int --atomic_fetch_xor_CONSUME (int a) --{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_CONSUME); --} -- --int --atomic_fetch_or_CONSUME (int a) --{ -- return __atomic_fetch_or (&v, a, __ATOMIC_CONSUME); --} -- - /* { dg-final { scan-assembler-times "ldxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-vaddv.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vaddv.c -@@ -0,0 +1,128 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps -ffast-math" } */ ++ 2013-08-14 Janis Johnson + -+#include ++ * gcc.target/arm/atomic-comp-swap-release-acquire.c: Move dg-do ++ to be the first test directive. ++ * gcc.target/arm/atomic-op-acq_rel.c: Likewise. ++ * gcc.target/arm/atomic-op-acquire.c: Likewise. ++ * gcc.target/arm/atomic-op-char.c: Likewise. ++ * gcc.target/arm/atomic-op-consume.c: Likewise. ++ * gcc.target/arm/atomic-op-int.c: Likewise. ++ * gcc.target/arm/atomic-op-relaxed.c: Likewise. ++ * gcc.target/arm/atomic-op-release.c: Likewise. ++ * gcc.target/arm/atomic-op-seq_cst.c: Likewise. ++ * gcc.target/arm/atomic-op-short.c: Likewise. + -+extern void abort (void); -+extern float fabsf (float); -+extern double fabs (double); ++ 2013-08-14 Janis Johnson + -+#define NUM_TESTS 16 -+#define DELTA 0.000001 ++ * gcc.target/arm/pr19599.c: Skip for -mthumb. + -+int8_t input_int8[] = {1, 56, 2, -9, -90, 23, 54, 76, -+ -4, 34, 110, -110, 6, 4, 75, -34}; -+int16_t input_int16[] = {1, 56, 2, -9, -90, 23, 54, 76, -+ -4, 34, 110, -110, 6, 4, 75, -34}; -+int32_t input_int32[] = {1, 56, 2, -9, -90, 23, 54, 76, -+ -4, 34, 110, -110, 6, 4, 75, -34}; -+int64_t input_int64[] = {1, 56, 2, -9, -90, 23, 54, 76, -+ -4, 34, 110, -110, 6, 4, 75, -34}; ++2013-09-03 Venkataramanan Kumar + -+uint8_t input_uint8[] = {1, 56, 2, 9, 90, 23, 54, 76, -+ 4, 34, 110, 110, 6, 4, 75, 34}; -+uint16_t input_uint16[] = {1, 56, 2, 9, 90, 23, 54, 76, -+ 4, 34, 110, 110, 6, 4, 75, 34}; -+uint32_t input_uint32[] = {1, 56, 2, 9, 90, 23, 54, 76, -+ 4, 34, 110, 110, 6, 4, 75, 34}; ++ Backport from trunk r201624. ++ 2013-08-09 James Greenhalgh + -+uint64_t input_uint64[] = {1, 56, 2, 9, 90, 23, 54, 76, -+ 4, 34, 110, 110, 6, 4, 75, 34}; ++ * gcc.target/aarch64/scalar_intrinsics.c: Update expected ++ output of vdup intrinsics + -+float input_float32[] = {0.1f, -0.1f, 0.4f, 10.3f, -+ 200.0f, -800.0f, -13.0f, -0.5f, -+ 7.9f, -870.0f, 10.4f, 310.11f, -+ 0.0f, -865.0f, -2213.0f, -1.5f}; ++2013-08-26 Kugan Vivekanandarajah + -+double input_float64[] = {0.1, -0.1, 0.4, 10.3, -+ 200.0, -800.0, -13.0, -0.5, -+ 7.9, -870.0, 10.4, 310.11, -+ 0.0, -865.0, -2213.0, -1.5}; ++ Backport from trunk r201636. ++ 2013-08-09 Yufeng Zhang + -+#define EQUALF(a, b) (fabsf (a - b) < DELTA) -+#define EQUALD(a, b) (fabs (a - b) < DELTA) -+#define EQUALL(a, b) (a == b) ++ * gcc.dg/lower-subreg-1.c: Skip aarch64*-*-*. + -+#define TEST(SUFFIX, Q, TYPE, LANES, FLOAT) \ -+int \ -+test_vaddv##SUFFIX##_##TYPE##x##LANES##_t (void) \ -+{ \ -+ int i, j; \ -+ int moves = (NUM_TESTS - LANES) + 1; \ -+ TYPE##_t out_l[NUM_TESTS]; \ -+ TYPE##_t out_v[NUM_TESTS]; \ -+ \ -+ /* Calculate linearly. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ out_l[i] = input_##TYPE[i]; \ -+ for (j = 1; j < LANES; j++) \ -+ out_l[i] += input_##TYPE[i + j]; \ -+ } \ -+ \ -+ /* Calculate using vector reduction intrinsics. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ -+ out_v[i] = vaddv##Q##_##SUFFIX (t1); \ -+ } \ -+ \ -+ /* Compare. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ if (!EQUAL##FLOAT (out_v[i], out_l[i])) \ -+ return 0; \ -+ } \ -+ return 1; \ -+} ++2013-08-14 Christophe Lyon + -+#define BUILD_VARIANTS(TYPE, STYPE, W32, W64, F) \ -+TEST (STYPE, , TYPE, W32, F) \ -+TEST (STYPE, q, TYPE, W64, F) \ ++ GCC Linaro 4.8-2013.08 released. + -+BUILD_VARIANTS (int8, s8, 8, 16, L) -+BUILD_VARIANTS (uint8, u8, 8, 16, L) -+/* { dg-final { scan-assembler "addv\\tb\[0-9\]+, v\[0-9\]+\.8b" } } */ -+/* { dg-final { scan-assembler "addv\\tb\[0-9\]+, v\[0-9\]+\.16b" } } */ -+BUILD_VARIANTS (int16, s16, 4, 8, L) -+BUILD_VARIANTS (uint16, u16, 4, 8, L) -+/* { dg-final { scan-assembler "addv\\th\[0-9\]+, v\[0-9\]+\.4h" } } */ -+/* { dg-final { scan-assembler "addv\\th\[0-9\]+, v\[0-9\]+\.8h" } } */ -+BUILD_VARIANTS (int32, s32, 2, 4, L) -+BUILD_VARIANTS (uint32, u32, 2, 4, L) -+/* { dg-final { scan-assembler "addp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "addv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+TEST (s64, q, int64, 2, D) -+TEST (u64, q, uint64, 2, D) -+/* { dg-final { scan-assembler "addp\\td\[0-9\]+\, v\[0-9\]+\.2d" } } */ ++2013-08-07 Christophe Lyon + -+BUILD_VARIANTS (float32, f32, 2, 4, F) -+/* { dg-final { scan-assembler "faddp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "faddp\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+TEST (f64, q, float64, 2, D) -+/* { dg-final { scan-assembler "faddp\\td\[0-9\]+\, v\[0-9\]+\.2d" } } */ ++ Backport from trunk r199720 ++ 2013-06-06 Marcus Shawcroft + -+#undef TEST -+#define TEST(SUFFIX, Q, TYPE, LANES, FLOAT) \ -+{ \ -+ if (!test_vaddv##SUFFIX##_##TYPE##x##LANES##_t ()) \ -+ abort (); \ -+} ++ * gcc.dg/vect/no-section-anchors-vect-68.c: ++ Add dg-skip-if aarch64_tiny. + -+int -+main (int argc, char **argv) -+{ -+BUILD_VARIANTS (int8, s8, 8, 16, L) -+BUILD_VARIANTS (uint8, u8, 8, 16, L) -+BUILD_VARIANTS (int16, s16, 4, 8, L) -+BUILD_VARIANTS (uint16, u16, 4, 8, L) -+BUILD_VARIANTS (int32, s32, 2, 4, L) -+BUILD_VARIANTS (uint32, u32, 2, 4, L) ++2013-08-07 Christophe Lyon + -+BUILD_VARIANTS (float32, f32, 2, 4, F) -+TEST (f64, q, float64, 2, D) ++ Backport from trunk r201237. ++ 2013-07-25 Terry Guo + -+ return 0; -+} ++ * gcc.target/arm/thumb1-Os-mult.c: New test case. + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.c -@@ -1,43 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ - --char v = 0; -+#include "atomic-op-char.x" - --char --atomic_fetch_add_RELAXED (char a) --{ -- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); --} -- --char --atomic_fetch_sub_RELAXED (char a) --{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); --} -- --char --atomic_fetch_and_RELAXED (char a) --{ -- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); --} -- --char --atomic_fetch_nand_RELAXED (char a) --{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); --} -- --char --atomic_fetch_xor_RELAXED (char a) --{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); --} -- --char --atomic_fetch_or_RELAXED (char a) --{ -- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); --} -- - /* { dg-final { scan-assembler-times "ldxrb\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stxrb\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-int.x -@@ -0,0 +1,37 @@ -+int v = 0; ++2013-08-06 Christophe Lyon + -+int -+atomic_fetch_add_RELAXED (int a) -+{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); -+} ++ Backport from trunk r200596,201067,201083. ++ 2013-07-02 Ian Bolton + -+int -+atomic_fetch_sub_RELAXED (int a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); -+} ++ * gcc.target/aarch64/abs_1.c: New test. + -+int -+atomic_fetch_and_RELAXED (int a) -+{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); -+} ++ 2013-07-19 Ian Bolton + -+int -+atomic_fetch_nand_RELAXED (int a) -+{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); -+} ++ * gcc.target/aarch64/scalar_intrinsics.c (test_vabs_s64): Added ++ new testcase. + -+int -+atomic_fetch_xor_RELAXED (int a) -+{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); -+} ++ 2013-07-20 James Greenhalgh + -+int -+atomic_fetch_or_RELAXED (int a) -+{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-seq_cst.x -@@ -0,0 +1,37 @@ -+int v = 0; ++ * gcc.target/aarch64/vabs_intrinsic_1.c: New file. + -+int -+atomic_fetch_add_SEQ_CST (int a) -+{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_SEQ_CST); -+} ++2013-08-06 Christophe Lyon + -+int -+atomic_fetch_sub_SEQ_CST (int a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_SEQ_CST); -+} ++ Backport from trunk r198864. ++ 2013-05-07 Ian Bolton + -+int -+atomic_fetch_and_SEQ_CST (int a) -+{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_SEQ_CST); -+} ++ * gcc.target/aarch64/ands_1.c: New test. ++ * gcc.target/aarch64/ands_2.c: Likewise + -+int -+atomic_fetch_nand_SEQ_CST (int a) -+{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_SEQ_CST); -+} ++2013-08-06 Christophe Lyon + -+int -+atomic_fetch_xor_SEQ_CST (int a) -+{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_SEQ_CST); -+} ++ Backport from trunk r199439,199533,201326. + -+int -+atomic_fetch_or_SEQ_CST (int a) -+{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_SEQ_CST); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/bfxil_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/bfxil_1.c -@@ -0,0 +1,40 @@ -+/* { dg-do run { target aarch64*-*-* } } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+/* { dg-require-effective-target aarch64_little_endian } */ ++ 2013-05-30 Zhenqiang Chen + -+extern void abort (void); ++ * gcc.dg/shrink-wrap-alloca.c: New added. ++ * gcc.dg/shrink-wrap-pretend.c: New added. ++ * gcc.dg/shrink-wrap-sibcall.c: New added. + -+typedef struct bitfield -+{ -+ unsigned short eight1: 8; -+ unsigned short four: 4; -+ unsigned short eight2: 8; -+ unsigned short seven: 7; -+ unsigned int sixteen: 16; -+} bitfield; ++ 2013-05-31 Rainer Orth + -+bitfield -+bfxil (bitfield a) -+{ -+ /* { dg-final { scan-assembler "bfxil\tx\[0-9\]+, x\[0-9\]+, 16, 8" } } */ -+ a.eight1 = a.eight2; -+ return a; -+} ++ * gcc.dg/shrink-wrap-alloca.c: Use __builtin_alloca. + -+int -+main (void) -+{ -+ static bitfield a; -+ bitfield b; ++ 2013-07-30 Zhenqiang Chen + -+ a.eight1 = 9; -+ a.eight2 = 57; -+ b = bfxil (a); ++ * gcc.target/arm/pr57637.c: New testcase. + -+ if (b.eight1 != a.eight2) -+ abort (); ++2013-08-06 Christophe Lyon + -+ return 0; -+} ++ Backport from trunk r198928,198973,199203,201240,201241. ++ 2013-05-15 Ramana Radhakrishnan + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-consume.x -@@ -0,0 +1,37 @@ -+int v = 0; ++ PR target/19599 ++ * gcc.target/arm/pr40887.c: Adjust testcase. ++ * gcc.target/arm/pr19599.c: New test. + -+int -+atomic_fetch_add_CONSUME (int a) -+{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_CONSUME); -+} ++2013-08-05 Yvan Roux + -+int -+atomic_fetch_sub_CONSUME (int a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_CONSUME); -+} ++ Backport from trunk r200922. ++ 2013-07-12 Tejas Belagod + -+int -+atomic_fetch_and_CONSUME (int a) -+{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_CONSUME); -+} ++ * gcc.target/aarch64/vect-movi.c: New. + -+int -+atomic_fetch_nand_CONSUME (int a) -+{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_CONSUME); -+} ++2013-08-05 Yvan Roux + -+int -+atomic_fetch_xor_CONSUME (int a) -+{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_CONSUME); -+} ++ Backport from trunk r200720. ++ 2013-07-05 Marcus Shawcroft + -+int -+atomic_fetch_or_CONSUME (int a) -+{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_CONSUME); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.c -@@ -1,43 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ - --short v = 0; -+#include "atomic-op-short.x" - --short --atomic_fetch_add_RELAXED (short a) --{ -- return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); --} -- --short --atomic_fetch_sub_RELAXED (short a) --{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); --} -- --short --atomic_fetch_and_RELAXED (short a) --{ -- return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); --} -- --short --atomic_fetch_nand_RELAXED (short a) --{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); --} -- --short --atomic_fetch_xor_RELAXED (short a) --{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); --} -- --short --atomic_fetch_or_RELAXED (short a) --{ -- return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); --} -- - /* { dg-final { scan-assembler-times "ldxrh\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stxrh\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-char.x -@@ -0,0 +1,37 @@ -+char v = 0; ++ * gcc.dg/pr57518.c: Adjust scan-rtl-dump-not pattern. + -+char -+atomic_fetch_add_RELAXED (char a) -+{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); -+} ++2013-07-21 Yvan Roux + -+char -+atomic_fetch_sub_RELAXED (char a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); -+} ++ Backport from trunk r200204. ++ 2013-06-19 Yufeng Zhang + -+char -+atomic_fetch_and_RELAXED (char a) -+{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); -+} ++ * gcc.dg/torture/stackalign/builtin-apply-2.c: set ++ STACK_ARGUMENTS_SIZE with 0 if __aarch64__ is defined. + -+char -+atomic_fetch_nand_RELAXED (char a) -+{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); -+} ++2013-07-19 Matthew Gretton-Dann + -+char -+atomic_fetch_xor_RELAXED (char a) -+{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); -+} ++ GCC Linaro 4.8-2013.07-1 released. + -+char -+atomic_fetch_or_RELAXED (char a) -+{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c -@@ -2,12 +2,13 @@ - /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ - - #define FTYPE float -+#define ITYPE int - #define OP == - #define INV_OP != - - #include "vect-fcm.x" - --/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ - /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */ - /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ - /* { dg-final { cleanup-tree-dump "vect" } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fp-compile.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fp-compile.c -@@ -11,3 +11,4 @@ - /* { dg-final { scan-assembler "fdiv\\tv" } } */ - /* { dg-final { scan-assembler "fneg\\tv" } } */ - /* { dg-final { scan-assembler "fabs\\tv" } } */ -+/* { dg-final { scan-assembler "fabd\\tv" } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/adds1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/adds1.c -@@ -0,0 +1,149 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+ -+extern void abort (void); ++2013-07-05 Christophe Lyon + -+int -+adds_si_test1 (int a, int b, int c) -+{ -+ int d = a + b; ++ GCC Linaro 4.8-2013.07 released. + -+ /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-07-03 Christophe Lyon + -+int -+adds_si_test2 (int a, int b, int c) -+{ -+ int d = a + 0xff; ++ Revert backport from trunk r198928. ++ 2013-05-15 Ramana Radhakrishnan + -+ /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, 255" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ PR target/19599 ++ * gcc.target/arm/pr40887.c: Adjust testcase. ++ * gcc.target/arm/pr19599.c: New test. + -+int -+adds_si_test3 (int a, int b, int c) -+{ -+ int d = a + (b << 3); ++2013-07-03 Christophe Lyon + -+ /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ Revert backport from trunk 199439, 199533 ++ 2013-05-31 Rainer Orth + -+typedef long long s64; ++ * gcc.dg/shrink-wrap-alloca.c: Use __builtin_alloca. + -+s64 -+adds_di_test1 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a + b; ++ 2013-05-30 Zhenqiang Chen + -+ /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ * gcc.dg/shrink-wrap-alloca.c: New added. ++ * gcc.dg/shrink-wrap-pretend.c: New added. ++ * gcc.dg/shrink-wrap-sibcall.c: New added. + -+s64 -+adds_di_test2 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a + 0xff; ++2013-07-02 Rob Savoye + -+ /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, 255" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ Backport from trunk 200096 + -+s64 -+adds_di_test3 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a + (b << 3); ++ 2013-06-14 Vidya Praveen + -+ /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ * gcc.target/aarch64/vect_smlal_1.c: New file. + -+int main () -+{ -+ int x; -+ s64 y; ++2013-07-02 Rob Savoye + -+ x = adds_si_test1 (29, 4, 5); -+ if (x != 42) -+ abort (); ++ Backport from trunk 200019 ++ 2013-06-12 Ramana Radhakrishnan + -+ x = adds_si_test1 (5, 2, 20); -+ if (x != 29) -+ abort (); ++ * gcc.target/arm/unaligned-memcpy-4.c (src, dst): Initialize ++ to ensure alignment. ++ * gcc.target/arm/unaligned-memcpy-3.c (src): Likewise. + -+ x = adds_si_test2 (29, 4, 5); -+ if (x != 293) -+ abort (); ++2013-06-20 Rob Savoye + -+ x = adds_si_test2 (1024, 2, 20); -+ if (x != 1301) -+ abort (); ++ Backport from trunk 200152 ++ 2013-06-17 Sofiane Naci + -+ x = adds_si_test3 (35, 4, 5); -+ if (x != 76) -+ abort (); ++ * gcc.target/aarch64/scalar_intrinsics.c: Update. + -+ x = adds_si_test3 (5, 2, 20); -+ if (x != 43) -+ abort (); ++2013-06-20 Rob Savoye + -+ y = adds_di_test1 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); ++ Backport from trunk 200148 ++ 2013-06-17 Kyrylo Tkachov + -+ if (y != 0xc75050536) -+ abort (); ++ * gcc.target/arm/unaligned-memcpy-2.c (dest): Initialize to ++ ensure alignment. + -+ y = adds_di_test1 (0x5000500050005ll, -+ 0x2111211121112ll, -+ 0x0000000002020ll); -+ if (y != 0x9222922294249) -+ abort (); ++2013-06-20 Rob Savoye + -+ y = adds_di_test2 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != 0x955050631) -+ abort (); ++ Backport from trunk 199533 ++ 2013-05-31 Rainer Orth + -+ y = adds_di_test2 (0x130002900ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != 0x955052f08) -+ abort (); ++ * gcc.dg/shrink-wrap-alloca.c: Use __builtin_alloca. + -+ y = adds_di_test3 (0x130000029ll, -+ 0x064000008ll, -+ 0x505050505ll); -+ if (y != 0x9b9050576) -+ abort (); ++2013-06-20 Christophe Lyon + -+ y = adds_di_test3 (0x130002900ll, -+ 0x088000008ll, -+ 0x505050505ll); -+ if (y != 0xafd052e4d) -+ abort (); ++ Backport from trunk r198683. ++ 2013-05-07 Christophe Lyon + -+ return 0; -+} ++ * lib/target-supports.exp (check_effective_target_hw): New ++ function. ++ * c-c++-common/asan/clone-test-1.c: Call ++ check_effective_target_hw. ++ * c-c++-common/asan/rlimit-mmap-test-1.c: Likewise. ++ * c-c++-common/asan/heap-overflow-1.c: Update regexps to accept ++ possible decorations. ++ * c-c++-common/asan/null-deref-1.c: Likewise. ++ * c-c++-common/asan/stack-overflow-1.c: Likewise. ++ * c-c++-common/asan/strncpy-overflow-1.c: Likewise. ++ * c-c++-common/asan/use-after-free-1.c: Likewise. ++ * g++.dg/asan/deep-thread-stack-1.C: Likewise. ++ * g++.dg/asan/large-func-test-1.C: Likewise. + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/insv_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/insv_1.c -@@ -0,0 +1,85 @@ -+/* { dg-do run { target aarch64*-*-* } } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+/* { dg-require-effective-target aarch64_little_endian } */ ++2013-06-11 Rob Savoye + -+extern void abort (void); ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+typedef struct bitfield -+{ -+ unsigned short eight: 8; -+ unsigned short four: 4; -+ unsigned short five: 5; -+ unsigned short seven: 7; -+ unsigned int sixteen: 16; -+} bitfield; ++2013-06-06 Zhenqiang Chen + -+bitfield -+bfi1 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 0, 8" } } */ -+ a.eight = 3; -+ return a; -+} ++ Backport from mainline r199439. ++ 2013-05-30 Zhenqiang Chen + -+bitfield -+bfi2 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 16, 5" } } */ -+ a.five = 7; -+ return a; -+} ++ * gcc.dg/shrink-wrap-alloca.c: New added. ++ * gcc.dg/shrink-wrap-pretend.c: New added. ++ * gcc.dg/shrink-wrap-sibcall.c: New added. + -+bitfield -+movk (bitfield a) -+{ -+ /* { dg-final { scan-assembler "movk\tx\[0-9\]+, 0x1d6b, lsl 32" } } */ -+ a.sixteen = 7531; -+ return a; -+} ++2013-06-05 Christophe Lyon + -+bitfield -+set1 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "orr\tx\[0-9\]+, x\[0-9\]+, 2031616" } } */ -+ a.five = 0x1f; -+ return a; -+} ++ Backport from trunk r199658. ++ 2013-06-04 Ian Bolton + -+bitfield -+set0 (bitfield a) -+{ -+ /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -2031617" } } */ -+ a.five = 0; -+ return a; -+} ++ * gcc.target/aarch64/movi_1.c: New test. + ++2013-06-04 Christophe Lyon + -+int -+main (int argc, char** argv) -+{ -+ static bitfield a; -+ bitfield b = bfi1 (a); -+ bitfield c = bfi2 (b); -+ bitfield d = movk (c); ++ Backport from trunk r199261. ++ 2013-05-23 Christian Bruel + -+ if (d.eight != 3) -+ abort (); ++ PR debug/57351 ++ * gcc.dg/debug/pr57351.c: New test + -+ if (d.five != 7) -+ abort (); ++2013-06-03 Christophe Lyon ++ Backport from trunk r198890,199254,199294,199454. + -+ if (d.sixteen != 7531) -+ abort (); ++ 2013-05-30 Ian Bolton + -+ d = set1 (d); -+ if (d.five != 0x1f) -+ abort (); ++ * gcc.target/aarch64/insv_1.c: New test. + -+ d = set0 (d); -+ if (d.five != 0) -+ abort (); ++ 2013-05-24 Ian Bolton + -+ return 0; -+} ++ * gcc.target/aarch64/scalar_intrinsics.c ++ (force_simd): Use a valid instruction. ++ (test_vdupd_lane_s64): Pass a valid lane argument. ++ (test_vdupd_lane_u64): Likewise. + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/ror.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/ror.c -@@ -0,0 +1,34 @@ -+/* { dg-options "-O2 --save-temps" } */ -+/* { dg-do run } */ ++ 2013-05-23 Vidya Praveen + -+extern void abort (void); ++ * gcc.target/aarch64/vect-clz.c: New file. + -+int -+test_si (int a) -+{ -+ /* { dg-final { scan-assembler "ror\tw\[0-9\]+, w\[0-9\]+, 27\n" } } */ -+ return (a << 5) | ((unsigned int) a >> 27); -+} ++ 2013-05-14 James Greenhalgh + -+long long -+test_di (long long a) -+{ -+ /* { dg-final { scan-assembler "ror\tx\[0-9\]+, x\[0-9\]+, 45\n" } } */ -+ return (a << 19) | ((unsigned long long) a >> 45); -+} ++ * gcc.target/aarch64/vect-fcm.x: Add cases testing ++ FLOAT cmp FLOAT ? INT : INT. ++ * gcc.target/aarch64/vect-fcm-eq-d.c: Define IMODE. ++ * gcc.target/aarch64/vect-fcm-eq-f.c: Likewise. ++ * gcc.target/aarch64/vect-fcm-ge-d.c: Likewise. ++ * gcc.target/aarch64/vect-fcm-ge-f.c: Likewise. ++ * gcc.target/aarch64/vect-fcm-gt-d.c: Likewise. ++ * gcc.target/aarch64/vect-fcm-gt-f.c: Likewise. + -+int -+main () -+{ -+ int v; -+ long long w; -+ v = test_si (0x0203050); -+ if (v != 0x4060a00) -+ abort(); -+ w = test_di (0x0000020506010304ll); -+ if (w != 0x1028300818200000ll) -+ abort(); -+ return 0; -+} ++2013-05-29 Christophe Lyon + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/ands_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/ands_1.c -@@ -0,0 +1,151 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ ++ Backport from trunk r198928. ++ 2013-05-15 Ramana Radhakrishnan + -+extern void abort (void); ++ PR target/19599 ++ * gcc.target/arm/pr40887.c: Adjust testcase. ++ * gcc.target/arm/pr19599.c: New test. + -+int -+ands_si_test1 (int a, int b, int c) -+{ -+ int d = a & b; ++2013-05-28 Christophe Lyon + -+ /* { dg-final { scan-assembler-times "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ Backport from trunk r198680. ++ 2013-05-07 Sofiane Naci + -+int -+ands_si_test2 (int a, int b, int c) -+{ -+ int d = a & 0xff; ++ * gcc.target/aarch64/scalar_intrinsics.c: Update. + -+ /* { dg-final { scan-assembler "ands\tw\[0-9\]+, w\[0-9\]+, 255" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-05-28 Christophe Lyon + -+int -+ands_si_test3 (int a, int b, int c) -+{ -+ int d = a & (b << 3); ++ Backport from trunk r198499-198500. ++ 2013-05-01 James Greenhalgh ++ * gcc.target/aarch64/vect-vaddv.c: New. + -+ /* { dg-final { scan-assembler "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ 2013-05-01 James Greenhalgh + -+typedef long long s64; ++ * gcc.target/aarch64/vect-vmaxv.c: New. ++ * gcc.target/aarch64/vect-vfmaxv.c: Likewise. + -+s64 -+ands_di_test1 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a & b; ++2013-05-23 Christophe Lyon + -+ /* { dg-final { scan-assembler-times "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ Backport from trunk r198970. ++ 2013-05-16 Greta Yorsh + -+s64 -+ands_di_test2 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a & 0xff; ++ * gcc.target/arm/unaligned-memcpy-2.c: Adjust expected output. ++ * gcc.target/arm/unaligned-memcpy-3.c: Likewise. ++ * gcc.target/arm/unaligned-memcpy-4.c: Likewise. + -+ /* { dg-final { scan-assembler "ands\tx\[0-9\]+, x\[0-9\]+, 255" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-05-14 Matthew Gretton-Dann + -+s64 -+ands_di_test3 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a & (b << 3); ++ GCC Linaro 4.8-2013.05 released. + -+ /* { dg-final { scan-assembler "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-05-14 Matthew Gretton-Dann + -+int -+main () -+{ -+ int x; -+ s64 y; ++ Backport from trunk r198574-198575. ++ 2013-05-03 Vidya Praveen + -+ x = ands_si_test1 (29, 4, 5); -+ if (x != 13) -+ abort (); ++ * gcc.target/aarch64/fabd.c: New file. + -+ x = ands_si_test1 (5, 2, 20); -+ if (x != 25) -+ abort (); ++2013-05-14 Matthew Gretton-Dann + -+ x = ands_si_test2 (29, 4, 5); -+ if (x != 38) -+ abort (); ++ Backport from trunk r198490-198496. ++ 2013-05-01 James Greenhalgh + -+ x = ands_si_test2 (1024, 2, 20); -+ if (x != 1044) -+ abort (); ++ * gcc.target/aarch64/scalar-vca.c: New. ++ * gcc.target/aarch64/vect-vca.c: Likewise. + -+ x = ands_si_test3 (35, 4, 5); -+ if (x != 41) -+ abort (); ++ 2013-05-01 James Greenhalgh + -+ x = ands_si_test3 (5, 2, 20); -+ if (x != 25) -+ abort (); ++ * gcc.target/aarch64/scalar_intrinsics.c (force_simd): New. ++ (test_vceqd_s64): Force arguments to SIMD registers. ++ (test_vceqzd_s64): Likewise. ++ (test_vcged_s64): Likewise. ++ (test_vcled_s64): Likewise. ++ (test_vcgezd_s64): Likewise. ++ (test_vcged_u64): Likewise. ++ (test_vcgtd_s64): Likewise. ++ (test_vcltd_s64): Likewise. ++ (test_vcgtzd_s64): Likewise. ++ (test_vcgtd_u64): Likewise. ++ (test_vclezd_s64): Likewise. ++ (test_vcltzd_s64): Likewise. ++ (test_vtst_s64): Likewise. ++ (test_vtst_u64): Likewise. + -+ y = ands_di_test1 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); ++2013-05-14 Matthew Gretton-Dann + -+ if (y != ((0x130000029ll & 0x320000004ll) + 0x320000004ll + 0x505050505ll)) -+ abort (); ++ Backport from trunk r198191. ++ 2013-04-23 Sofiane Naci + -+ y = ands_di_test1 (0x5000500050005ll, -+ 0x2111211121112ll, -+ 0x0000000002020ll); -+ if (y != 0x5000500052025ll) -+ abort (); ++ * gcc.target/aarch64/scalar-mov.c: New testcase. + -+ y = ands_di_test2 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != ((0x130000029ll & 0xff) + 0x320000004ll + 0x505050505ll)) -+ abort (); ++2013-05-14 Matthew Gretton-Dann + -+ y = ands_di_test2 (0x130002900ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != (0x130002900ll + 0x505050505ll)) -+ abort (); ++ Backport from trunk r197838. ++ 2013-04-11 Naveen H.S + -+ y = ands_di_test3 (0x130000029ll, -+ 0x064000008ll, -+ 0x505050505ll); -+ if (y != ((0x130000029ll & (0x064000008ll << 3)) -+ + 0x064000008ll + 0x505050505ll)) -+ abort (); ++ * gcc.target/aarch64/negs.c: New. + -+ y = ands_di_test3 (0x130002900ll, -+ 0x088000008ll, -+ 0x505050505ll); -+ if (y != (0x130002900ll + 0x505050505ll)) -+ abort (); ++2013-05-02 Matthew Gretton-Dann + -+ return 0; -+} ++ Backport from trunk r198019. ++ 2013-04-16 Naveen H.S + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.c -@@ -1,43 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ - --int v = 0; -+#include "atomic-op-release.x" - --int --atomic_fetch_add_RELEASE (int a) --{ -- return __atomic_fetch_add (&v, a, __ATOMIC_RELEASE); --} -- --int --atomic_fetch_sub_RELEASE (int a) --{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_RELEASE); --} -- --int --atomic_fetch_and_RELEASE (int a) --{ -- return __atomic_fetch_and (&v, a, __ATOMIC_RELEASE); --} -- --int --atomic_fetch_nand_RELEASE (int a) --{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_RELEASE); --} -- --int --atomic_fetch_xor_RELEASE (int a) --{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_RELEASE); --} -- --int --atomic_fetch_or_RELEASE (int a) --{ -- return __atomic_fetch_or (&v, a, __ATOMIC_RELEASE); --} -- - /* { dg-final { scan-assembler-times "ldxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-vfmaxv.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vfmaxv.c -@@ -0,0 +1,169 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps -ffast-math" } */ ++ * gcc.target/aarch64/adds1.c: New. ++ * gcc.target/aarch64/adds2.c: New. ++ * gcc.target/aarch64/subs1.c: New. ++ * gcc.target/aarch64/subs2.c: New. + -+#include ++2013-05-02 Matthew Gretton-Dann + -+extern void abort (void); ++ Backport from trunk r198394,198396-198400,198402-198404,198406. ++ 2013-04-29 James Greenhalgh + -+extern float fabsf (float); -+extern double fabs (double); -+extern int isnan (double); -+extern float fmaxf (float, float); -+extern float fminf (float, float); -+extern double fmax (double, double); -+extern double fmin (double, double); ++ * lib/target-supports.exp (vect_uintfloat_cvt): Enable for AArch64. + -+#define NUM_TESTS 16 -+#define DELTA 0.000001 -+#define NAN (0.0 / 0.0) ++ 2013-04-29 James Greenhalgh + -+float input_float32[] = {0.1f, -0.1f, 0.4f, 10.3f, -+ 200.0f, -800.0f, -13.0f, -0.5f, -+ NAN, -870.0f, 10.4f, 310.11f, -+ 0.0f, -865.0f, -2213.0f, -1.5f}; ++ * gcc.target/aarch64/vect-vcvt.c: New. + -+double input_float64[] = {0.1, -0.1, 0.4, 10.3, -+ 200.0, -800.0, -13.0, -0.5, -+ NAN, -870.0, 10.4, 310.11, -+ 0.0, -865.0, -2213.0, -1.5}; ++ 2013-04-29 James Greenhalgh + -+#define EQUALF(a, b) (fabsf (a - b) < DELTA) -+#define EQUALD(a, b) (fabs (a - b) < DELTA) ++ * gcc.target/aarch64/vect-vrnd.c: New. + -+/* Floating point 'unordered' variants. */ ++2013-05-02 Matthew Gretton-Dann + -+#undef TEST -+#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT) \ -+int \ -+test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t (void) \ -+{ \ -+ int i, j; \ -+ int moves = (NUM_TESTS - LANES) + 1; \ -+ TYPE##_t out_l[NUM_TESTS]; \ -+ TYPE##_t out_v[NUM_TESTS]; \ -+ \ -+ /* Calculate linearly. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ out_l[i] = input_##TYPE[i]; \ -+ for (j = 0; j < LANES; j++) \ -+ { \ -+ if (isnan (out_l[i])) \ -+ continue; \ -+ if (isnan (input_##TYPE[i + j]) \ -+ || input_##TYPE[i + j] CMP_OP out_l[i]) \ -+ out_l[i] = input_##TYPE[i + j]; \ -+ } \ -+ } \ -+ \ -+ /* Calculate using vector reduction intrinsics. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ -+ out_v[i] = v##MAXMIN##v##Q##_##SUFFIX (t1); \ -+ } \ -+ \ -+ /* Compare. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ if (!EQUAL##FLOAT (out_v[i], out_l[i]) \ -+ && !(isnan (out_v[i]) && isnan (out_l[i]))) \ -+ return 0; \ -+ } \ -+ return 1; \ -+} ++ Backport from trunk r198302-198306,198316. ++ 2013-04-25 James Greenhalgh ++ Tejas Belagod + -+#define BUILD_VARIANTS(TYPE, STYPE, W32, W64, F) \ -+TEST (max, >, STYPE, , TYPE, W32, F) \ -+TEST (max, >, STYPE, q, TYPE, W64, F) \ -+TEST (min, <, STYPE, , TYPE, W32, F) \ -+TEST (min, <, STYPE, q, TYPE, W64, F) ++ * gcc.target/aarch64/vaddv-intrinsic.c: New. ++ * gcc.target/aarch64/vaddv-intrinsic-compile.c: Likewise. ++ * gcc.target/aarch64/vaddv-intrinsic.x: Likewise. + -+BUILD_VARIANTS (float32, f32, 2, 4, F) -+/* { dg-final { scan-assembler "fmaxp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fminp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fmaxv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fminv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+TEST (max, >, f64, q, float64, 2, D) -+/* { dg-final { scan-assembler "fmaxp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ -+TEST (min, <, f64, q, float64, 2, D) -+/* { dg-final { scan-assembler "fminp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ ++ 2013-04-25 Naveen H.S + -+/* Floating point 'nm' variants. */ ++ * gcc.target/aarch64/cmp.c: New. + -+#undef TEST -+#define TEST(MAXMIN, F, SUFFIX, Q, TYPE, LANES, FLOAT) \ -+int \ -+test_v##MAXMIN##nmv##SUFFIX##_##TYPE##x##LANES##_t (void) \ -+{ \ -+ int i, j; \ -+ int moves = (NUM_TESTS - LANES) + 1; \ -+ TYPE##_t out_l[NUM_TESTS]; \ -+ TYPE##_t out_v[NUM_TESTS]; \ -+ \ -+ /* Calculate linearly. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ out_l[i] = input_##TYPE[i]; \ -+ for (j = 0; j < LANES; j++) \ -+ out_l[i] = f##MAXMIN##F (input_##TYPE[i + j], out_l[i]); \ -+ } \ -+ \ -+ /* Calculate using vector reduction intrinsics. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i); \ -+ out_v[i] = v##MAXMIN##nmv##Q##_##SUFFIX (t1); \ -+ } \ -+ \ -+ /* Compare. */ \ -+ for (i = 0; i < moves; i++) \ -+ { \ -+ if (!EQUAL##FLOAT (out_v[i], out_l[i])) \ -+ return 0; \ -+ } \ -+ return 1; \ -+} ++ 2013-04-25 Naveen H.S + -+TEST (max, f, f32, , float32, 2, D) -+/* { dg-final { scan-assembler "fmaxnmp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ -+TEST (min, f, f32, , float32, 2, D) -+/* { dg-final { scan-assembler "fminnmp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */ -+TEST (max, f, f32, q, float32, 4, D) -+/* { dg-final { scan-assembler "fmaxnmv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+TEST (min, f, f32, q, float32, 4, D) -+/* { dg-final { scan-assembler "fminnmv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */ -+TEST (max, , f64, q, float64, 2, D) -+/* { dg-final { scan-assembler "fmaxnmp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ -+TEST (min, , f64, q, float64, 2, D) -+/* { dg-final { scan-assembler "fminnmp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */ ++ * gcc.target/aarch64/ngc.c: New. + -+#undef TEST -+#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT) \ -+{ \ -+ if (!test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t ()) \ -+ abort (); \ -+} ++2013-05-02 Matthew Gretton-Dann + -+int -+main (int argc, char **argv) -+{ -+ BUILD_VARIANTS (float32, f32, 2, 4, F) -+ TEST (max, >, f64, q, float64, 2, D) -+ TEST (min, <, f64, q, float64, 2, D) ++ Backport from trunk r198298. ++ 2013-04-25 Kyrylo Tkachov + -+#undef TEST -+#define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT) \ -+{ \ -+ if (!test_v##MAXMIN##nmv##SUFFIX##_##TYPE##x##LANES##_t ()) \ -+ abort (); \ -+} ++ * lib/target-supports.exp ++ (check_effective_target_arm_neon_fp16_ok_nocache): New procedure. ++ (check_effective_target_arm_neon_fp16_ok): Likewise. ++ (add_options_for_arm_neon_fp16): Likewise. ++ * gcc.target/arm/neon/vcvtf16_f32.c: New test. Generated. ++ * gcc.target/arm/neon/vcvtf32_f16.c: Likewise. + -+ BUILD_VARIANTS (float32, f32, 2, 4, F) -+ TEST (max, >, f64, q, float64, 2, D) -+ TEST (min, <, f64, q, float64, 2, D) ++2013-05-02 Matthew Gretton-Dann + -+ return 0; -+} ++ Backport from trunk r198136-198137,198142,198176 ++ 2013-04-22 James Greenhalgh + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-short.x -@@ -0,0 +1,37 @@ -+short v = 0; ++ * gcc.target/aarch64/vrecps.c: New. ++ * gcc.target/aarch64/vrecpx.c: Likewise. + -+short -+atomic_fetch_add_RELAXED (short a) -+{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_RELAXED); -+} ++2013-05-02 Matthew Gretton-Dann + -+short -+atomic_fetch_sub_RELAXED (short a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_RELAXED); -+} ++ Backport from trunk r198020. ++ 2013-04-16 Naveen H.S + -+short -+atomic_fetch_and_RELAXED (short a) -+{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_RELAXED); -+} ++ * gcc.target/aarch64/adds3.c: New. ++ * gcc.target/aarch64/subs3.c: New. + -+short -+atomic_fetch_nand_RELAXED (short a) -+{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_RELAXED); -+} ++2013-05-02 Matthew Gretton-Dann + -+short -+atomic_fetch_xor_RELAXED (short a) -+{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_RELAXED); -+} ++ Backport from trunk r197965. ++ 2013-04-15 Kyrylo Tkachov + -+short -+atomic_fetch_or_RELAXED (short a) -+{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_RELAXED); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-vcvt.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-vcvt.c -@@ -0,0 +1,132 @@ -+/* { dg-do run } */ -+/* { dg-options "-O3 --save-temps -ffast-math" } */ ++ * gcc.target/arm/anddi3-opt.c: New test. ++ * gcc.target/arm/anddi3-opt2.c: Likewise. + -+#include ++2013-05-02 Matthew Gretton-Dann + -+extern void abort (void); -+extern double fabs (double); ++ Backport from trunk r197642. ++ 2013-04-09 Kyrylo Tkachov + -+#define NUM_TESTS 8 -+#define DELTA 0.000001 ++ * gcc.target/arm/minmax_minus.c: New test. + -+float input_f32[] = {0.1f, -0.1f, 0.4f, 10.3f, -+ 200.0f, -800.0f, -13.0f, -0.5f}; -+double input_f64[] = {0.1, -0.1, 0.4, 10.3, -+ 200.0, -800.0, -13.0, -0.5}; ++2013-05-02 Matthew Gretton-Dann + -+#define TEST(SUFFIX, Q, WIDTH, LANES, S, U, D) \ -+int \ -+test_vcvt##SUFFIX##_##S##WIDTH##_f##WIDTH##x##LANES##_t (void) \ -+{ \ -+ int ret = 1; \ -+ int i = 0; \ -+ int nlanes = LANES; \ -+ U##int##WIDTH##_t expected_out[NUM_TESTS]; \ -+ U##int##WIDTH##_t actual_out[NUM_TESTS]; \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ { \ -+ expected_out[i] \ -+ = vcvt##SUFFIX##D##_##S##WIDTH##_f##WIDTH (input_f##WIDTH[i]); \ -+ /* Don't vectorize this. */ \ -+ asm volatile ("" : : : "memory"); \ -+ } \ -+ \ -+ for (i = 0; i < NUM_TESTS; i+=nlanes) \ -+ { \ -+ U##int##WIDTH##x##LANES##_t out = \ -+ vcvt##SUFFIX##Q##_##S##WIDTH##_f##WIDTH \ -+ (vld1##Q##_f##WIDTH (input_f##WIDTH + i)); \ -+ vst1##Q##_##S##WIDTH (actual_out + i, out); \ -+ } \ -+ \ -+ for (i = 0; i < NUM_TESTS; i++) \ -+ ret &= fabs (expected_out[i] - actual_out[i]) < DELTA; \ -+ \ -+ return ret; \ -+} \ ++ Backport from trunk r197530,197921. ++ 2013-04-05 Greta Yorsh + ++ * gcc.target/arm/peep-ldrd-1.c: New test. ++ * gcc.target/arm/peep-strd-1.c: Likewise. + -+#define BUILD_VARIANTS(SUFFIX) \ -+TEST (SUFFIX, , 32, 2, s, ,s) \ -+TEST (SUFFIX, q, 32, 4, s, ,s) \ -+TEST (SUFFIX, q, 64, 2, s, ,d) \ -+TEST (SUFFIX, , 32, 2, u,u,s) \ -+TEST (SUFFIX, q, 32, 4, u,u,s) \ -+TEST (SUFFIX, q, 64, 2, u,u,d) \ ++2013-05-02 Matthew Gretton-Dann + -+BUILD_VARIANTS ( ) -+/* { dg-final { scan-assembler "fcvtzs\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtzs\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtzs\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtzs\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtzs\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "fcvtzu\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtzu\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtzu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtzu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtzu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (a) -+/* { dg-final { scan-assembler "fcvtas\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtas\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtas\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtas\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtas\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "fcvtau\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtau\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtau\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtau\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtau\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (m) -+/* { dg-final { scan-assembler "fcvtms\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtms\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtms\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtms\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtms\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "fcvtmu\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtmu\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtmu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtmu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtmu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (n) -+/* { dg-final { scan-assembler "fcvtns\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtns\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtns\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtns\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtns\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "fcvtnu\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtnu\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtnu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtnu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtnu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+BUILD_VARIANTS (p) -+/* { dg-final { scan-assembler "fcvtps\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtps\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtps\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtps\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtps\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ -+/* { dg-final { scan-assembler "fcvtpu\\tw\[0-9\]+, s\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtpu\\tx\[0-9\]+, d\[0-9\]+" } } */ -+/* { dg-final { scan-assembler "fcvtpu\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */ -+/* { dg-final { scan-assembler "fcvtpu\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */ -+/* { dg-final { scan-assembler "fcvtpu\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ ++ Backport from trunk r197523. ++ 2013-04-05 Kyrylo Tkachov + -+#undef TEST -+#define TEST(SUFFIX, Q, WIDTH, LANES, S, U, D) \ -+{ \ -+ if (!test_vcvt##SUFFIX##_##S##WIDTH##_f##WIDTH##x##LANES##_t ()) \ -+ abort (); \ -+} ++ * lib/target-supports.exp (add_options_for_arm_v8_neon): ++ Add -march=armv8-a when we use v8 NEON. ++ (check_effective_target_vect_call_btruncf): Remove arm-*-*-*. ++ (check_effective_target_vect_call_ceilf): Likewise. ++ (check_effective_target_vect_call_floorf): Likewise. ++ (check_effective_target_vect_call_roundf): Likewise. ++ (check_vect_support_and_set_flags): Remove check for arm_v8_neon. ++ * gcc.target/arm/vect-rounding-btruncf.c: New testcase. ++ * gcc.target/arm/vect-rounding-ceilf.c: Likewise. ++ * gcc.target/arm/vect-rounding-floorf.c: Likewise. ++ * gcc.target/arm/vect-rounding-roundf.c: Likewise. + -+int -+main (int argc, char **argv) -+{ -+ BUILD_VARIANTS ( ) -+ BUILD_VARIANTS (a) -+ BUILD_VARIANTS (m) -+ BUILD_VARIANTS (n) -+ BUILD_VARIANTS (p) -+ return 0; -+} ++2013-05-02 Matthew Gretton-Dann + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-release.x -@@ -0,0 +1,37 @@ -+int v = 0; ++ Backport from trunk r197518-197522,197516-197528. ++ 2013-04-05 Greta Yorsh + -+int -+atomic_fetch_add_RELEASE (int a) -+{ -+ return __atomic_fetch_add (&v, a, __ATOMIC_RELEASE); -+} ++ * gcc.target/arm/negdi-1.c: New test. ++ * gcc.target/arm/negdi-2.c: Likewise. ++ * gcc.target/arm/negdi-3.c: Likewise. ++ * gcc.target/arm/negdi-4.c: Likewise. + -+int -+atomic_fetch_sub_RELEASE (int a) -+{ -+ return __atomic_fetch_sub (&v, a, __ATOMIC_RELEASE); -+} ++2013-05-02 Matthew Gretton-Dann + -+int -+atomic_fetch_and_RELEASE (int a) -+{ -+ return __atomic_fetch_and (&v, a, __ATOMIC_RELEASE); -+} ++ Backport from trunk r197489-197491. ++ 2013-04-04 Kyrylo Tkachov + -+int -+atomic_fetch_nand_RELEASE (int a) -+{ -+ return __atomic_fetch_nand (&v, a, __ATOMIC_RELEASE); -+} ++ * lib/target-supports.exp (check_effective_target_arm_v8_neon_hw): ++ New procedure. ++ (check_effective_target_arm_v8_neon_ok_nocache): ++ Likewise. ++ (check_effective_target_arm_v8_neon_ok): Change to use ++ check_effective_target_arm_v8_neon_ok_nocache. ++ (add_options_for_arm_v8_neon): Use et_arm_v8_neon_flags to set ARMv8 ++ NEON flags. ++ (check_effective_target_vect_call_btruncf): ++ Enable for arm and ARMv8 NEON. ++ (check_effective_target_vect_call_ceilf): Likewise. ++ (check_effective_target_vect_call_floorf): Likewise. ++ (check_effective_target_vect_call_roundf): Likewise. ++ (check_vect_support_and_set_flags): Handle ARMv8 NEON effective ++ target. + -+int -+atomic_fetch_xor_RELEASE (int a) -+{ -+ return __atomic_fetch_xor (&v, a, __ATOMIC_RELEASE); -+} ++2013-05-02 Matthew Gretton-Dann + -+int -+atomic_fetch_or_RELEASE (int a) -+{ -+ return __atomic_fetch_or (&v, a, __ATOMIC_RELEASE); -+} ---- a/src/gcc/testsuite/gcc.target/aarch64/fabd.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/fabd.c -@@ -0,0 +1,38 @@ -+/* { dg-do run } */ -+/* { dg-options "-O1 -fno-inline --save-temps" } */ ++ Backport from trunk r196795-196797,196957. ++ 2013-03-19 Ian Bolton + -+extern double fabs (double); -+extern float fabsf (float); -+extern void abort (); -+extern void exit (int); ++ * gcc.target/aarch64/sbc.c: New test. + -+void -+fabd_d (double x, double y, double d) -+{ -+ if ((fabs (x - y) - d) > 0.00001) -+ abort (); -+} ++ 2013-03-19 Ian Bolton + -+/* { dg-final { scan-assembler "fabd\td\[0-9\]+" } } */ ++ * gcc.target/aarch64/ror.c: New test. + -+void -+fabd_f (float x, float y, float d) -+{ -+ if ((fabsf (x - y) - d) > 0.00001) -+ abort (); -+} ++ 2013-03-19 Ian Bolton + -+/* { dg-final { scan-assembler "fabd\ts\[0-9\]+" } } */ ++ * gcc.target/aarch64/extr.c: New test. + -+int -+main () -+{ -+ fabd_d (10.0, 5.0, 5.0); -+ fabd_d (5.0, 10.0, 5.0); -+ fabd_f (10.0, 5.0, 5.0); -+ fabd_f (5.0, 10.0, 5.0); ++2013-04-09 Matthew Gretton-Dann + -+ return 0; -+} ++ * GCC Linaro 4.8-2013.04 released. + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fp.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fp.c -@@ -117,6 +117,16 @@ - 9.0, 10.0, 11.0, 12.0, - 13.0, 14.0, 15.0, 16.0 }; - -+ F32 fabd_F32_vector[] = { 1.0f, 1.0f, 1.0f, 1.0f, -+ 1.0f, 1.0f, 1.0f, 1.0f, -+ 1.0f, 1.0f, 1.0f, 1.0f, -+ 1.0f, 1.0f, 1.0f, 1.0f }; ++2013-04-08 Matthew Gretton-Dann + -+ F64 fabd_F64_vector[] = { 1.0, 1.0, 1.0, 1.0, -+ 1.0, 1.0, 1.0, 1.0, -+ 1.0, 1.0, 1.0, 1.0, -+ 1.0, 1.0, 1.0, 1.0 }; ++ Backport from trunk r197052. ++ 2013-03-25 Kyrylo Tkachov + - /* Setup input vectors. */ - for (i=1; i<=16; i++) - { -@@ -132,6 +142,7 @@ - TEST (div, 3); - TEST (neg, 2); - TEST (abs, 2); -+ TEST (fabd, 3); - - return 0; - } ---- a/src/gcc/testsuite/gcc.target/aarch64/ngc.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/ngc.c -@@ -0,0 +1,66 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ ++ * gcc.target/arm/vseleqdf.c: New test. ++ * gcc.target/arm/vseleqsf.c: Likewise. ++ * gcc.target/arm/vselgedf.c: Likewise. ++ * gcc.target/arm/vselgesf.c: Likewise. ++ * gcc.target/arm/vselgtdf.c: Likewise. ++ * gcc.target/arm/vselgtsf.c: Likewise. ++ * gcc.target/arm/vselledf.c: Likewise. ++ * gcc.target/arm/vsellesf.c: Likewise. ++ * gcc.target/arm/vselltdf.c: Likewise. ++ * gcc.target/arm/vselltsf.c: Likewise. ++ * gcc.target/arm/vselnedf.c: Likewise. ++ * gcc.target/arm/vselnesf.c: Likewise. ++ * gcc.target/arm/vselvcdf.c: Likewise. ++ * gcc.target/arm/vselvcsf.c: Likewise. ++ * gcc.target/arm/vselvsdf.c: Likewise. ++ * gcc.target/arm/vselvssf.c: Likewise. + -+extern void abort (void); -+typedef unsigned int u32; ++2013-04-08 Matthew Gretton-Dann + -+u32 -+ngc_si (u32 a, u32 b, u32 c, u32 d) ++ Backport from trunk r197051. ++ 2013-03-25 Kyrylo Tkachov ++ ++ * gcc.target/aarch64/atomic-comp-swap-release-acquire.c: Move test ++ body from here... ++ * gcc.target/aarch64/atomic-comp-swap-release-acquire.x: ... to here. ++ * gcc.target/aarch64/atomic-op-acq_rel.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-acq_rel.x: ... to here. ++ * gcc.target/aarch64/atomic-op-acquire.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-acquire.x: ... to here. ++ * gcc.target/aarch64/atomic-op-char.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-char.x: ... to here. ++ * gcc.target/aarch64/atomic-op-consume.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-consume.x: ... to here. ++ * gcc.target/aarch64/atomic-op-int.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-int.x: ... to here. ++ * gcc.target/aarch64/atomic-op-relaxed.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-relaxed.x: ... to here. ++ * gcc.target/aarch64/atomic-op-release.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-release.x: ... to here. ++ * gcc.target/aarch64/atomic-op-seq_cst.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-seq_cst.x: ... to here. ++ * gcc.target/aarch64/atomic-op-short.c: Move test body from here... ++ * gcc.target/aarch64/atomic-op-short.x: ... to here. ++ * gcc.target/arm/atomic-comp-swap-release-acquire.c: New test. ++ * gcc.target/arm/atomic-op-acq_rel.c: Likewise. ++ * gcc.target/arm/atomic-op-acquire.c: Likewise. ++ * gcc.target/arm/atomic-op-char.c: Likewise. ++ * gcc.target/arm/atomic-op-consume.c: Likewise. ++ * gcc.target/arm/atomic-op-int.c: Likewise. ++ * gcc.target/arm/atomic-op-relaxed.c: Likewise. ++ * gcc.target/arm/atomic-op-release.c: Likewise. ++ * gcc.target/arm/atomic-op-seq_cst.c: Likewise. ++ * gcc.target/arm/atomic-op-short.c: Likewise. ++ ++2013-04-08 Matthew Gretton-Dann ++ ++ Backport from trunk r196876. ++ 2013-03-21 Christophe Lyon ++ ++ * gcc.target/arm/neon-for-64bits-1.c: New tests. ++ * gcc.target/arm/neon-for-64bits-2.c: Likewise. ++ ++2013-04-08 Matthew Gretton-Dann ++ ++ Backport from trunk r196858. ++ 2013-03-21 Naveen H.S ++ ++ * gcc.target/aarch64/vect.c: Test and result vector added ++ for sabd and saba instructions. ++ * gcc.target/aarch64/vect-compile.c: Check for sabd and saba ++ instructions in assembly. ++ * gcc.target/aarch64/vect.x: Add sabd and saba test functions. ++ * gcc.target/aarch64/vect-fp.c: Test and result vector added ++ for fabd instruction. ++ * gcc.target/aarch64/vect-fp-compile.c: Check for fabd ++ instruction in assembly. ++ * gcc.target/aarch64/vect-fp.x: Add fabd test function. +--- a/src/gcc/testsuite/gcc.dg/shrink-wrap-alloca.c ++++ b/src/gcc/testsuite/gcc.dg/shrink-wrap-alloca.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -g" } */ ++ ++int *p; ++ ++void ++test (int a) +{ -+ a = -b - (c < d); -+ return a; ++ if (a > 0) ++ p = __builtin_alloca (4); +} +--- a/src/gcc/testsuite/gcc.dg/shrink-wrap-pretend.c ++++ b/src/gcc/testsuite/gcc.dg/shrink-wrap-pretend.c +@@ -0,0 +1,36 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -g" } */ + -+typedef unsigned long long u64; ++#include ++#include ++#include + -+u64 -+ngc_si_tst (u64 a, u32 b, u32 c, u32 d) ++#define DEBUG_BUFFER_SIZE 80 ++int unifi_debug = 5; ++ ++void ++unifi_trace (void* ospriv, int level, const char *fmt, ...) +{ -+ a = -b - (c < d); -+ return a; ++ static char s[DEBUG_BUFFER_SIZE]; ++ va_list args; ++ unsigned int len; ++ ++ if (!ospriv) ++ return; ++ ++ if (unifi_debug >= level) ++ { ++ va_start (args, fmt); ++ len = vsnprintf (&(s)[0], (DEBUG_BUFFER_SIZE), fmt, args); ++ va_end (args); ++ ++ if (len >= DEBUG_BUFFER_SIZE) ++ { ++ (s)[DEBUG_BUFFER_SIZE - 2] = '\n'; ++ (s)[DEBUG_BUFFER_SIZE - 1] = 0; ++ } ++ ++ printf ("%s", s); ++ } +} + -+u64 -+ngc_di (u64 a, u64 b, u64 c, u64 d) +--- a/src/gcc/testsuite/gcc.dg/debug/pr57351.c ++++ b/src/gcc/testsuite/gcc.dg/debug/pr57351.c +@@ -0,0 +1,54 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_neon } */ ++/* { dg-options "-std=c99 -Os -g -march=armv7-a" } */ ++/* { dg-add-options arm_neon } */ ++ ++typedef unsigned int size_t; ++typedef int ptrdiff_t; ++typedef signed char int8_t ; ++typedef signed long long int64_t; ++typedef int8_t GFC_INTEGER_1; ++typedef GFC_INTEGER_1 GFC_LOGICAL_1; ++typedef int64_t GFC_INTEGER_8; ++typedef GFC_INTEGER_8 GFC_LOGICAL_8; ++typedef ptrdiff_t index_type; ++typedef struct descriptor_dimension +{ -+ a = -b - (c < d); -+ return a; ++ index_type lower_bound; ++ index_type _ubound; ++} ++descriptor_dimension; ++typedef struct { GFC_LOGICAL_1 *base_addr; size_t offset; index_type dtype; descriptor_dimension dim[7];} gfc_array_l1; ++typedef struct { GFC_LOGICAL_8 *base_addr; size_t offset; index_type dtype; descriptor_dimension dim[7];} gfc_array_l8; ++void ++all_l8 (gfc_array_l8 * const restrict retarray, ++ gfc_array_l1 * const restrict array, ++ const index_type * const restrict pdim) ++{ ++ GFC_LOGICAL_8 * restrict dest; ++ index_type n; ++ index_type len; ++ index_type delta; ++ index_type dim; ++ dim = (*pdim) - 1; ++ len = ((array)->dim[dim]._ubound + 1 - (array)->dim[dim].lower_bound); ++ for (n = 0; n < dim; n++) ++ { ++ const GFC_LOGICAL_1 * restrict src; ++ GFC_LOGICAL_8 result; ++ { ++ result = 1; ++ { ++ for (n = 0; n < len; n++, src += delta) ++ { ++ if (! *src) ++ { ++ result = 0; ++ break; ++ } ++ } ++ *dest = result; ++ } ++ } ++ } +} +--- a/src/gcc/testsuite/gcc.dg/lower-subreg-1.c ++++ b/src/gcc/testsuite/gcc.dg/lower-subreg-1.c +@@ -1,4 +1,4 @@ +-/* { dg-do compile { target { ! { mips64 || { arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ ++/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ + /* { dg-options "-O -fdump-rtl-subreg1" } */ + /* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } { "*" } { "" } } */ + /* { dg-require-effective-target ilp32 } */ +--- a/src/gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c ++++ b/src/gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c +@@ -0,0 +1,26 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -g" } */ ++ ++unsigned char a, b, d, f, g; ++ ++int test (void); + +int -+main () ++baz (int c) +{ -+ int x; -+ u64 y; ++ if (c == 0) return test (); ++ if (b & 1) ++ { ++ g = 0; ++ int e = (a & 0x0f) - (g & 0x0f); + -+ x = ngc_si (29, 4, 5, 4); -+ if (x != -4) -+ abort (); ++ if (!a) b |= 0x80; ++ a = e + test (); ++ f = g/5 + a*3879 + b *2985; ++ } ++ else ++ { ++ f = g + a*39879 + b *25; ++ } ++ return test (); ++} +--- a/src/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c ++++ b/src/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c +@@ -16,7 +16,7 @@ + E, F and G are passed on stack. So the size of the stack argument + data is 20. */ + #define STACK_ARGUMENTS_SIZE 20 +-#elif defined __MMIX__ ++#elif defined __aarch64__ || defined __MMIX__ + /* No parameters on stack for bar. */ + #define STACK_ARGUMENTS_SIZE 0 + #else +--- a/src/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c ++++ b/src/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c +@@ -1,4 +1,6 @@ +-/* { dg-require-effective-target vect_int } */ ++/* { dg-require-effective-target vect_int } ++ { dg-skip-if "AArch64 tiny code model does not support programs larger than 1MiB" {aarch64_tiny} {"*"} {""} } ++ */ + + #include + #include "tree-vect.h" +--- a/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C ++++ b/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C +@@ -37,9 +37,9 @@ + + // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow on address\[^\n\r]*" } + // { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } +-// { dg-output "READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } ++// { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } + // { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } +-// { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } +-// { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } ++// { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } ++// { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } + // { dg-output " #0( 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } + // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } +--- a/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C ++++ b/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C +@@ -45,9 +45,9 @@ + } + + // { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } +-// { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } +-// { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } +-// { dg-output "previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } ++// { dg-output "\[^\n\r]*WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } ++// { dg-output "\[^\n\r]*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } ++// { dg-output "\[^\n\r]*previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } + // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } + // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } + // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } +--- a/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c ++++ b/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c +@@ -15,7 +15,7 @@ + /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +-/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ +-/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +--- a/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c ++++ b/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c +@@ -2,6 +2,7 @@ + + /* { dg-do run { target setrlimit } } */ + /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ ++/* { dg-require-effective-target hw } */ + /* { dg-shouldfail "asan" } */ + + #include +--- a/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c ++++ b/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c +@@ -19,4 +19,4 @@ + + /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +-/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame
" } */ ++/* { dg-output "\[^\n\r]*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame
" } */ +--- a/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c ++++ b/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c +@@ -11,12 +11,12 @@ + + /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free on address\[^\n\r]*" } */ + /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ +-/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +-/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ +-/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +-/* { dg-output "previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +--- a/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c ++++ b/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c +@@ -3,6 +3,7 @@ + + /* { dg-do run { target { *-*-linux* } } } */ + /* { dg-require-effective-target clone } */ ++/* { dg-require-effective-target hw } */ + /* { dg-options "-D_GNU_SOURCE" } */ + + #include +--- a/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c ++++ b/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c +@@ -25,7 +25,7 @@ + + /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +-/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ +-/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +--- a/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c ++++ b/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c +@@ -18,6 +18,6 @@ + + /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */ + /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ +-/* { dg-output "AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */ ++/* { dg-output "\[^\n\r]*AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */ + /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ + /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +--- a/src/gcc/objcp/ChangeLog.linaro ++++ b/src/gcc/objcp/ChangeLog.linaro +@@ -0,0 +1,31 @@ ++2013-10-15 Christophe Lyon + -+ x = ngc_si (1024, 2, 20, 13); -+ if (x != -2) -+ abort (); ++ GCC Linaro 4.8-2013.10 released. + -+ y = ngc_si_tst (0x130000029ll, 32, 50, 12); -+ if (y != 0xffffffe0) -+ abort (); ++2013-09-10 Christophe Lyon + -+ y = ngc_si_tst (0x5000500050005ll, 21, 2, 14); -+ if (y != 0xffffffea) -+ abort (); ++ GCC Linaro 4.8-2013.09 released. + -+ y = ngc_di (0x130000029ll, 0x320000004ll, 0x505050505ll, 0x123123123ll); -+ if (y != 0xfffffffcdffffffc) -+ abort (); ++2013-08-14 Christophe Lyon + -+ y = ngc_di (0x5000500050005ll, -+ 0x2111211121112ll, 0x0000000002020ll, 0x1414575046477ll); -+ if (y != 0xfffdeeedeeedeeed) -+ abort (); ++ GCC Linaro 4.8-2013.08 released. + -+ return 0; -+} ++2013-07-19 Matthew Gretton-Dann + -+/* { dg-final { scan-assembler-times "ngc\tw\[0-9\]+, w\[0-9\]+" 2 } } */ -+/* { dg-final { scan-assembler-times "ngc\tx\[0-9\]+, x\[0-9\]+" 1 } } */ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/sha1_1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/sha1_1.c -@@ -0,0 +1,55 @@ ++ GCC Linaro 4.8-2013.07-1 released. + -+/* { dg-do compile } */ -+/* { dg-options "-march=armv8-a+crypto" } */ ++2013-07-05 Christophe Lyon + -+#include "arm_neon.h" ++ GCC Linaro 4.8-2013.07 released. + -+uint32x4_t -+test_vsha1cq_u32 (uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) -+{ -+ return vsha1cq_u32 (hash_abcd, hash_e, wk); -+} ++2013-06-11 Rob Savoye + -+/* { dg-final { scan-assembler-times "sha1c\\tq" 1 } } */ ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+uint32x4_t -+test_vsha1mq_u32 (uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) -+{ -+ return vsha1mq_u32 (hash_abcd, hash_e, wk); -+} ++2013-05-14 Matthew Gretton-Dann + -+/* { dg-final { scan-assembler-times "sha1m\\tq" 1 } } */ ++ GCC Linaro 4.8-2013.05 released. + -+uint32x4_t -+test_vsha1pq_u32 (uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) -+{ -+ return vsha1pq_u32 (hash_abcd, hash_e, wk); -+} ++2013-04-09 Matthew Gretton-Dann + -+/* { dg-final { scan-assembler-times "sha1p\\tq" 1 } } */ ++ * GCC Linaro 4.8-2013.04 released. +--- a/src/gcc/cp/ChangeLog.linaro ++++ b/src/gcc/cp/ChangeLog.linaro +@@ -0,0 +1,31 @@ ++2013-10-15 Christophe Lyon + -+uint32_t -+test_vsha1h_u32 (uint32_t hash_e) -+{ -+ return vsha1h_u32 (hash_e); -+} ++ GCC Linaro 4.8-2013.10 released. + -+/* { dg-final { scan-assembler-times "sha1h\\ts" 1 } } */ ++2013-09-10 Christophe Lyon + -+uint32x4_t -+test_vsha1su0q_u32 (uint32x4_t w0_3, uint32x4_t w4_7, uint32x4_t w8_11) -+{ -+ return vsha1su0q_u32 (w0_3, w4_7, w8_11); -+} ++ GCC Linaro 4.8-2013.09 released. + -+/* { dg-final { scan-assembler-times "sha1su0\\tv" 1 } } */ ++2013-08-14 Christophe Lyon + -+uint32x4_t -+test_vsha1su1q_u32 (uint32x4_t tw0_3, uint32x4_t w12_15) -+{ -+ return vsha1su1q_u32 (tw0_3, w12_15); -+} ++ GCC Linaro 4.8-2013.08 released. + -+/* { dg-final { scan-assembler-times "sha1su1\\tv" 1 } } */ ++2013-07-19 Matthew Gretton-Dann + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/cmp.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/cmp.c -@@ -0,0 +1,61 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O2" } */ ++ GCC Linaro 4.8-2013.07-1 released. + -+int -+cmp_si_test1 (int a, int b, int c) -+{ -+ if (a > b) -+ return a + c; -+ else -+ return a + b + c; -+} ++2013-07-05 Christophe Lyon + -+int -+cmp_si_test2 (int a, int b, int c) -+{ -+ if ((a >> 3) > b) -+ return a + c; -+ else -+ return a + b + c; -+} ++ GCC Linaro 4.8-2013.07 released. + -+typedef long long s64; ++2013-06-11 Rob Savoye + -+s64 -+cmp_di_test1 (s64 a, s64 b, s64 c) -+{ -+ if (a > b) -+ return a + c; -+ else -+ return a + b + c; -+} ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+s64 -+cmp_di_test2 (s64 a, s64 b, s64 c) -+{ -+ if ((a >> 3) > b) -+ return a + c; -+ else -+ return a + b + c; -+} ++2013-05-14 Matthew Gretton-Dann + -+int -+cmp_di_test3 (int a, s64 b, s64 c) -+{ -+ if (a > b) -+ return a + c; -+ else -+ return a + b + c; -+} -+ -+int -+cmp_di_test4 (int a, s64 b, s64 c) -+{ -+ if (((s64)a << 3) > b) -+ return a + c; -+ else -+ return a + b + c; -+} -+ -+/* { dg-final { scan-assembler-times "cmp\tw\[0-9\]+, w\[0-9\]+" 2 } } */ -+/* { dg-final { scan-assembler-times "cmp\tx\[0-9\]+, x\[0-9\]+" 4 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c -@@ -2,12 +2,13 @@ - /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ - - #define FTYPE float -+#define ITYPE int - #define OP >= - #define INV_OP < - - #include "vect-fcm.x" - --/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ - /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */ - /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ - /* { dg-final { scan-assembler "fcmlt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/bfxil_2.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/bfxil_2.c -@@ -0,0 +1,42 @@ -+/* { dg-do run { target aarch64*-*-* } } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+/* { dg-require-effective-target aarch64_big_endian } */ -+ -+extern void abort (void); -+ -+typedef struct bitfield -+{ -+ unsigned short eight1: 8; -+ unsigned short four: 4; -+ unsigned short eight2: 8; -+ unsigned short seven: 7; -+ unsigned int sixteen: 16; -+ unsigned short eight3: 8; -+ unsigned short eight4: 8; -+} bitfield; -+ -+bitfield -+bfxil (bitfield a) -+{ -+ /* { dg-final { scan-assembler "bfxil\tx\[0-9\]+, x\[0-9\]+, 40, 8" } } */ -+ a.eight4 = a.eight2; -+ return a; -+} ++ GCC Linaro 4.8-2013.05 released. + -+int -+main (void) -+{ -+ static bitfield a; -+ bitfield b; ++2013-04-09 Matthew Gretton-Dann + -+ a.eight4 = 9; -+ a.eight2 = 57; -+ b = bfxil (a); ++ * GCC Linaro 4.8-2013.04 released. +--- a/src/gcc/tree-ssa-loop-ivopts.c ++++ b/src/gcc/tree-ssa-loop-ivopts.c +@@ -4827,22 +4827,36 @@ + for (i = 0; i < n_iv_cands (data); i++) + { + struct iv_cand *cand = iv_cand (data, i); +- struct iv_use *closest = NULL; ++ struct iv_use *closest_before = NULL; ++ struct iv_use *closest_after = NULL; + if (cand->pos != IP_ORIGINAL) + continue; + -+ if (b.eight4 != a.eight2) -+ abort (); + for (j = 0; j < n_iv_uses (data); j++) + { + struct iv_use *use = iv_use (data, j); + unsigned uid = gimple_uid (use->stmt); +- if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at) +- || uid > gimple_uid (cand->incremented_at)) + -+ return 0; -+} ++ if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at)) + continue; +- if (closest == NULL || uid > gimple_uid (closest->stmt)) +- closest = use; + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fp.x -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fp.x -@@ -7,6 +7,16 @@ - extern float fabsf (float); - extern double fabs (double); - -+#define DEF3a(fname, type, op) \ -+ void fname##_##type (pR##type a, \ -+ pR##type b, \ -+ pR##type c) \ -+ { \ -+ int i; \ -+ for (i = 0; i < 16; i++) \ -+ a[i] = op (b[i] - c[i]); \ -+ } ++ if (uid < gimple_uid (cand->incremented_at) ++ && (closest_before == NULL ++ || uid > gimple_uid (closest_before->stmt))) ++ closest_before = use; + - #define DEF3(fname, type, op) \ - void fname##_##type (pR##type a, \ - pR##type b, \ -@@ -13,7 +23,7 @@ - pR##type c) \ - { \ - int i; \ -- for (i=0; i<16; i++) \ -+ for (i = 0; i < 16; i++) \ - a[i] = b[i] op c[i]; \ - } - -@@ -22,11 +32,15 @@ - pR##type b) \ - { \ - int i; \ -- for (i=0; i<16; i++) \ -+ for (i = 0; i < 16; i++) \ - a[i] = op(b[i]); \ - } - - -+#define DEFN3a(fname, op) \ -+ DEF3a (fname, F32, op) \ -+ DEF3a (fname, F64, op) ++ if (uid > gimple_uid (cand->incremented_at) ++ && (closest_after == NULL ++ || uid < gimple_uid (closest_after->stmt))) ++ closest_after = use; + } +- if (closest == NULL || !autoinc_possible_for_pair (data, closest, cand)) +- continue; +- cand->ainc_use = closest; + - #define DEFN3(fname, op) \ - DEF3 (fname, F32, op) \ - DEF3 (fname, F64, op) -@@ -42,3 +56,5 @@ - DEFN2 (neg, -) - DEF2 (abs, F32, fabsf) - DEF2 (abs, F64, fabs) -+DEF3a (fabd, F32, fabsf) -+DEF3a (fabd, F64, fabs) ---- a/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/atomic-op-acq_rel.c -@@ -1,43 +1,7 @@ - /* { dg-do compile } */ - /* { dg-options "-O2" } */ ++ if (closest_before != NULL ++ && autoinc_possible_for_pair (data, closest_before, cand)) ++ cand->ainc_use = closest_before; ++ else if (closest_after != NULL ++ && autoinc_possible_for_pair (data, closest_after, cand)) ++ cand->ainc_use = closest_after; + } + } --int v = 0; -+#include "atomic-op-acq_rel.x" +--- a/src/gcc/rtl.def ++++ b/src/gcc/rtl.def +@@ -937,8 +937,9 @@ + relational operator. Operands should have only one alternative. + 1: A C expression giving an additional condition for recognizing + the generated pattern. +- 2: A template or C code to produce assembler output. */ +-DEF_RTL_EXPR(DEFINE_COND_EXEC, "define_cond_exec", "Ess", RTX_EXTRA) ++ 2: A template or C code to produce assembler output. ++ 3: A vector of attributes to append to the resulting cond_exec insn. */ ++DEF_RTL_EXPR(DEFINE_COND_EXEC, "define_cond_exec", "EssV", RTX_EXTRA) --int --atomic_fetch_add_ACQ_REL (int a) --{ -- return __atomic_fetch_add (&v, a, __ATOMIC_ACQ_REL); --} -- --int --atomic_fetch_sub_ACQ_REL (int a) --{ -- return __atomic_fetch_sub (&v, a, __ATOMIC_ACQ_REL); --} -- --int --atomic_fetch_and_ACQ_REL (int a) --{ -- return __atomic_fetch_and (&v, a, __ATOMIC_ACQ_REL); --} -- --int --atomic_fetch_nand_ACQ_REL (int a) --{ -- return __atomic_fetch_nand (&v, a, __ATOMIC_ACQ_REL); --} -- --int --atomic_fetch_xor_ACQ_REL (int a) --{ -- return __atomic_fetch_xor (&v, a, __ATOMIC_ACQ_REL); --} -- --int --atomic_fetch_or_ACQ_REL (int a) --{ -- return __atomic_fetch_or (&v, a, __ATOMIC_ACQ_REL); --} -- - /* { dg-final { scan-assembler-times "ldaxr\tw\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ - /* { dg-final { scan-assembler-times "stlxr\tw\[0-9\]+, w\[0-9\]+, \\\[x\[0-9\]+\\\]" 6 } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/subs1.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/subs1.c -@@ -0,0 +1,149 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ -+ -+extern void abort (void); -+ -+int -+subs_si_test1 (int a, int b, int c) -+{ -+ int d = a - c; -+ -+ /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} + /* Definition of an operand predicate. The difference between + DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE is that genrecog will +--- a/src/gcc/go/ChangeLog.linaro ++++ b/src/gcc/go/ChangeLog.linaro +@@ -0,0 +1,31 @@ ++2013-10-15 Christophe Lyon + -+int -+subs_si_test2 (int a, int b, int c) -+{ -+ int d = a - 0xff; ++ GCC Linaro 4.8-2013.10 released. + -+ /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, #255" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-09-10 Christophe Lyon + -+int -+subs_si_test3 (int a, int b, int c) -+{ -+ int d = a - (b << 3); ++ GCC Linaro 4.8-2013.09 released. + -+ /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-08-14 Christophe Lyon + -+typedef long long s64; ++ GCC Linaro 4.8-2013.08 released. + -+s64 -+subs_di_test1 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a - c; ++2013-07-19 Matthew Gretton-Dann + -+ /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ GCC Linaro 4.8-2013.07-1 released. + -+s64 -+subs_di_test2 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a - 0xff; ++2013-07-05 Christophe Lyon + -+ /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, #255" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ GCC Linaro 4.8-2013.07 released. + -+s64 -+subs_di_test3 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a - (b << 3); ++2013-06-11 Rob Savoye + -+ /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d == 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+int main () -+{ -+ int x; -+ s64 y; ++2013-05-14 Matthew Gretton-Dann + -+ x = subs_si_test1 (29, 4, 5); -+ if (x != 33) -+ abort (); ++ GCC Linaro 4.8-2013.05 released. + -+ x = subs_si_test1 (5, 2, 20); -+ if (x != 7) -+ abort (); ++2013-04-09 Matthew Gretton-Dann + -+ x = subs_si_test2 (29, 4, 5); -+ if (x != -217) -+ abort (); ++ * GCC Linaro 4.8-2013.04 released. +--- a/src/gcc/ada/ChangeLog.linaro ++++ b/src/gcc/ada/ChangeLog.linaro +@@ -0,0 +1,31 @@ ++2013-10-15 Christophe Lyon + -+ x = subs_si_test2 (1024, 2, 20); -+ if (x != 791) -+ abort (); ++ GCC Linaro 4.8-2013.10 released. + -+ x = subs_si_test3 (35, 4, 5); -+ if (x != 12) -+ abort (); ++2013-09-10 Christophe Lyon + -+ x = subs_si_test3 (5, 2, 20); -+ if (x != 11) -+ abort (); ++ GCC Linaro 4.8-2013.09 released. + -+ y = subs_di_test1 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); ++2013-08-14 Christophe Lyon + -+ if (y != 0x45000002d) -+ abort (); ++ GCC Linaro 4.8-2013.08 released. + -+ y = subs_di_test1 (0x5000500050005ll, -+ 0x2111211121112ll, -+ 0x0000000002020ll); -+ if (y != 0x7111711171117) -+ abort (); ++2013-07-19 Matthew Gretton-Dann + -+ y = subs_di_test2 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != 0x955050433) -+ abort (); ++ GCC Linaro 4.8-2013.07-1 released. + -+ y = subs_di_test2 (0x130002900ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != 0x955052d0a) -+ abort (); ++2013-07-05 Christophe Lyon + -+ y = subs_di_test3 (0x130000029ll, -+ 0x064000008ll, -+ 0x505050505ll); -+ if (y != 0x3790504f6) -+ abort (); ++ GCC Linaro 4.8-2013.07 released. + -+ y = subs_di_test3 (0x130002900ll, -+ 0x088000008ll, -+ 0x505050505ll); -+ if (y != 0x27d052dcd) -+ abort (); ++2013-06-11 Rob Savoye + -+ return 0; -+} ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/adds2.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/adds2.c -@@ -0,0 +1,155 @@ -+/* { dg-do run } */ -+/* { dg-options "-O2 --save-temps -fno-inline" } */ ++2013-05-14 Matthew Gretton-Dann + -+extern void abort (void); ++ GCC Linaro 4.8-2013.05 released. + -+int -+adds_si_test1 (int a, int b, int c) -+{ -+ int d = a + b; ++2013-04-09 Matthew Gretton-Dann + -+ /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ * GCC Linaro 4.8-2013.04 released. +--- a/src/gcc/common/config/aarch64/aarch64-common.c ++++ b/src/gcc/common/config/aarch64/aarch64-common.c +@@ -44,6 +44,8 @@ + { + /* Enable section anchors by default at -O1 or higher. */ + { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, ++ /* Enable redundant extension instructions removal at -O2 and higher. */ ++ { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +--- a/src/gcc/fortran/ChangeLog.linaro ++++ b/src/gcc/fortran/ChangeLog.linaro +@@ -0,0 +1,31 @@ ++2013-10-15 Christophe Lyon + -+int -+adds_si_test2 (int a, int b, int c) -+{ -+ int d = a + 0xfff; ++ GCC Linaro 4.8-2013.10 released. + -+ /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, 4095" } } */ -+ /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, 4095" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-09-10 Christophe Lyon + -+int -+adds_si_test3 (int a, int b, int c) -+{ -+ int d = a + (b << 3); ++ GCC Linaro 4.8-2013.09 released. + -+ /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++2013-08-14 Christophe Lyon + -+typedef long long s64; ++ GCC Linaro 4.8-2013.08 released. + -+s64 -+adds_di_test1 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a + b; ++2013-07-19 Matthew Gretton-Dann + -+ /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ GCC Linaro 4.8-2013.07-1 released. + -+s64 -+adds_di_test2 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a + 0x1000ll; ++2013-07-05 Christophe Lyon + -+ /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, 4096" } } */ -+ /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, 4096" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ GCC Linaro 4.8-2013.07 released. + -+s64 -+adds_di_test3 (s64 a, s64 b, s64 c) -+{ -+ s64 d = a + (b << 3); ++2013-06-11 Rob Savoye + -+ /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ -+ if (d <= 0) -+ return a + c; -+ else -+ return b + d + c; -+} ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+int main () -+{ -+ int x; -+ s64 y; ++2013-05-14 Matthew Gretton-Dann + -+ x = adds_si_test1 (29, 4, 5); -+ if (x != 42) -+ abort (); ++ GCC Linaro 4.8-2013.05 released. + -+ x = adds_si_test1 (5, 2, 20); -+ if (x != 29) -+ abort (); ++2013-04-09 Matthew Gretton-Dann + -+ x = adds_si_test2 (29, 4, 5); -+ if (x != 4133) -+ abort (); ++ * GCC Linaro 4.8-2013.04 released. +--- a/src/gcc/configure.ac ++++ b/src/gcc/configure.ac +@@ -813,7 +813,7 @@ + ) + AC_SUBST(CONFIGURE_SPECS) + +-ACX_PKGVERSION([GCC]) ++ACX_PKGVERSION([Linaro GCC `cat $srcdir/LINARO-VERSION`]) + ACX_BUGURL([http://gcc.gnu.org/bugs.html]) + + # Sanity check enable_languages in case someone does not run the toplevel +@@ -4179,8 +4179,9 @@ + # ??? Once 2.11 is released, probably need to add first known working + # version to the per-target configury. + case "$cpu_type" in +- alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \ +- | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa) ++ aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \ ++ | mips | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 \ ++ | xtensa) + insn="nop" + ;; + ia64 | s390) +--- a/src/gcc/function.c ++++ b/src/gcc/function.c +@@ -5509,22 +5509,45 @@ + except for any part that overlaps SRC (next loop). */ + bb_uses = &DF_LR_BB_INFO (bb)->use; + bb_defs = &DF_LR_BB_INFO (bb)->def; +- for (i = dregno; i < end_dregno; i++) ++ if (df_live) + { +- if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i)) +- next_block = NULL; +- CLEAR_REGNO_REG_SET (live_out, i); +- CLEAR_REGNO_REG_SET (live_in, i); ++ for (i = dregno; i < end_dregno; i++) ++ { ++ if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i) ++ || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i)) ++ next_block = NULL; ++ CLEAR_REGNO_REG_SET (live_out, i); ++ CLEAR_REGNO_REG_SET (live_in, i); ++ } + -+ x = adds_si_test2 (1024, 2, 20); -+ if (x != 5141) -+ abort (); -+ -+ x = adds_si_test3 (35, 4, 5); -+ if (x != 76) -+ abort (); -+ -+ x = adds_si_test3 (5, 2, 20); -+ if (x != 43) -+ abort (); -+ -+ y = adds_di_test1 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ -+ if (y != 0xc75050536) -+ abort (); -+ -+ y = adds_di_test1 (0x5000500050005ll, -+ 0x2111211121112ll, -+ 0x0000000002020ll); -+ if (y != 0x9222922294249) -+ abort (); -+ -+ y = adds_di_test2 (0x130000029ll, -+ 0x320000004ll, -+ 0x505050505ll); -+ if (y != 0x955051532) -+ abort (); -+ -+ y = adds_di_test2 (0x540004100ll, -+ 0x320000004ll, -+ 0x805050205ll); -+ if (y != 0x1065055309) -+ abort (); -+ -+ y = adds_di_test3 (0x130000029ll, -+ 0x064000008ll, -+ 0x505050505ll); -+ if (y != 0x9b9050576) -+ abort (); -+ -+ y = adds_di_test3 (0x130002900ll, -+ 0x088000008ll, -+ 0x505050505ll); -+ if (y != 0xafd052e4d) -+ abort (); -+ -+ return 0; -+} -+ -+/* { dg-final { cleanup-saved-temps } } */ ---- a/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c -+++ b/src/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c -@@ -2,12 +2,13 @@ - /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */ - - #define FTYPE double -+#define ITYPE long - #define OP > - #define INV_OP <= - - #include "vect-fcm.x" ++ /* Check whether BB clobbers SRC. We need to add INSN to BB if so. ++ Either way, SRC is now live on entry. */ ++ for (i = sregno; i < end_sregno; i++) ++ { ++ if (REGNO_REG_SET_P (bb_defs, i) ++ || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i)) ++ next_block = NULL; ++ SET_REGNO_REG_SET (live_out, i); ++ SET_REGNO_REG_SET (live_in, i); ++ } + } ++ else ++ { ++ /* DF_LR_BB_INFO (bb)->def does not comprise the DF_REF_PARTIAL and ++ DF_REF_CONDITIONAL defs. So if DF_LIVE doesn't exist, i.e. ++ at -O1, just give up searching NEXT_BLOCK. */ ++ next_block = NULL; ++ for (i = dregno; i < end_dregno; i++) ++ { ++ CLEAR_REGNO_REG_SET (live_out, i); ++ CLEAR_REGNO_REG_SET (live_in, i); ++ } --/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ -+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */ - /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */ - /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ - /* { dg-final { scan-assembler "fcmle\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */ ---- a/src/gcc/testsuite/lib/target-supports.exp -+++ b/src/gcc/testsuite/lib/target-supports.exp -@@ -487,13 +487,6 @@ - return 0 - } +- /* Check whether BB clobbers SRC. We need to add INSN to BB if so. +- Either way, SRC is now live on entry. */ +- for (i = sregno; i < end_sregno; i++) +- { +- if (REGNO_REG_SET_P (bb_defs, i)) +- next_block = NULL; +- SET_REGNO_REG_SET (live_out, i); +- SET_REGNO_REG_SET (live_in, i); ++ for (i = sregno; i < end_sregno; i++) ++ { ++ SET_REGNO_REG_SET (live_out, i); ++ SET_REGNO_REG_SET (live_in, i); ++ } + } -- # We don't yet support profiling for AArch64. -- if { [istarget aarch64*-*-*] -- && ([lindex $test_what 1] == "-p" -- || [lindex $test_what 1] == "-pg") } { -- return 0 -- } -- - # cygwin does not support -p. - if { [istarget *-*-cygwin*] && $test_what == "-p" } { - return 0 -@@ -2012,6 +2005,7 @@ - || ([istarget powerpc*-*-*] - && ![istarget powerpc-*-linux*paired*]) - || [istarget x86_64-*-*] -+ || [istarget aarch64*-*-*] - || ([istarget arm*-*-*] - && [check_effective_target_arm_neon_ok])} { - set et_vect_uintfloat_cvt_saved 1 -@@ -2078,6 +2072,15 @@ - }] - } + /* If we don't need to add the move to BB, look for a single +--- a/src/gcc/coretypes.h ++++ b/src/gcc/coretypes.h +@@ -62,6 +62,8 @@ + typedef union gimple_statement_d *gimple; + typedef const union gimple_statement_d *const_gimple; + typedef gimple gimple_seq; ++struct gimple_stmt_iterator_d; ++typedef struct gimple_stmt_iterator_d gimple_stmt_iterator; + union section; + typedef union section section; + struct gcc_options; +--- a/src/gcc/lower-subreg.c ++++ b/src/gcc/lower-subreg.c +@@ -966,7 +966,20 @@ + rtx reg; -+# Return 1 if this is a AArch64 target supporting little endian -+proc check_effective_target_aarch64_little_endian { } { -+ return [check_no_compiler_messages aarch64_little_endian assembly { -+ #if !defined(__aarch64__) || defined(__AARCH64EB__) -+ #error FOO -+ #endif -+ }] -+} + reg = gen_reg_rtx (orig_mode); + - # Return 1 is this is an arm target using 32-bit instructions - proc check_effective_target_arm32 { } { - return [check_no_compiler_messages arm32 assembly { -@@ -2147,22 +2150,6 @@ ++#ifdef AUTO_INC_DEC ++ { ++ rtx move = emit_move_insn (reg, src); ++ if (MEM_P (src)) ++ { ++ rtx note = find_reg_note (insn, REG_INC, NULL_RTX); ++ if (note) ++ add_reg_note (move, REG_INC, XEXP (note, 0)); ++ } ++ } ++#else + emit_move_insn (reg, src); ++#endif + src = reg; } - } - --# Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8 --# -mfloat-abi=softfp --proc check_effective_target_arm_v8_neon_ok {} { -- if { [check_effective_target_arm32] } { -- return [check_no_compiler_messages arm_v8_neon_ok object { -- int foo (void) -- { -- __asm__ volatile ("vrintn.f32 q0, q0"); -- return 0; -- } -- } "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"] -- } else { -- return 0 -- } --} -- - # Return 1 if this is an ARM target supporting -mfpu=vfp - # -mfloat-abi=hard. Some multilibs may be incompatible with these - # options. -@@ -2202,6 +2189,49 @@ - }] - } -+# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8 -+# -mfloat-abi=softfp or equivalent options. Some multilibs may be -+# incompatible with these options. Also set et_arm_crypto_flags to the -+# best options to add. -+ -+proc check_effective_target_arm_crypto_ok_nocache { } { -+ global et_arm_crypto_flags -+ set et_arm_crypto_flags "" -+ if { [check_effective_target_arm32] } { -+ foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} { -+ if { [check_no_compiler_messages_nocache arm_crypto_ok object { -+ #include "arm_neon.h" -+ uint8x16_t -+ foo (uint8x16_t a, uint8x16_t b) -+ { -+ return vaeseq_u8 (a, b); -+ } -+ } "$flags"] } { -+ set et_arm_crypto_flags $flags -+ return 1 -+ } -+ } -+ } -+ -+ return 0 -+} -+ -+# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8 -+ -+proc check_effective_target_arm_crypto_ok { } { -+ return [check_cached_effective_target arm_crypto_ok \ -+ check_effective_target_arm_crypto_ok_nocache] -+} -+ -+# Add options for crypto extensions. -+proc add_options_for_arm_crypto { flags } { -+ if { ! [check_effective_target_arm_crypto_ok] } { -+ return "$flags" -+ } -+ global et_arm_crypto_flags -+ return "$flags $et_arm_crypto_flags" -+} -+ - # Add the options needed for NEON. We need either -mfloat-abi=softfp - # or -mfloat-abi=hard, but if one is already specified by the - # multilib, use it. Similarly, if a -mfpu option already enables -@@ -2226,9 +2256,18 @@ - if { ! [check_effective_target_arm_v8_neon_ok] } { - return "$flags" - } -- return "$flags -march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=softfp" -+ global et_arm_v8_neon_flags -+ return "$flags $et_arm_v8_neon_flags -march=armv8-a" - } +@@ -1056,6 +1069,16 @@ + mdest = simplify_gen_subreg (orig_mode, dest, GET_MODE (dest), 0); + minsn = emit_move_insn (real_dest, mdest); -+proc add_options_for_arm_crc { flags } { -+ if { ! [check_effective_target_arm_crc_ok] } { -+ return "$flags" ++#ifdef AUTO_INC_DEC ++ if (MEM_P (real_dest) ++ && !(resolve_reg_p (real_dest) || resolve_subreg_p (real_dest))) ++ { ++ rtx note = find_reg_note (insn, REG_INC, NULL_RTX); ++ if (note) ++ add_reg_note (minsn, REG_INC, XEXP (note, 0)); + } -+ global et_arm_crc_flags -+ return "$flags $et_arm_crc_flags" -+} ++#endif + - # Add the options needed for NEON. We need either -mfloat-abi=softfp - # or -mfloat-abi=hard, but if one is already specified by the - # multilib, use it. Similarly, if a -mfpu option already enables -@@ -2270,6 +2309,94 @@ - check_effective_target_arm_neon_ok_nocache] - } + smove = single_set (minsn); + gcc_assert (smove != NULL_RTX); -+proc check_effective_target_arm_crc_ok_nocache { } { -+ global et_arm_crc_flags -+ set et_arm_crc_flags "-march=armv8-a+crc" -+ return [check_no_compiler_messages_nocache arm_crc_ok object { -+ #if !defined (__ARM_FEATURE_CRC32) -+ #error FOO -+ #endif -+ } "$et_arm_crc_flags"] -+} -+ -+proc check_effective_target_arm_crc_ok { } { -+ return [check_cached_effective_target arm_crc_ok \ -+ check_effective_target_arm_crc_ok_nocache] -+} -+ -+# Return 1 if this is an ARM target supporting -mfpu=neon-fp16 -+# -mfloat-abi=softfp or equivalent options. Some multilibs may be -+# incompatible with these options. Also set et_arm_neon_flags to the -+# best options to add. -+ -+proc check_effective_target_arm_neon_fp16_ok_nocache { } { -+ global et_arm_neon_fp16_flags -+ set et_arm_neon_fp16_flags "" -+ if { [check_effective_target_arm32] } { -+ foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" -+ "-mfpu=neon-fp16 -mfloat-abi=softfp"} { -+ if { [check_no_compiler_messages_nocache arm_neon_fp_16_ok object { -+ #include "arm_neon.h" -+ float16x4_t -+ foo (float32x4_t arg) -+ { -+ return vcvt_f16_f32 (arg); -+ } -+ } "$flags"] } { -+ set et_arm_neon_fp16_flags $flags -+ return 1 -+ } -+ } -+ } -+ -+ return 0 -+} -+ -+proc check_effective_target_arm_neon_fp16_ok { } { -+ return [check_cached_effective_target arm_neon_fp16_ok \ -+ check_effective_target_arm_neon_fp16_ok_nocache] -+} -+ -+proc add_options_for_arm_neon_fp16 { flags } { -+ if { ! [check_effective_target_arm_neon_fp16_ok] } { -+ return "$flags" -+ } -+ global et_arm_neon_fp16_flags -+ return "$flags $et_arm_neon_fp16_flags" -+} -+ -+# Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8 -+# -mfloat-abi=softfp or equivalent options. Some multilibs may be -+# incompatible with these options. Also set et_arm_v8_neon_flags to the -+# best options to add. -+ -+proc check_effective_target_arm_v8_neon_ok_nocache { } { -+ global et_arm_v8_neon_flags -+ set et_arm_v8_neon_flags "" -+ if { [check_effective_target_arm32] } { -+ foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { -+ if { [check_no_compiler_messages_nocache arm_v8_neon_ok object { -+ #include "arm_neon.h" -+ void -+ foo () -+ { -+ __asm__ volatile ("vrintn.f32 q0, q0"); -+ } -+ } "$flags"] } { -+ set et_arm_v8_neon_flags $flags -+ return 1 -+ } -+ } -+ } -+ -+ return 0 -+} -+ -+proc check_effective_target_arm_v8_neon_ok { } { -+ return [check_cached_effective_target arm_v8_neon_ok \ -+ check_effective_target_arm_v8_neon_ok_nocache] -+} -+ - # Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4 - # -mfloat-abi=softfp or equivalent options. Some multilibs may be - # incompatible with these options. Also set et_arm_neonv2_flags to the -@@ -2332,6 +2459,11 @@ - # Must generate floating-point instructions. - return 0 +--- a/src/gcc/gimple-fold.c ++++ b/src/gcc/gimple-fold.c +@@ -1143,6 +1143,8 @@ + gimplify_and_update_call_from_tree (gsi, result); + changed = true; + } ++ else if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD) ++ changed |= targetm.gimple_fold_builtin (gsi); } -+ if [check_effective_target_arm_hf_eabi] { -+ # Use existing float-abi and force an fpu which supports fp16 -+ set et_arm_fp16_flags "-mfpu=vfpv4" -+ return 1; -+ } - if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] { - # The existing -mfpu value is OK; use it, but add softfp. - set et_arm_fp16_flags "-mfloat-abi=softfp" -@@ -2464,6 +2596,17 @@ - } ""] - } - -+# Return 1 if this is an ARM target where conditional execution is available. -+ -+proc check_effective_target_arm_cond_exec { } { -+ return [check_no_compiler_messages arm_cond_exec assembly { -+ #if defined(__arm__) && defined(__thumb__) && !defined(__thumb2__) -+ #error FOO -+ #endif -+ int i; -+ } ""] -+} -+ - # Return 1 if this is an ARM cortex-M profile cpu - - proc check_effective_target_arm_cortex_m { } { -@@ -2509,6 +2652,24 @@ - } [add_options_for_arm_neonv2 ""]] - } - -+# Return 1 if the target supports executing ARMv8 NEON instructions, 0 -+# otherwise. -+ -+proc check_effective_target_arm_v8_neon_hw { } { -+ return [check_runtime arm_v8_neon_hw_available { -+ #include "arm_neon.h" -+ int -+ main (void) -+ { -+ float32x2_t a; -+ asm ("vrinta.f32 %P0, %P1" -+ : "=w" (a) -+ : "0" (a)); -+ return 0; -+ } -+ } [add_options_for_arm_v8_neon ""]] -+} -+ - # Return 1 if this is a ARM target with NEON enabled. - - proc check_effective_target_arm_neon { } { -@@ -4591,6 +4752,33 @@ - return 0 - } - -+# Return 1 if programs are intended to be run on hardware rather than -+# on a simulator -+ -+proc check_effective_target_hw { } { -+ -+ # All "src/sim" simulators set this one. -+ if [board_info target exists is_simulator] { -+ if [board_info target is_simulator] { -+ return 0 -+ } else { -+ return 1 -+ } -+ } -+ -+ # The "sid" simulators don't set that one, but at least they set -+ # this one. -+ if [board_info target exists slow_simulator] { -+ if [board_info target slow_simulator] { -+ return 0 -+ } else { -+ return 1 -+ } -+ } -+ -+ return 1 -+} -+ - # Return 1 if the target is a VxWorks kernel. - proc check_effective_target_vxworks_kernel { } { ---- a/src/gcc/testsuite/ChangeLog.linaro -+++ b/src/gcc/testsuite/ChangeLog.linaro -@@ -0,0 +1,978 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206519 -+ 2014-01-10 Kyrylo Tkachov -+ -+ * lib/target-supports.exp -+ (check_effective_target_arm_crypto_ok_nocache): New. -+ (check_effective_target_arm_crypto_ok): Use above procedure. -+ (add_options_for_arm_crypto): Use et_arm_crypto_flags. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206151 -+ 2013-12-20 Kyrylo Tkachov -+ -+ * gcc.target/arm/neon-vceq_p64.c: New test. -+ * gcc.target/arm/neon-vtst_p64.c: Likewise. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206131 -+ 2013-12-04 Kyrylo Tkachov -+ -+ * lib/target-supports.exp (check_effective_target_arm_crypto_ok): -+ New procedure. -+ (add_options_for_arm_crypto): Likewise. -+ * gcc.target/arm/crypto-vaesdq_u8.c: New test. -+ * gcc.target/arm/crypto-vaeseq_u8.c: Likewise. -+ * gcc.target/arm/crypto-vaesimcq_u8.c: Likewise. -+ * gcc.target/arm/crypto-vaesmcq_u8.c: Likewise. -+ * gcc.target/arm/crypto-vldrq_p128.c: Likewise. -+ * gcc.target/arm/crypto-vmull_high_p64.c: Likewise. -+ * gcc.target/arm/crypto-vmullp64.c: Likewise. -+ * gcc.target/arm/crypto-vsha1cq_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha1h_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha1mq_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha1pq_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha1su0q_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha1su1q_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha256h2q_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha256hq_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha256su0q_u32.c: Likewise. -+ * gcc.target/arm/crypto-vsha256su1q_u32.c: Likewise. -+ * gcc.target/arm/crypto-vstrq_p128.c: Likewise. -+ * gcc.target/arm/neon/vbslQp64: Generate. -+ * gcc.target/arm/neon/vbslp64: Likewise. -+ * gcc.target/arm/neon/vcombinep64: Likewise. -+ * gcc.target/arm/neon/vcreatep64: Likewise. -+ * gcc.target/arm/neon/vdupQ_lanep64: Likewise. -+ * gcc.target/arm/neon/vdupQ_np64: Likewise. -+ * gcc.target/arm/neon/vdup_lanep64: Likewise. -+ * gcc.target/arm/neon/vdup_np64: Likewise. -+ * gcc.target/arm/neon/vextQp64: Likewise. -+ * gcc.target/arm/neon/vextp64: Likewise. -+ * gcc.target/arm/neon/vget_highp64: Likewise. -+ * gcc.target/arm/neon/vget_lowp64: Likewise. -+ * gcc.target/arm/neon/vld1Q_dupp64: Likewise. -+ * gcc.target/arm/neon/vld1Q_lanep64: Likewise. -+ * gcc.target/arm/neon/vld1Qp64: Likewise. -+ * gcc.target/arm/neon/vld1_dupp64: Likewise. -+ * gcc.target/arm/neon/vld1_lanep64: Likewise. -+ * gcc.target/arm/neon/vld1p64: Likewise. -+ * gcc.target/arm/neon/vld2_dupp64: Likewise. -+ * gcc.target/arm/neon/vld2p64: Likewise. -+ * gcc.target/arm/neon/vld3_dupp64: Likewise. -+ * gcc.target/arm/neon/vld3p64: Likewise. -+ * gcc.target/arm/neon/vld4_dupp64: Likewise. -+ * gcc.target/arm/neon/vld4p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQf32_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQf32_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_f32: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_p16: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_p8: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_s16: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_s32: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_s64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_s8: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_u16: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_u32: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_u64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp128_u8: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp16_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp16_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_f32: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_p16: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_p8: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_s16: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_s32: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_s64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_s8: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_u16: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_u32: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_u64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp64_u8: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp8_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQp8_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs16_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs16_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs32_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs32_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs64_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs64_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs8_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQs8_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu16_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu16_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu32_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu32_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu64_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu64_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu8_p128: Likewise. -+ * gcc.target/arm/neon/vreinterpretQu8_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretf32_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretp16_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_f32: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_p16: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_p8: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_s16: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_s32: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_s64: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_s8: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_u16: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_u32: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_u64: Likewise. -+ * gcc.target/arm/neon/vreinterpretp64_u8: Likewise. -+ * gcc.target/arm/neon/vreinterpretp8_p64: Likewise. -+ * gcc.target/arm/neon/vreinterprets16_p64: Likewise. -+ * gcc.target/arm/neon/vreinterprets32_p64: Likewise. -+ * gcc.target/arm/neon/vreinterprets64_p64: Likewise. -+ * gcc.target/arm/neon/vreinterprets8_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretu16_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretu32_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretu64_p64: Likewise. -+ * gcc.target/arm/neon/vreinterpretu8_p64: Likewise. -+ * gcc.target/arm/neon/vsliQ_np64: Likewise. -+ * gcc.target/arm/neon/vsli_np64: Likewise. -+ * gcc.target/arm/neon/vsriQ_np64: Likewise. -+ * gcc.target/arm/neon/vsri_np64: Likewise. -+ * gcc.target/arm/neon/vst1Q_lanep64: Likewise. -+ * gcc.target/arm/neon/vst1Qp64: Likewise. -+ * gcc.target/arm/neon/vst1_lanep64: Likewise. -+ * gcc.target/arm/neon/vst1p64: Likewise. -+ * gcc.target/arm/neon/vst2p64: Likewise. -+ * gcc.target/arm/neon/vst3p64: Likewise. -+ * gcc.target/arm/neon/vst4p64: Likewise. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206128 -+ 2013-12-19 Kyrylo Tkachov -+ -+ * lib/target-supports.exp (add_options_for_arm_crc): New procedure. -+ (check_effective_target_arm_crc_ok_nocache): Likewise. -+ (check_effective_target_arm_crc_ok): Likewise. -+ * gcc.target/arm/acle/: New directory. -+ * gcc.target/arm/acle/acle.exp: New. -+ * gcc.target/arm/acle/crc32b.c: New test. -+ * gcc.target/arm/acle/crc32h.c: Likewise. -+ * gcc.target/arm/acle/crc32w.c: Likewise. -+ * gcc.target/arm/acle/crc32d.c: Likewise. -+ * gcc.target/arm/acle/crc32cb.c: Likewise. -+ * gcc.target/arm/acle/crc32ch.c: Likewise. -+ * gcc.target/arm/acle/crc32cw.c: Likewise. -+ * gcc.target/arm/acle/crc32cd.c: Likewise. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206120 -+ 2013-12-19 Tejas Belagod -+ -+ * gcc.target/aarch64/pmull_1.c: New. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206119 -+ 2013-12-19 Tejas Belagod -+ -+ * gcc.target/aarch64/sha256_1.c: New. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206118 -+ 2013-12-19 Tejas Belagod -+ -+ * gcc.target/aarch64/sha1_1.c: New. -+ -+2014-02-10 Michael Collison -+ -+ Backport from trunk r206117 -+ 2013-12-19 Tejas Belagod -+ -+ * gcc.target/aarch64/aes_1.c: New. -+ -+2014-02-01 Christophe Lyon -+ -+ Backport from trunk r203057. -+ 2013-10-01 Kyrylo Tkachov -+ -+ PR tree-optimization/58556 -+ * gcc.dg/tree-ssa/gen-vect-26.c: Use dynamic vector cost model. -+ * gcc.dg/tree-ssa/gen-vect-28.c: Likewise. -+ -+2014-01-21 Zhenqiang Chen -+ -+ Backport from trunk r205509 and r200103 -+ 2013-11-29 Zhenqiang Chen -+ -+ * gcc.target/arm/lp1243022.c: Skip target arm-neon. -+ -+ Backport mainline r200103 -+ 2013-06-15 Jeff Law -+ -+ * gcc.dg/tree-ssa/coalesce-1.c: New test. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-12-06 Michael Collison -+ -+ Backport from trunk r202872. -+ 2013-09-24 Kyrylo Tkachov -+ -+ * lib/target-supports.exp (check_effective_target_arm_cond_exec): -+ New Procedure -+ * gcc.target/arm/minmax_minus.c: Check for cond_exec target. -+ -+2013-12-06 Christophe Lyon -+ -+ Backport from trunk r203327. -+ 2013-10-09 Zhenqiang Chen -+ -+ * gcc.dg/tree-ssa/phi-opt-11.c: New test. -+ -+2013-12-06 Charles Baylis -+ -+ Backport from trunk r203799. -+ 2013-10-17 Charles Bayis -+ -+ * gcc.dg/builtin-apply2.c: Skip test on arm hardfloat ABI -+ targets. -+ * gcc.dg/tls/pr42894.c: Remove dg-options for arm*-*-* targets. -+ * gcc.target/arm/thumb-ltu.c: Remove dg-skip-if and require -+ effective target arm_thumb1_ok. -+ * lib/target-supports.exp -+ (check_effective_target_arm_fp16_ok_nocache): Don't force -+ -mfloat-abi=soft when building for hardfloat target. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-11-06 Christophe Lyon -+ -+ Revert backport from trunk r197526. -+ 2013-04-05 Greta Yorsh -+ -+ * gcc.target/arm/negdi-1.c: New test. -+ * gcc.target/arm/negdi-2.c: Likewise. -+ * gcc.target/arm/negdi-3.c: Likewise. -+ * gcc.target/arm/negdi-4.c: Likewise. -+ -+2013-11-05 Zhenqiang Chen -+ -+ Backport from trunk r204247. -+ 2013-10-31 Zhenqiang Chen -+ -+ * gcc.target/arm/lp1243022.c: New test. -+ -+2013-11-04 Kugan Vivekanandarajah -+ -+ Backport from trunk r204336 -+ 2013-11-03 Kugan Vivekanandarajah -+ -+ * gcc.target/arm/neon-vcond-gt.c: Scan for vbsl or vbit or vbif. -+ * gcc.target/arm/neon-vcond-ltgt.c: Scan for vbsl or vbit or vbif. -+ * gcc.target/arm/neon-vcond-unordered.c: Scan for vbsl or vbit or -+ vbif. -+ + return changed; +--- a/src/gcc/lto/ChangeLog.linaro ++++ b/src/gcc/lto/ChangeLog.linaro +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + -+2013-10-09 Christophe Lyon -+ -+ Backport from trunk r198526,200595,200597. -+ 2013-05-02 Ian Bolton ++2013-09-10 Christophe Lyon + -+ * gcc.target/aarch64/bics_1.c: New test. -+ * gcc.target/aarch64/bics_2.c: Likewise. ++ GCC Linaro 4.8-2013.09 released. + -+ 2013-07-02 Ian Bolton ++2013-08-14 Christophe Lyon + -+ * gcc.target/aarch64/bfxil_1.c: New test. -+ * gcc.target/aarch64/bfxil_2.c: Likewise. ++ GCC Linaro 4.8-2013.08 released. + -+ 2013-07-02 Ian Bolton ++2013-07-19 Matthew Gretton-Dann + -+ * gcc.target/config/aarch64/insv_1.c: Update to show it doesn't work -+ on big endian. -+ * gcc.target/config/aarch64/insv_2.c: New test for big endian. -+ * lib/target-supports.exp: Define aarch64_little_endian. ++ GCC Linaro 4.8-2013.07-1 released. + -+2013-10-03 Christophe Lyon ++2013-07-05 Christophe Lyon + -+ Backport from trunk r202400. -+ 2013-09-09 Kyrylo Tkachov ++ GCC Linaro 4.8-2013.07 released. + -+ * gcc.target/aarch64/cmn-neg.c: New test. ++2013-06-11 Rob Savoye + -+2013-10-03 Christophe Lyon ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+ Backport from trunk r202164. -+ 2013-09-02 Bin Cheng ++2013-05-14 Matthew Gretton-Dann + -+ * gcc.target/arm/ivopts-orig_biv-inc.c: New testcase. ++ GCC Linaro 4.8-2013.05 released. + -+2013-10-01 Kugan Vivekanandarajah ++2013-04-09 Matthew Gretton-Dann + -+ Backport from trunk r203059,203116. -+ 2013-10-01 Kugan Vivekanandarajah ++ * GCC Linaro 4.8-2013.04 released. +--- a/src/gcc/po/ChangeLog.linaro ++++ b/src/gcc/po/ChangeLog.linaro +@@ -0,0 +1,31 @@ ++2013-10-15 Christophe Lyon + -+ PR Target/58578 -+ * gcc.target/arm/pr58578.c: New test. ++ GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-09-06 Venkataramanan Kumar -+ -+ Backport from trunk r201411. -+ 2013-08-01 Kyrylo Tkachov -+ -+ * gcc.target/arm/pr46972-2.c: New test. -+ -+2013-09-05 Yvan Roux -+ -+ Backport from trunk r201267. -+ 2013-07-26 Kyrylo Tkachov -+ -+ * gcc.target/arm/minmax_minus.c: Scan for absence of mov. -+ -+2013-09-05 Christophe Lyon ++ GCC Linaro 4.8-2013.09 released. + -+ Backport from trunk r199527,199814,201435. -+ 2013-05-31 Kyrylo Tkachov ++2013-08-14 Christophe Lyon + -+ PR target/56315 -+ * gcc.target/arm/iordi3-opt.c: New test. ++ GCC Linaro 4.8-2013.08 released. + -+ 2013-06-07 Kyrylo Tkachov ++2013-07-19 Matthew Gretton-Dann + -+ PR target/56315 -+ * gcc.target/arm/xordi3-opt.c: New test. ++ GCC Linaro 4.8-2013.07-1 released. + -+ 2013-08-02 Kyrylo Tkachov ++2013-07-05 Christophe Lyon + -+ * gcc.target/arm/neon-for-64bits-2.c: Delete. ++ GCC Linaro 4.8-2013.07 released. + -+2013-09-05 Christophe Lyon ++2013-06-11 Rob Savoye + -+ Backport from trunk r201730,201731. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + -+ 2013-08-14 Janis Johnson ++2013-05-14 Matthew Gretton-Dann + -+ * gcc.target/arm/atomic-comp-swap-release-acquire.c: Move dg-do -+ to be the first test directive. -+ * gcc.target/arm/atomic-op-acq_rel.c: Likewise. -+ * gcc.target/arm/atomic-op-acquire.c: Likewise. -+ * gcc.target/arm/atomic-op-char.c: Likewise. -+ * gcc.target/arm/atomic-op-consume.c: Likewise. -+ * gcc.target/arm/atomic-op-int.c: Likewise. -+ * gcc.target/arm/atomic-op-relaxed.c: Likewise. -+ * gcc.target/arm/atomic-op-release.c: Likewise. -+ * gcc.target/arm/atomic-op-seq_cst.c: Likewise. -+ * gcc.target/arm/atomic-op-short.c: Likewise. ++ GCC Linaro 4.8-2013.05 released. + -+ 2013-08-14 Janis Johnson ++2013-04-09 Matthew Gretton-Dann + -+ * gcc.target/arm/pr19599.c: Skip for -mthumb. ++ * GCC Linaro 4.8-2013.04 released. +--- a/src/gcc/combine.c ++++ b/src/gcc/combine.c +@@ -11989,6 +11989,13 @@ + } + } + ++ /* We may have changed the comparison operands. Re-canonicalize. */ ++ if (swap_commutative_operands_p (op0, op1)) ++ { ++ tem = op0, op0 = op1, op1 = tem; ++ code = swap_condition (code); ++ } + -+2013-09-03 Venkataramanan Kumar -+ -+ Backport from trunk r201624. -+ 2013-08-09 James Greenhalgh -+ -+ * gcc.target/aarch64/scalar_intrinsics.c: Update expected -+ output of vdup intrinsics -+ -+2013-08-26 Kugan Vivekanandarajah -+ -+ Backport from trunk r201636. -+ 2013-08-09 Yufeng Zhang + /* If this machine only supports a subset of valid comparisons, see if we + can convert an unsupported one into a supported one. */ + target_canonicalize_comparison (&code, &op0, &op1, 0); +--- a/src/gcc/config.gcc ++++ b/src/gcc/config.gcc +@@ -329,6 +329,7 @@ + target_type_format_char='%' + c_target_objs="arm-c.o" + cxx_target_objs="arm-c.o" ++ need_64bit_hwint=yes + extra_options="${extra_options} arm/arm-tables.opt" + ;; + avr-*-*) +@@ -885,10 +886,6 @@ + tmake_file="$tmake_file arm/t-linux-androideabi" + ;; + esac +- # The BPABI long long divmod functions return a 128-bit value in +- # registers r0-r3. Correctly modeling that requires the use of +- # TImode. +- need_64bit_hwint=yes + # The EABI requires the use of __cxa_atexit. + default_use_cxa_atexit=yes + with_tls=${with_tls:-gnu} +@@ -897,10 +894,6 @@ + tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h glibc-stdint.h" + tmake_file="arm/t-arm arm/t-arm-elf arm/t-bpabi" + tm_file="$tm_file arm/bpabi.h arm/uclinux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h" +- # The BPABI long long divmod functions return a 128-bit value in +- # registers r0-r3. Correctly modeling that requires the use of +- # TImode. +- need_64bit_hwint=yes + # The EABI requires the use of __cxa_atexit. + default_use_cxa_atexit=yes + ;; +@@ -909,10 +902,6 @@ + arm*eb-*-eabi*) + tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" + esac +- # The BPABI long long divmod functions return a 128-bit value in +- # registers r0-r3. Correctly modeling that requires the use of +- # TImode. +- need_64bit_hwint=yes + default_use_cxa_atexit=yes + tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/bpabi.h" + tmake_file="arm/t-arm arm/t-arm-elf" +@@ -3295,6 +3284,43 @@ + if test "x$with_arch" != x && test "x$with_cpu" != x; then + echo "Warning: --with-arch overrides --with-cpu=$with_cpu" 1>&2 + fi + -+ * gcc.dg/lower-subreg-1.c: Skip aarch64*-*-*. ++ # Add extra multilibs ++ if test "x$with_multilib_list" != x; then ++ arm_multilibs=`echo $with_multilib_list | sed -e 's/,/ /g'` ++ for arm_multilib in ${arm_multilibs}; do ++ case ${arm_multilib} in ++ aprofile) ++ # Note that arm/t-aprofile is a ++ # stand-alone make file fragment to be ++ # used only with itself. We do not ++ # specifically use the ++ # TM_MULTILIB_OPTION framework because ++ # this shorthand is more ++ # pragmatic. Additionally it is only ++ # designed to work without any ++ # with-cpu, with-arch with-mode ++ # with-fpu or with-float options. ++ if test "x$with_arch" != x \ ++ || test "x$with_cpu" != x \ ++ || test "x$with_float" != x \ ++ || test "x$with_fpu" != x \ ++ || test "x$with_mode" != x ; then ++ echo "Error: You cannot use any of --with-arch/cpu/fpu/float/mode with --with-multilib-list=aprofile" 1>&2 ++ exit 1 ++ fi ++ tmake_file="${tmake_file} arm/t-aprofile" ++ break ++ ;; ++ default) ++ ;; ++ *) ++ echo "Error: --with-multilib-list=${with_multilib_list} not supported." 1>&2 ++ exit 1 ++ ;; ++ esac ++ done ++ fi + ;; + + fr*-*-*linux*) +--- a/src/gcc/gimple.h ++++ b/src/gcc/gimple.h +@@ -130,7 +130,7 @@ + + /* Iterator object for GIMPLE statement sequences. */ + +-typedef struct ++struct gimple_stmt_iterator_d + { + /* Sequence node holding the current statement. */ + gimple_seq_node ptr; +@@ -141,9 +141,8 @@ + block/sequence is removed. */ + gimple_seq *seq; + basic_block bb; +-} gimple_stmt_iterator; ++}; + +- + /* Data structure definitions for GIMPLE tuples. NOTE: word markers + are for 64 bit hosts. */ + +--- a/src/gcc/config/i386/linux-common.h ++++ b/src/gcc/config/i386/linux-common.h +@@ -40,7 +40,7 @@ + #undef LIB_SPEC + #define LIB_SPEC \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \ +- GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC) ++ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC " " ANDROID_LIB_SPEC) + + #undef STARTFILE_SPEC + #define STARTFILE_SPEC \ +--- a/src/gcc/config/gnu-user.h ++++ b/src/gcc/config/gnu-user.h +@@ -73,10 +73,14 @@ + #undef CPLUSPLUS_CPP_SPEC + #define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" + ++#define GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC \ ++ "%{shared:-lc} \ ++ %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}" + -+2013-08-14 Christophe Lyon + #define GNU_USER_TARGET_LIB_SPEC \ +- "%{pthread:-lpthread} \ +- %{shared:-lc} \ +- %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}" ++ "%{pthread:-lpthread} " \ ++ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC + -+ GCC Linaro 4.8-2013.08 released. + #undef LIB_SPEC + #define LIB_SPEC GNU_USER_TARGET_LIB_SPEC + +--- a/src/gcc/config/aarch64/aarch64-simd.md ++++ b/src/gcc/config/aarch64/aarch64-simd.md +@@ -21,7 +21,7 @@ + + ; Main data types used by the insntructions + +-(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,HI,QI" ++(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,SF,HI,QI" + (const_string "unknown")) + + +@@ -44,6 +44,7 @@ + ; simd_dup duplicate element. + ; simd_dupgp duplicate general purpose register. + ; simd_ext bitwise extract from pair. ++; simd_fabd floating point absolute difference. + ; simd_fadd floating point add/sub. + ; simd_fcmp floating point compare. + ; simd_fcvti floating point convert to integer. +@@ -58,9 +59,9 @@ + ; simd_fmul floating point multiply. + ; simd_fmul_elt floating point multiply (by element). + ; simd_fnegabs floating point neg/abs. +-; simd_frcpe floating point reciprocal estimate. +-; simd_frcps floating point reciprocal step. +-; simd_frecx floating point reciprocal exponent. ++; simd_frecpe floating point reciprocal estimate. ++; simd_frecps floating point reciprocal step. ++; simd_frecpx floating point reciprocal exponent. + ; simd_frint floating point round to integer. + ; simd_fsqrt floating point square root. + ; simd_icvtf integer convert to floating point. +@@ -147,6 +148,7 @@ + simd_dup,\ + simd_dupgp,\ + simd_ext,\ ++ simd_fabd,\ + simd_fadd,\ + simd_fcmp,\ + simd_fcvti,\ +@@ -161,9 +163,9 @@ + simd_fmul,\ + simd_fmul_elt,\ + simd_fnegabs,\ +- simd_frcpe,\ +- simd_frcps,\ +- simd_frecx,\ ++ simd_frecpe,\ ++ simd_frecps,\ ++ simd_frecpx,\ + simd_frint,\ + simd_fsqrt,\ + simd_icvtf,\ +@@ -303,8 +305,8 @@ + (eq_attr "simd_type" "simd_store3,simd_store4") (const_string "neon_vst1_3_4_regs") + (eq_attr "simd_type" "simd_store1s,simd_store2s") (const_string "neon_vst1_vst2_lane") + (eq_attr "simd_type" "simd_store3s,simd_store4s") (const_string "neon_vst3_vst4_lane") +- (and (eq_attr "simd_type" "simd_frcpe,simd_frcps") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vrecps_vrsqrts_ddd") +- (and (eq_attr "simd_type" "simd_frcpe,simd_frcps") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vrecps_vrsqrts_qqq") ++ (and (eq_attr "simd_type" "simd_frecpe,simd_frecps") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vrecps_vrsqrts_ddd") ++ (and (eq_attr "simd_type" "simd_frecpe,simd_frecps") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vrecps_vrsqrts_qqq") + (eq_attr "simd_type" "none") (const_string "none") + ] + (const_string "unknown"))) +@@ -355,18 +357,6 @@ + (set_attr "simd_mode" "")] + ) + +-(define_insn "aarch64_dup_lane" +- [(set (match_operand:SDQ_I 0 "register_operand" "=w") +- (vec_select: +- (match_operand: 1 "register_operand" "w") +- (parallel [(match_operand:SI 2 "immediate_operand" "i")]) +- ))] +- "TARGET_SIMD" +- "dup\\t%0, %1.[%2]" +- [(set_attr "simd_type" "simd_dup") +- (set_attr "simd_mode" "")] +-) +- + (define_insn "aarch64_simd_dup" + [(set (match_operand:VDQF 0 "register_operand" "=w") + (vec_duplicate:VDQF (match_operand: 1 "register_operand" "w")))] +@@ -394,7 +384,7 @@ + case 4: return "ins\t%0.d[0], %1"; + case 5: return "mov\t%0, %1"; + case 6: +- return aarch64_output_simd_mov_immediate (&operands[1], ++ return aarch64_output_simd_mov_immediate (operands[1], + mode, 64); + default: gcc_unreachable (); + } +@@ -414,16 +404,20 @@ + { + switch (which_alternative) + { +- case 0: return "ld1\t{%0.}, %1"; +- case 1: return "st1\t{%1.}, %0"; +- case 2: return "orr\t%0., %1., %1."; +- case 3: return "umov\t%0, %1.d[0]\;umov\t%H0, %1.d[1]"; +- case 4: return "ins\t%0.d[0], %1\;ins\t%0.d[1], %H1"; +- case 5: return "#"; ++ case 0: ++ return "ld1\t{%0.}, %1"; ++ case 1: ++ return "st1\t{%1.}, %0"; ++ case 2: ++ return "orr\t%0., %1., %1."; ++ case 3: ++ case 4: ++ case 5: ++ return "#"; + case 6: +- return aarch64_output_simd_mov_immediate (&operands[1], +- mode, 128); +- default: gcc_unreachable (); ++ return aarch64_output_simd_mov_immediate (operands[1], mode, 128); ++ default: ++ gcc_unreachable (); + } + } + [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm") +@@ -452,6 +446,77 @@ + aarch64_simd_disambiguate_copy (operands, dest, src, 2); + }) + ++(define_split ++ [(set (match_operand:VQ 0 "register_operand" "") ++ (match_operand:VQ 1 "register_operand" ""))] ++ "TARGET_SIMD && reload_completed ++ && ((FP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1]))) ++ || (GP_REGNUM_P (REGNO (operands[0])) && FP_REGNUM_P (REGNO (operands[1]))))" ++ [(const_int 0)] ++{ ++ aarch64_split_simd_move (operands[0], operands[1]); ++ DONE; ++}) + -+2013-08-07 Christophe Lyon ++(define_expand "aarch64_split_simd_mov" ++ [(set (match_operand:VQ 0) ++ (match_operand:VQ 1))] ++ "TARGET_SIMD" ++ { ++ rtx dst = operands[0]; ++ rtx src = operands[1]; + -+ Backport from trunk r199720 -+ 2013-06-06 Marcus Shawcroft ++ if (GP_REGNUM_P (REGNO (src))) ++ { ++ rtx src_low_part = gen_lowpart (mode, src); ++ rtx src_high_part = gen_highpart (mode, src); + -+ * gcc.dg/vect/no-section-anchors-vect-68.c: -+ Add dg-skip-if aarch64_tiny. ++ emit_insn ++ (gen_move_lo_quad_ (dst, src_low_part)); ++ emit_insn ++ (gen_move_hi_quad_ (dst, src_high_part)); ++ } + -+2013-08-07 Christophe Lyon ++ else ++ { ++ rtx dst_low_part = gen_lowpart (mode, dst); ++ rtx dst_high_part = gen_highpart (mode, dst); ++ rtx lo = aarch64_simd_vect_par_cnst_half (mode, false); ++ rtx hi = aarch64_simd_vect_par_cnst_half (mode, true); + -+ Backport from trunk r201237. -+ 2013-07-25 Terry Guo ++ emit_insn ++ (gen_aarch64_simd_mov_from_low (dst_low_part, src, lo)); ++ emit_insn ++ (gen_aarch64_simd_mov_from_high (dst_high_part, src, hi)); ++ } ++ DONE; ++ } ++) + -+ * gcc.target/arm/thumb1-Os-mult.c: New test case. ++(define_insn "aarch64_simd_mov_from_low" ++ [(set (match_operand: 0 "register_operand" "=r") ++ (vec_select: ++ (match_operand:VQ 1 "register_operand" "w") ++ (match_operand:VQ 2 "vect_par_cnst_lo_half" "")))] ++ "TARGET_SIMD && reload_completed" ++ "umov\t%0, %1.d[0]" ++ [(set_attr "simd_type" "simd_movgp") ++ (set_attr "simd_mode" "") ++ (set_attr "length" "4") ++ ]) + -+2013-08-06 Christophe Lyon ++(define_insn "aarch64_simd_mov_from_high" ++ [(set (match_operand: 0 "register_operand" "=r") ++ (vec_select: ++ (match_operand:VQ 1 "register_operand" "w") ++ (match_operand:VQ 2 "vect_par_cnst_hi_half" "")))] ++ "TARGET_SIMD && reload_completed" ++ "umov\t%0, %1.d[1]" ++ [(set_attr "simd_type" "simd_movgp") ++ (set_attr "simd_mode" "") ++ (set_attr "length" "4") ++ ]) + -+ Backport from trunk r200596,201067,201083. -+ 2013-07-02 Ian Bolton + (define_insn "orn3" + [(set (match_operand:VDQ 0 "register_operand" "=w") + (ior:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w")) +@@ -503,8 +568,8 @@ + ) + + (define_insn "neg2" +- [(set (match_operand:VDQM 0 "register_operand" "=w") +- (neg:VDQM (match_operand:VDQM 1 "register_operand" "w")))] ++ [(set (match_operand:VDQ 0 "register_operand" "=w") ++ (neg:VDQ (match_operand:VDQ 1 "register_operand" "w")))] + "TARGET_SIMD" + "neg\t%0., %1." + [(set_attr "simd_type" "simd_negabs") +@@ -520,6 +585,51 @@ + (set_attr "simd_mode" "")] + ) + ++(define_insn "abd_3" ++ [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") ++ (abs:VDQ_BHSI (minus:VDQ_BHSI ++ (match_operand:VDQ_BHSI 1 "register_operand" "w") ++ (match_operand:VDQ_BHSI 2 "register_operand" "w"))))] ++ "TARGET_SIMD" ++ "sabd\t%0., %1., %2." ++ [(set_attr "simd_type" "simd_abd") ++ (set_attr "simd_mode" "")] ++) + -+ * gcc.target/aarch64/abs_1.c: New test. ++(define_insn "aba_3" ++ [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") ++ (plus:VDQ_BHSI (abs:VDQ_BHSI (minus:VDQ_BHSI ++ (match_operand:VDQ_BHSI 1 "register_operand" "w") ++ (match_operand:VDQ_BHSI 2 "register_operand" "w"))) ++ (match_operand:VDQ_BHSI 3 "register_operand" "0")))] ++ "TARGET_SIMD" ++ "saba\t%0., %1., %2." ++ [(set_attr "simd_type" "simd_abd") ++ (set_attr "simd_mode" "")] ++) + -+ 2013-07-19 Ian Bolton ++(define_insn "fabd_3" ++ [(set (match_operand:VDQF 0 "register_operand" "=w") ++ (abs:VDQF (minus:VDQF ++ (match_operand:VDQF 1 "register_operand" "w") ++ (match_operand:VDQF 2 "register_operand" "w"))))] ++ "TARGET_SIMD" ++ "fabd\t%0., %1., %2." ++ [(set_attr "simd_type" "simd_fabd") ++ (set_attr "simd_mode" "")] ++) + -+ * gcc.target/aarch64/scalar_intrinsics.c (test_vabs_s64): Added -+ new testcase. ++(define_insn "*fabd_scalar3" ++ [(set (match_operand:GPF 0 "register_operand" "=w") ++ (abs:GPF (minus:GPF ++ (match_operand:GPF 1 "register_operand" "w") ++ (match_operand:GPF 2 "register_operand" "w"))))] ++ "TARGET_SIMD" ++ "fabd\t%0, %1, %2" ++ [(set_attr "simd_type" "simd_fabd") ++ (set_attr "mode" "")] ++) + -+ 2013-07-20 James Greenhalgh + (define_insn "and3" + [(set (match_operand:VDQ 0 "register_operand" "=w") + (and:VDQ (match_operand:VDQ 1 "register_operand" "w") +@@ -904,12 +1014,12 @@ + ) + + ;; Max/Min operations. +-(define_insn "3" ++(define_insn "3" + [(set (match_operand:VQ_S 0 "register_operand" "=w") + (MAXMIN:VQ_S (match_operand:VQ_S 1 "register_operand" "w") + (match_operand:VQ_S 2 "register_operand" "w")))] + "TARGET_SIMD" +- "\t%0., %1., %2." ++ "\t%0., %1., %2." + [(set_attr "simd_type" "simd_minmax") + (set_attr "simd_mode" "")] + ) +@@ -917,29 +1027,39 @@ + ;; Move into low-half clearing high half to 0. + + (define_insn "move_lo_quad_" +- [(set (match_operand:VQ 0 "register_operand" "=w") ++ [(set (match_operand:VQ 0 "register_operand" "=w,w,w") + (vec_concat:VQ +- (match_operand: 1 "register_operand" "w") ++ (match_operand: 1 "register_operand" "w,r,r") + (vec_duplicate: (const_int 0))))] + "TARGET_SIMD" +- "mov\\t%d0, %d1"; +- [(set_attr "simd_type" "simd_dup") +- (set_attr "simd_mode" "")] ++ "@ ++ dup\\t%d0, %1.d[0] ++ fmov\\t%d0, %1 ++ dup\\t%d0, %1" ++ [(set_attr "v8type" "*,fmov,*") ++ (set_attr "simd_type" "simd_dup,*,simd_dup") ++ (set_attr "simd_mode" "") ++ (set_attr "simd" "yes,*,yes") ++ (set_attr "fp" "*,yes,*") ++ (set_attr "length" "4")] + ) + + ;; Move into high-half. + + (define_insn "aarch64_simd_move_hi_quad_" +- [(set (match_operand:VQ 0 "register_operand" "+w") ++ [(set (match_operand:VQ 0 "register_operand" "+w,w") + (vec_concat:VQ + (vec_select: + (match_dup 0) + (match_operand:VQ 2 "vect_par_cnst_lo_half" "")) +- (match_operand: 1 "register_operand" "w")))] ++ (match_operand: 1 "register_operand" "w,r")))] + "TARGET_SIMD" +- "ins\\t%0.d[1], %1.d[0]"; +- [(set_attr "simd_type" "simd_ins") +- (set_attr "simd_mode" "")] ++ "@ ++ ins\\t%0.d[1], %1.d[0] ++ ins\\t%0.d[1], %1" ++ [(set_attr "simd_type" "simd_ins,simd_ins") ++ (set_attr "simd_mode" "") ++ (set_attr "length" "4")] + ) + + (define_expand "move_hi_quad_" +@@ -1045,6 +1165,104 @@ + + ;; Widening arithmetic. + ++(define_insn "*aarch64_mlal_lo" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (plus: ++ (mult: ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 2 "register_operand" "w") ++ (match_operand:VQW 3 "vect_par_cnst_lo_half" ""))) ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 4 "register_operand" "w") ++ (match_dup 3)))) ++ (match_operand: 1 "register_operand" "0")))] ++ "TARGET_SIMD" ++ "mlal\t%0., %2., %4." ++ [(set_attr "simd_type" "simd_mlal") ++ (set_attr "simd_mode" "")] ++) + -+ * gcc.target/aarch64/vabs_intrinsic_1.c: New file. ++(define_insn "*aarch64_mlal_hi" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (plus: ++ (mult: ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 2 "register_operand" "w") ++ (match_operand:VQW 3 "vect_par_cnst_hi_half" ""))) ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 4 "register_operand" "w") ++ (match_dup 3)))) ++ (match_operand: 1 "register_operand" "0")))] ++ "TARGET_SIMD" ++ "mlal2\t%0., %2., %4." ++ [(set_attr "simd_type" "simd_mlal") ++ (set_attr "simd_mode" "")] ++) + -+2013-08-06 Christophe Lyon -+ -+ Backport from trunk r198864. -+ 2013-05-07 Ian Bolton -+ -+ * gcc.target/aarch64/ands_1.c: New test. -+ * gcc.target/aarch64/ands_2.c: Likewise -+ -+2013-08-06 Christophe Lyon -+ -+ Backport from trunk r199439,199533,201326. -+ -+ 2013-05-30 Zhenqiang Chen -+ -+ * gcc.dg/shrink-wrap-alloca.c: New added. -+ * gcc.dg/shrink-wrap-pretend.c: New added. -+ * gcc.dg/shrink-wrap-sibcall.c: New added. -+ -+ 2013-05-31 Rainer Orth -+ -+ * gcc.dg/shrink-wrap-alloca.c: Use __builtin_alloca. -+ -+ 2013-07-30 Zhenqiang Chen -+ -+ * gcc.target/arm/pr57637.c: New testcase. -+ -+2013-08-06 Christophe Lyon -+ -+ Backport from trunk r198928,198973,199203,201240,201241. -+ 2013-05-15 Ramana Radhakrishnan -+ -+ PR target/19599 -+ * gcc.target/arm/pr40887.c: Adjust testcase. -+ * gcc.target/arm/pr19599.c: New test. -+ -+2013-08-05 Yvan Roux -+ -+ Backport from trunk r200922. -+ 2013-07-12 Tejas Belagod -+ -+ * gcc.target/aarch64/vect-movi.c: New. -+ -+2013-08-05 Yvan Roux -+ -+ Backport from trunk r200720. -+ 2013-07-05 Marcus Shawcroft -+ -+ * gcc.dg/pr57518.c: Adjust scan-rtl-dump-not pattern. -+ -+2013-07-21 Yvan Roux -+ -+ Backport from trunk r200204. -+ 2013-06-19 Yufeng Zhang -+ -+ * gcc.dg/torture/stackalign/builtin-apply-2.c: set -+ STACK_ARGUMENTS_SIZE with 0 if __aarch64__ is defined. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-07-03 Christophe Lyon -+ -+ Revert backport from trunk r198928. -+ 2013-05-15 Ramana Radhakrishnan -+ -+ PR target/19599 -+ * gcc.target/arm/pr40887.c: Adjust testcase. -+ * gcc.target/arm/pr19599.c: New test. -+ -+2013-07-03 Christophe Lyon -+ -+ Revert backport from trunk 199439, 199533 -+ 2013-05-31 Rainer Orth -+ -+ * gcc.dg/shrink-wrap-alloca.c: Use __builtin_alloca. -+ -+ 2013-05-30 Zhenqiang Chen -+ -+ * gcc.dg/shrink-wrap-alloca.c: New added. -+ * gcc.dg/shrink-wrap-pretend.c: New added. -+ * gcc.dg/shrink-wrap-sibcall.c: New added. -+ -+2013-07-02 Rob Savoye -+ -+ Backport from trunk 200096 -+ -+ 2013-06-14 Vidya Praveen -+ -+ * gcc.target/aarch64/vect_smlal_1.c: New file. -+ -+2013-07-02 Rob Savoye -+ -+ Backport from trunk 200019 -+ 2013-06-12 Ramana Radhakrishnan -+ -+ * gcc.target/arm/unaligned-memcpy-4.c (src, dst): Initialize -+ to ensure alignment. -+ * gcc.target/arm/unaligned-memcpy-3.c (src): Likewise. -+ -+2013-06-20 Rob Savoye -+ -+ Backport from trunk 200152 -+ 2013-06-17 Sofiane Naci -+ -+ * gcc.target/aarch64/scalar_intrinsics.c: Update. -+ -+2013-06-20 Rob Savoye -+ -+ Backport from trunk 200148 -+ 2013-06-17 Kyrylo Tkachov -+ -+ * gcc.target/arm/unaligned-memcpy-2.c (dest): Initialize to -+ ensure alignment. -+ -+2013-06-20 Rob Savoye -+ -+ Backport from trunk 199533 -+ 2013-05-31 Rainer Orth -+ -+ * gcc.dg/shrink-wrap-alloca.c: Use __builtin_alloca. -+ -+2013-06-20 Christophe Lyon -+ -+ Backport from trunk r198683. -+ 2013-05-07 Christophe Lyon -+ -+ * lib/target-supports.exp (check_effective_target_hw): New -+ function. -+ * c-c++-common/asan/clone-test-1.c: Call -+ check_effective_target_hw. -+ * c-c++-common/asan/rlimit-mmap-test-1.c: Likewise. -+ * c-c++-common/asan/heap-overflow-1.c: Update regexps to accept -+ possible decorations. -+ * c-c++-common/asan/null-deref-1.c: Likewise. -+ * c-c++-common/asan/stack-overflow-1.c: Likewise. -+ * c-c++-common/asan/strncpy-overflow-1.c: Likewise. -+ * c-c++-common/asan/use-after-free-1.c: Likewise. -+ * g++.dg/asan/deep-thread-stack-1.C: Likewise. -+ * g++.dg/asan/large-func-test-1.C: Likewise. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-06-06 Zhenqiang Chen -+ -+ Backport from mainline r199439. -+ 2013-05-30 Zhenqiang Chen -+ -+ * gcc.dg/shrink-wrap-alloca.c: New added. -+ * gcc.dg/shrink-wrap-pretend.c: New added. -+ * gcc.dg/shrink-wrap-sibcall.c: New added. -+ -+2013-06-05 Christophe Lyon -+ -+ Backport from trunk r199658. -+ 2013-06-04 Ian Bolton -+ -+ * gcc.target/aarch64/movi_1.c: New test. -+ -+2013-06-04 Christophe Lyon -+ -+ Backport from trunk r199261. -+ 2013-05-23 Christian Bruel -+ -+ PR debug/57351 -+ * gcc.dg/debug/pr57351.c: New test -+ -+2013-06-03 Christophe Lyon -+ Backport from trunk r198890,199254,199294,199454. -+ -+ 2013-05-30 Ian Bolton -+ -+ * gcc.target/aarch64/insv_1.c: New test. -+ -+ 2013-05-24 Ian Bolton ++(define_insn "*aarch64_mlsl_lo" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (minus: ++ (match_operand: 1 "register_operand" "0") ++ (mult: ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 2 "register_operand" "w") ++ (match_operand:VQW 3 "vect_par_cnst_lo_half" ""))) ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 4 "register_operand" "w") ++ (match_dup 3))))))] ++ "TARGET_SIMD" ++ "mlsl\t%0., %2., %4." ++ [(set_attr "simd_type" "simd_mlal") ++ (set_attr "simd_mode" "")] ++) + -+ * gcc.target/aarch64/scalar_intrinsics.c -+ (force_simd): Use a valid instruction. -+ (test_vdupd_lane_s64): Pass a valid lane argument. -+ (test_vdupd_lane_u64): Likewise. ++(define_insn "*aarch64_mlsl_hi" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (minus: ++ (match_operand: 1 "register_operand" "0") ++ (mult: ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 2 "register_operand" "w") ++ (match_operand:VQW 3 "vect_par_cnst_hi_half" ""))) ++ (ANY_EXTEND: (vec_select: ++ (match_operand:VQW 4 "register_operand" "w") ++ (match_dup 3))))))] ++ "TARGET_SIMD" ++ "mlsl2\t%0., %2., %4." ++ [(set_attr "simd_type" "simd_mlal") ++ (set_attr "simd_mode" "")] ++) + -+ 2013-05-23 Vidya Praveen ++(define_insn "*aarch64_mlal" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (plus: ++ (mult: ++ (ANY_EXTEND: ++ (match_operand:VDW 1 "register_operand" "w")) ++ (ANY_EXTEND: ++ (match_operand:VDW 2 "register_operand" "w"))) ++ (match_operand: 3 "register_operand" "0")))] ++ "TARGET_SIMD" ++ "mlal\t%0., %1., %2." ++ [(set_attr "simd_type" "simd_mlal") ++ (set_attr "simd_mode" "")] ++) + -+ * gcc.target/aarch64/vect-clz.c: New file. ++(define_insn "*aarch64_mlsl" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (minus: ++ (match_operand: 1 "register_operand" "0") ++ (mult: ++ (ANY_EXTEND: ++ (match_operand:VDW 2 "register_operand" "w")) ++ (ANY_EXTEND: ++ (match_operand:VDW 3 "register_operand" "w")))))] ++ "TARGET_SIMD" ++ "mlsl\t%0., %2., %3." ++ [(set_attr "simd_type" "simd_mlal") ++ (set_attr "simd_mode" "")] ++) + -+ 2013-05-14 James Greenhalgh + (define_insn "aarch64_simd_vec_mult_lo_" + [(set (match_operand: 0 "register_operand" "=w") + (mult: (ANY_EXTEND: (vec_select: +@@ -1196,7 +1414,9 @@ + (set_attr "simd_mode" "")] + ) + +-(define_insn "aarch64_frint" ++;; Vector versions of the floating-point frint patterns. ++;; Expands to btrunc, ceil, floor, nearbyint, rint, round. ++(define_insn "2" + [(set (match_operand:VDQF 0 "register_operand" "=w") + (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")] + FRINT))] +@@ -1206,16 +1426,9 @@ + (set_attr "simd_mode" "")] + ) + +-;; Vector versions of the floating-point frint patterns. +-;; Expands to btrunc, ceil, floor, nearbyint, rint, round. +-(define_expand "2" +- [(set (match_operand:VDQF 0 "register_operand") +- (unspec:VDQF [(match_operand:VDQF 1 "register_operand")] +- FRINT))] +- "TARGET_SIMD" +- {}) +- +-(define_insn "aarch64_fcvt" ++;; Vector versions of the fcvt standard patterns. ++;; Expands to lbtrunc, lround, lceil, lfloor ++(define_insn "l2" + [(set (match_operand: 0 "register_operand" "=w") + (FIXUORS: (unspec: + [(match_operand:VDQF 1 "register_operand" "w")] +@@ -1226,16 +1439,141 @@ + (set_attr "simd_mode" "")] + ) + +-;; Vector versions of the fcvt standard patterns. +-;; Expands to lbtrunc, lround, lceil, lfloor +-(define_expand "l2" ++(define_expand "2" + [(set (match_operand: 0 "register_operand") + (FIXUORS: (unspec: + [(match_operand:VDQF 1 "register_operand")] +- FCVT)))] ++ UNSPEC_FRINTZ)))] + "TARGET_SIMD" + {}) + ++(define_expand "2" ++ [(set (match_operand: 0 "register_operand") ++ (FIXUORS: (unspec: ++ [(match_operand:VDQF 1 "register_operand")] ++ UNSPEC_FRINTZ)))] ++ "TARGET_SIMD" ++ {}) + -+ * gcc.target/aarch64/vect-fcm.x: Add cases testing -+ FLOAT cmp FLOAT ? INT : INT. -+ * gcc.target/aarch64/vect-fcm-eq-d.c: Define IMODE. -+ * gcc.target/aarch64/vect-fcm-eq-f.c: Likewise. -+ * gcc.target/aarch64/vect-fcm-ge-d.c: Likewise. -+ * gcc.target/aarch64/vect-fcm-ge-f.c: Likewise. -+ * gcc.target/aarch64/vect-fcm-gt-d.c: Likewise. -+ * gcc.target/aarch64/vect-fcm-gt-f.c: Likewise. ++(define_expand "ftrunc2" ++ [(set (match_operand:VDQF 0 "register_operand") ++ (unspec:VDQF [(match_operand:VDQF 1 "register_operand")] ++ UNSPEC_FRINTZ))] ++ "TARGET_SIMD" ++ {}) + -+2013-05-29 Christophe Lyon ++(define_insn "2" ++ [(set (match_operand:VDQF 0 "register_operand" "=w") ++ (FLOATUORS:VDQF ++ (match_operand: 1 "register_operand" "w")))] ++ "TARGET_SIMD" ++ "cvtf\\t%0., %1." ++ [(set_attr "simd_type" "simd_icvtf") ++ (set_attr "simd_mode" "")] ++) + -+ Backport from trunk r198928. -+ 2013-05-15 Ramana Radhakrishnan ++;; Conversions between vectors of floats and doubles. ++;; Contains a mix of patterns to match standard pattern names ++;; and those for intrinsics. + -+ PR target/19599 -+ * gcc.target/arm/pr40887.c: Adjust testcase. -+ * gcc.target/arm/pr19599.c: New test. ++;; Float widening operations. + -+2013-05-28 Christophe Lyon ++(define_insn "vec_unpacks_lo_v4sf" ++ [(set (match_operand:V2DF 0 "register_operand" "=w") ++ (float_extend:V2DF ++ (vec_select:V2SF ++ (match_operand:V4SF 1 "register_operand" "w") ++ (parallel [(const_int 0) (const_int 1)]) ++ )))] ++ "TARGET_SIMD" ++ "fcvtl\\t%0.2d, %1.2s" ++ [(set_attr "simd_type" "simd_fcvtl") ++ (set_attr "simd_mode" "V2DF")] ++) + -+ Backport from trunk r198680. -+ 2013-05-07 Sofiane Naci ++(define_insn "aarch64_float_extend_lo_v2df" ++ [(set (match_operand:V2DF 0 "register_operand" "=w") ++ (float_extend:V2DF ++ (match_operand:V2SF 1 "register_operand" "w")))] ++ "TARGET_SIMD" ++ "fcvtl\\t%0.2d, %1.2s" ++ [(set_attr "simd_type" "simd_fcvtl") ++ (set_attr "simd_mode" "V2DF")] ++) + -+ * gcc.target/aarch64/scalar_intrinsics.c: Update. ++(define_insn "vec_unpacks_hi_v4sf" ++ [(set (match_operand:V2DF 0 "register_operand" "=w") ++ (float_extend:V2DF ++ (vec_select:V2SF ++ (match_operand:V4SF 1 "register_operand" "w") ++ (parallel [(const_int 2) (const_int 3)]) ++ )))] ++ "TARGET_SIMD" ++ "fcvtl2\\t%0.2d, %1.4s" ++ [(set_attr "simd_type" "simd_fcvtl") ++ (set_attr "simd_mode" "V2DF")] ++) + -+2013-05-28 Christophe Lyon ++;; Float narrowing operations. + -+ Backport from trunk r198499-198500. -+ 2013-05-01 James Greenhalgh -+ * gcc.target/aarch64/vect-vaddv.c: New. ++(define_insn "aarch64_float_truncate_lo_v2sf" ++ [(set (match_operand:V2SF 0 "register_operand" "=w") ++ (float_truncate:V2SF ++ (match_operand:V2DF 1 "register_operand" "w")))] ++ "TARGET_SIMD" ++ "fcvtn\\t%0.2s, %1.2d" ++ [(set_attr "simd_type" "simd_fcvtl") ++ (set_attr "simd_mode" "V2SF")] ++) + -+ 2013-05-01 James Greenhalgh ++(define_insn "aarch64_float_truncate_hi_v4sf" ++ [(set (match_operand:V4SF 0 "register_operand" "=w") ++ (vec_concat:V4SF ++ (match_operand:V2SF 1 "register_operand" "0") ++ (float_truncate:V2SF ++ (match_operand:V2DF 2 "register_operand" "w"))))] ++ "TARGET_SIMD" ++ "fcvtn2\\t%0.4s, %2.2d" ++ [(set_attr "simd_type" "simd_fcvtl") ++ (set_attr "simd_mode" "V4SF")] ++) + -+ * gcc.target/aarch64/vect-vmaxv.c: New. -+ * gcc.target/aarch64/vect-vfmaxv.c: Likewise. ++(define_expand "vec_pack_trunc_v2df" ++ [(set (match_operand:V4SF 0 "register_operand") ++ (vec_concat:V4SF ++ (float_truncate:V2SF ++ (match_operand:V2DF 1 "register_operand")) ++ (float_truncate:V2SF ++ (match_operand:V2DF 2 "register_operand")) ++ ))] ++ "TARGET_SIMD" ++ { ++ rtx tmp = gen_reg_rtx (V2SFmode); ++ emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[1])); ++ emit_insn (gen_aarch64_float_truncate_hi_v4sf (operands[0], ++ tmp, operands[2])); ++ DONE; ++ } ++) + -+2013-05-23 Christophe Lyon ++(define_expand "vec_pack_trunc_df" ++ [(set (match_operand:V2SF 0 "register_operand") ++ (vec_concat:V2SF ++ (float_truncate:SF ++ (match_operand:DF 1 "register_operand")) ++ (float_truncate:SF ++ (match_operand:DF 2 "register_operand")) ++ ))] ++ "TARGET_SIMD" ++ { ++ rtx tmp = gen_reg_rtx (V2SFmode); ++ emit_insn (gen_move_lo_quad_v2df (tmp, operands[1])); ++ emit_insn (gen_move_hi_quad_v2df (tmp, operands[2])); ++ emit_insn (gen_aarch64_float_truncate_lo_v2sf (operands[0], tmp)); ++ DONE; ++ } ++) + -+ Backport from trunk r198970. -+ 2013-05-16 Greta Yorsh + (define_insn "aarch64_vmls" + [(set (match_operand:VDQF 0 "register_operand" "=w") + (minus:VDQF (match_operand:VDQF 1 "register_operand" "0") +@@ -1261,51 +1599,70 @@ + ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring + ;; NaNs. + +-(define_insn "smax3" ++(define_insn "3" + [(set (match_operand:VDQF 0 "register_operand" "=w") +- (smax:VDQF (match_operand:VDQF 1 "register_operand" "w") ++ (FMAXMIN:VDQF (match_operand:VDQF 1 "register_operand" "w") + (match_operand:VDQF 2 "register_operand" "w")))] + "TARGET_SIMD" +- "fmaxnm\\t%0., %1., %2." ++ "fnm\\t%0., %1., %2." + [(set_attr "simd_type" "simd_fminmax") + (set_attr "simd_mode" "")] + ) + +-(define_insn "smin3" ++(define_insn "3" + [(set (match_operand:VDQF 0 "register_operand" "=w") +- (smin:VDQF (match_operand:VDQF 1 "register_operand" "w") +- (match_operand:VDQF 2 "register_operand" "w")))] ++ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w") ++ (match_operand:VDQF 2 "register_operand" "w")] ++ FMAXMIN_UNS))] + "TARGET_SIMD" +- "fminnm\\t%0., %1., %2." ++ "\\t%0., %1., %2." + [(set_attr "simd_type" "simd_fminmax") + (set_attr "simd_mode" "")] + ) + +-;; FP 'across lanes' max and min ops. ++;; 'across lanes' add. + +-(define_insn "reduc_s_v4sf" +- [(set (match_operand:V4SF 0 "register_operand" "=w") +- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")] +- FMAXMINV))] ++(define_insn "reduc_plus_" ++ [(set (match_operand:VDQV 0 "register_operand" "=w") ++ (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] ++ SUADDV))] + "TARGET_SIMD" +- "fnmv\\t%s0, %1.4s"; +- [(set_attr "simd_type" "simd_fminmaxv") +- (set_attr "simd_mode" "V4SF")] ++ "addv\\t%0, %1." ++ [(set_attr "simd_type" "simd_addv") ++ (set_attr "simd_mode" "")] + ) + +-(define_insn "reduc_s_" ++(define_insn "reduc_plus_v2di" ++ [(set (match_operand:V2DI 0 "register_operand" "=w") ++ (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] ++ SUADDV))] ++ "TARGET_SIMD" ++ "addp\\t%d0, %1.2d" ++ [(set_attr "simd_type" "simd_addv") ++ (set_attr "simd_mode" "V2DI")] ++) + -+ * gcc.target/arm/unaligned-memcpy-2.c: Adjust expected output. -+ * gcc.target/arm/unaligned-memcpy-3.c: Likewise. -+ * gcc.target/arm/unaligned-memcpy-4.c: Likewise. ++(define_insn "reduc_plus_v2si" ++ [(set (match_operand:V2SI 0 "register_operand" "=w") ++ (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] ++ SUADDV))] ++ "TARGET_SIMD" ++ "addp\\t%0.2s, %1.2s, %1.2s" ++ [(set_attr "simd_type" "simd_addv") ++ (set_attr "simd_mode" "V2SI")] ++) + -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ Backport from trunk r198574-198575. -+ 2013-05-03 Vidya Praveen -+ -+ * gcc.target/aarch64/fabd.c: New file. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ Backport from trunk r198490-198496. -+ 2013-05-01 James Greenhalgh -+ -+ * gcc.target/aarch64/scalar-vca.c: New. -+ * gcc.target/aarch64/vect-vca.c: Likewise. -+ -+ 2013-05-01 James Greenhalgh -+ -+ * gcc.target/aarch64/scalar_intrinsics.c (force_simd): New. -+ (test_vceqd_s64): Force arguments to SIMD registers. -+ (test_vceqzd_s64): Likewise. -+ (test_vcged_s64): Likewise. -+ (test_vcled_s64): Likewise. -+ (test_vcgezd_s64): Likewise. -+ (test_vcged_u64): Likewise. -+ (test_vcgtd_s64): Likewise. -+ (test_vcltd_s64): Likewise. -+ (test_vcgtzd_s64): Likewise. -+ (test_vcgtd_u64): Likewise. -+ (test_vclezd_s64): Likewise. -+ (test_vcltzd_s64): Likewise. -+ (test_vtst_s64): Likewise. -+ (test_vtst_u64): Likewise. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ Backport from trunk r198191. -+ 2013-04-23 Sofiane Naci -+ -+ * gcc.target/aarch64/scalar-mov.c: New testcase. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ Backport from trunk r197838. -+ 2013-04-11 Naveen H.S -+ -+ * gcc.target/aarch64/negs.c: New. -+ -+2013-05-02 Matthew Gretton-Dann ++(define_insn "reduc_plus_" + [(set (match_operand:V2F 0 "register_operand" "=w") + (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] +- FMAXMINV))] ++ SUADDV))] + "TARGET_SIMD" +- "fnmp\\t%0., %1., %1."; +- [(set_attr "simd_type" "simd_fminmax") ++ "faddp\\t%0, %1." ++ [(set_attr "simd_type" "simd_fadd") + (set_attr "simd_mode" "")] + ) + +-;; FP 'across lanes' add. +- +-(define_insn "aarch64_addvv4sf" ++(define_insn "aarch64_addpv4sf" + [(set (match_operand:V4SF 0 "register_operand" "=w") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")] + UNSPEC_FADDV))] +@@ -1315,169 +1672,106 @@ + (set_attr "simd_mode" "V4SF")] + ) + +-(define_expand "reduc_uplus_v4sf" +- [(set (match_operand:V4SF 0 "register_operand" "=w") +- (match_operand:V4SF 1 "register_operand" "w"))] ++(define_expand "reduc_plus_v4sf" ++ [(set (match_operand:V4SF 0 "register_operand") ++ (unspec:V4SF [(match_operand:V4SF 1 "register_operand")] ++ SUADDV))] + "TARGET_SIMD" + { + rtx tmp = gen_reg_rtx (V4SFmode); +- emit_insn (gen_aarch64_addvv4sf (tmp, operands[1])); +- emit_insn (gen_aarch64_addvv4sf (operands[0], tmp)); ++ emit_insn (gen_aarch64_addpv4sf (tmp, operands[1])); ++ emit_insn (gen_aarch64_addpv4sf (operands[0], tmp)); + DONE; + }) + +-(define_expand "reduc_splus_v4sf" +- [(set (match_operand:V4SF 0 "register_operand" "=w") +- (match_operand:V4SF 1 "register_operand" "w"))] ++(define_insn "clz2" ++ [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") ++ (clz:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))] + "TARGET_SIMD" +-{ +- rtx tmp = gen_reg_rtx (V4SFmode); +- emit_insn (gen_aarch64_addvv4sf (tmp, operands[1])); +- emit_insn (gen_aarch64_addvv4sf (operands[0], tmp)); +- DONE; +-}) +- +-(define_insn "aarch64_addv" +- [(set (match_operand:V2F 0 "register_operand" "=w") +- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] +- UNSPEC_FADDV))] +- "TARGET_SIMD" +- "faddp\\t%0, %1." +- [(set_attr "simd_type" "simd_fadd") +- (set_attr "simd_mode" "")] ++ "clz\\t%0., %1." ++ [(set_attr "simd_type" "simd_cls") ++ (set_attr "simd_mode" "")] + ) + +-(define_expand "reduc_uplus_" +- [(set (match_operand:V2F 0 "register_operand" "=w") +- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] +- UNSPEC_FADDV))] +- "TARGET_SIMD" +- "" +-) ++;; 'across lanes' max and min ops. + +-(define_expand "reduc_splus_" +- [(set (match_operand:V2F 0 "register_operand" "=w") +- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] +- UNSPEC_FADDV))] +- "TARGET_SIMD" +- "" +-) +- +-;; Reduction across lanes. +- +-(define_insn "aarch64_addv" ++(define_insn "reduc__" + [(set (match_operand:VDQV 0 "register_operand" "=w") + (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] +- UNSPEC_ADDV))] ++ MAXMINV))] + "TARGET_SIMD" +- "addv\\t%0, %1." +- [(set_attr "simd_type" "simd_addv") ++ "v\\t%0, %1." ++ [(set_attr "simd_type" "simd_minmaxv") + (set_attr "simd_mode" "")] + ) + +-(define_expand "reduc_splus_" +- [(set (match_operand:VDQV 0 "register_operand" "=w") +- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] +- UNSPEC_ADDV))] +- "TARGET_SIMD" +- "" +-) +- +-(define_expand "reduc_uplus_" +- [(set (match_operand:VDQV 0 "register_operand" "=w") +- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] +- UNSPEC_ADDV))] +- "TARGET_SIMD" +- "" +-) +- +-(define_insn "aarch64_addvv2di" ++(define_insn "reduc__v2di" + [(set (match_operand:V2DI 0 "register_operand" "=w") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] +- UNSPEC_ADDV))] ++ MAXMINV))] + "TARGET_SIMD" +- "addp\\t%d0, %1.2d" +- [(set_attr "simd_type" "simd_add") ++ "p\\t%d0, %1.2d" ++ [(set_attr "simd_type" "simd_minmaxv") + (set_attr "simd_mode" "V2DI")] + ) + +-(define_expand "reduc_uplus_v2di" +- [(set (match_operand:V2DI 0 "register_operand" "=w") +- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] +- UNSPEC_ADDV))] +- "TARGET_SIMD" +- "" +-) +- +-(define_expand "reduc_splus_v2di" +- [(set (match_operand:V2DI 0 "register_operand" "=w") +- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] +- UNSPEC_ADDV))] +- "TARGET_SIMD" +- "" +-) +- +-(define_insn "aarch64_addvv2si" ++(define_insn "reduc__v2si" + [(set (match_operand:V2SI 0 "register_operand" "=w") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] +- UNSPEC_ADDV))] ++ MAXMINV))] + "TARGET_SIMD" +- "addp\\t%0.2s, %1.2s, %1.2s" +- [(set_attr "simd_type" "simd_add") ++ "p\\t%0.2s, %1.2s, %1.2s" ++ [(set_attr "simd_type" "simd_minmaxv") + (set_attr "simd_mode" "V2SI")] + ) + +-(define_expand "reduc_uplus_v2si" +- [(set (match_operand:V2SI 0 "register_operand" "=w") +- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] +- UNSPEC_ADDV))] ++(define_insn "reduc__" ++ [(set (match_operand:V2F 0 "register_operand" "=w") ++ (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] ++ FMAXMINV))] + "TARGET_SIMD" +- "" +-) +- +-(define_expand "reduc_splus_v2si" +- [(set (match_operand:V2SI 0 "register_operand" "=w") +- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] +- UNSPEC_ADDV))] +- "TARGET_SIMD" +- "" +-) +- +-(define_insn "reduc__" +- [(set (match_operand:VDQV 0 "register_operand" "=w") +- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] +- MAXMINV))] +- "TARGET_SIMD" +- "v\\t%0, %1." +- [(set_attr "simd_type" "simd_minmaxv") ++ "p\\t%0, %1." ++ [(set_attr "simd_type" "simd_fminmaxv") + (set_attr "simd_mode" "")] + ) + +-(define_insn "reduc__v2si" +- [(set (match_operand:V2SI 0 "register_operand" "=w") +- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] +- MAXMINV))] ++(define_insn "reduc__v4sf" ++ [(set (match_operand:V4SF 0 "register_operand" "=w") ++ (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")] ++ FMAXMINV))] + "TARGET_SIMD" +- "p\\t%0.2s, %1.2s, %1.2s" +- [(set_attr "simd_type" "simd_minmax") +- (set_attr "simd_mode" "V2SI")] ++ "v\\t%s0, %1.4s" ++ [(set_attr "simd_type" "simd_fminmaxv") ++ (set_attr "simd_mode" "V4SF")] + ) + +-;; vbsl_* intrinsics may compile to any of bsl/bif/bit depending on register +-;; allocation. For an intrinsic of form: +-;; vD = bsl_* (vS, vN, vM) ++;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register ++;; allocation. ++;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which ++;; to select. ++;; ++;; Thus our BSL is of the form: ++;; op0 = bsl (mask, op2, op3) + ;; We can use any of: +-;; bsl vS, vN, vM (if D = S) +-;; bit vD, vN, vS (if D = M, so 1-bits in vS choose bits from vN, else vM) +-;; bif vD, vM, vS (if D = N, so 0-bits in vS choose bits from vM, else vN) ++;; ++;; if (op0 = mask) ++;; bsl mask, op1, op2 ++;; if (op0 = op1) (so 1-bits in mask choose bits from op2, else op0) ++;; bit op0, op2, mask ++;; if (op0 = op2) (so 0-bits in mask choose bits from op1, else op0) ++;; bif op0, op1, mask + + (define_insn "aarch64_simd_bsl_internal" + [(set (match_operand:VALL 0 "register_operand" "=w,w,w") +- (unspec:VALL +- [(match_operand: 1 "register_operand" " 0,w,w") +- (match_operand:VALL 2 "register_operand" " w,w,0") +- (match_operand:VALL 3 "register_operand" " w,0,w")] +- UNSPEC_BSL))] ++ (ior:VALL ++ (and:VALL ++ (match_operand: 1 "register_operand" " 0,w,w") ++ (match_operand:VALL 2 "register_operand" " w,w,0")) ++ (and:VALL ++ (not: ++ (match_dup: 1)) ++ (match_operand:VALL 3 "register_operand" " w,0,w")) ++ ))] + "TARGET_SIMD" + "@ + bsl\\t%0., %2., %3. +@@ -1486,28 +1780,32 @@ + ) + + (define_expand "aarch64_simd_bsl" +- [(set (match_operand:VALL 0 "register_operand") +- (unspec:VALL [(match_operand: 1 "register_operand") +- (match_operand:VALL 2 "register_operand") +- (match_operand:VALL 3 "register_operand")] +- UNSPEC_BSL))] +- "TARGET_SIMD" ++ [(match_operand:VALL 0 "register_operand") ++ (match_operand: 1 "register_operand") ++ (match_operand:VALL 2 "register_operand") ++ (match_operand:VALL 3 "register_operand")] ++ "TARGET_SIMD" + { + /* We can't alias operands together if they have different modes. */ + operands[1] = gen_lowpart (mode, operands[1]); ++ emit_insn (gen_aarch64_simd_bsl_internal (operands[0], operands[1], ++ operands[2], operands[3])); ++ DONE; + }) + +-(define_expand "aarch64_vcond_internal" ++(define_expand "aarch64_vcond_internal" + [(set (match_operand:VDQ 0 "register_operand") + (if_then_else:VDQ + (match_operator 3 "comparison_operator" + [(match_operand:VDQ 4 "register_operand") + (match_operand:VDQ 5 "nonmemory_operand")]) +- (match_operand:VDQ 1 "register_operand") +- (match_operand:VDQ 2 "register_operand")))] ++ (match_operand:VDQ 1 "nonmemory_operand") ++ (match_operand:VDQ 2 "nonmemory_operand")))] + "TARGET_SIMD" + { + int inverse = 0, has_zero_imm_form = 0; ++ rtx op1 = operands[1]; ++ rtx op2 = operands[2]; + rtx mask = gen_reg_rtx (mode); + + switch (GET_CODE (operands[3])) +@@ -1548,12 +1846,12 @@ + + case LTU: + case GEU: +- emit_insn (gen_aarch64_cmhs (mask, operands[4], operands[5])); ++ emit_insn (gen_aarch64_cmgeu (mask, operands[4], operands[5])); + break; + + case LEU: + case GTU: +- emit_insn (gen_aarch64_cmhi (mask, operands[4], operands[5])); ++ emit_insn (gen_aarch64_cmgtu (mask, operands[4], operands[5])); + break; + + case NE: +@@ -1566,30 +1864,47 @@ + } + + if (inverse) +- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[2], +- operands[1])); +- else +- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[1], +- operands[2])); ++ { ++ op1 = operands[2]; ++ op2 = operands[1]; ++ } + ++ /* If we have (a = (b CMP c) ? -1 : 0); ++ Then we can simply move the generated mask. */ + -+ Backport from trunk r198019. -+ 2013-04-16 Naveen H.S ++ if (op1 == CONSTM1_RTX (mode) ++ && op2 == CONST0_RTX (mode)) ++ emit_move_insn (operands[0], mask); ++ else ++ { ++ if (!REG_P (op1)) ++ op1 = force_reg (mode, op1); ++ if (!REG_P (op2)) ++ op2 = force_reg (mode, op2); ++ emit_insn (gen_aarch64_simd_bsl (operands[0], mask, ++ op1, op2)); ++ } + -+ * gcc.target/aarch64/adds1.c: New. -+ * gcc.target/aarch64/adds2.c: New. -+ * gcc.target/aarch64/subs1.c: New. -+ * gcc.target/aarch64/subs2.c: New. + DONE; + }) + +-(define_expand "aarch64_vcond_internal" +- [(set (match_operand:VDQF 0 "register_operand") ++(define_expand "aarch64_vcond_internal" ++ [(set (match_operand:VDQF_COND 0 "register_operand") + (if_then_else:VDQF + (match_operator 3 "comparison_operator" + [(match_operand:VDQF 4 "register_operand") + (match_operand:VDQF 5 "nonmemory_operand")]) +- (match_operand:VDQF 1 "register_operand") +- (match_operand:VDQF 2 "register_operand")))] ++ (match_operand:VDQF_COND 1 "nonmemory_operand") ++ (match_operand:VDQF_COND 2 "nonmemory_operand")))] + "TARGET_SIMD" + { + int inverse = 0; + int use_zero_form = 0; + int swap_bsl_operands = 0; +- rtx mask = gen_reg_rtx (mode); +- rtx tmp = gen_reg_rtx (mode); ++ rtx op1 = operands[1]; ++ rtx op2 = operands[2]; ++ rtx mask = gen_reg_rtx (mode); ++ rtx tmp = gen_reg_rtx (mode); + + rtx (*base_comparison) (rtx, rtx, rtx); + rtx (*complimentary_comparison) (rtx, rtx, rtx); +@@ -1609,7 +1924,7 @@ + /* Fall through. */ + default: + if (!REG_P (operands[5])) +- operands[5] = force_reg (mode, operands[5]); ++ operands[5] = force_reg (mode, operands[5]); + } + + switch (GET_CODE (operands[3])) +@@ -1622,8 +1937,8 @@ + case UNGE: + case ORDERED: + case UNORDERED: +- base_comparison = gen_aarch64_cmge; +- complimentary_comparison = gen_aarch64_cmgt; ++ base_comparison = gen_aarch64_cmge; ++ complimentary_comparison = gen_aarch64_cmgt; + break; + case LE: + case UNLE: +@@ -1631,14 +1946,14 @@ + /* Fall through. */ + case GT: + case UNGT: +- base_comparison = gen_aarch64_cmgt; +- complimentary_comparison = gen_aarch64_cmge; ++ base_comparison = gen_aarch64_cmgt; ++ complimentary_comparison = gen_aarch64_cmge; + break; + case EQ: + case NE: + case UNEQ: +- base_comparison = gen_aarch64_cmeq; +- complimentary_comparison = gen_aarch64_cmeq; ++ base_comparison = gen_aarch64_cmeq; ++ complimentary_comparison = gen_aarch64_cmeq; + break; + default: + gcc_unreachable (); +@@ -1666,10 +1981,10 @@ + switch (GET_CODE (operands[3])) + { + case LT: +- base_comparison = gen_aarch64_cmlt; ++ base_comparison = gen_aarch64_cmlt; + break; + case LE: +- base_comparison = gen_aarch64_cmle; ++ base_comparison = gen_aarch64_cmle; + break; + default: + /* Do nothing, other zero form cases already have the correct +@@ -1712,9 +2027,9 @@ + true iff !(a != b && a ORDERED b), swapping the operands to BSL + will then give us (a == b || a UNORDERED b) as intended. */ + +- emit_insn (gen_aarch64_cmgt (mask, operands[4], operands[5])); +- emit_insn (gen_aarch64_cmgt (tmp, operands[5], operands[4])); +- emit_insn (gen_ior3 (mask, mask, tmp)); ++ emit_insn (gen_aarch64_cmgt (mask, operands[4], operands[5])); ++ emit_insn (gen_aarch64_cmgt (tmp, operands[5], operands[4])); ++ emit_insn (gen_ior3 (mask, mask, tmp)); + swap_bsl_operands = 1; + break; + case UNORDERED: +@@ -1723,20 +2038,36 @@ + swap_bsl_operands = 1; + /* Fall through. */ + case ORDERED: +- emit_insn (gen_aarch64_cmgt (tmp, operands[4], operands[5])); +- emit_insn (gen_aarch64_cmge (mask, operands[5], operands[4])); +- emit_insn (gen_ior3 (mask, mask, tmp)); ++ emit_insn (gen_aarch64_cmgt (tmp, operands[4], operands[5])); ++ emit_insn (gen_aarch64_cmge (mask, operands[5], operands[4])); ++ emit_insn (gen_ior3 (mask, mask, tmp)); + break; + default: + gcc_unreachable (); + } + + if (swap_bsl_operands) +- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[2], +- operands[1])); +- else +- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[1], +- operands[2])); ++ { ++ op1 = operands[2]; ++ op2 = operands[1]; ++ } + -+2013-05-02 Matthew Gretton-Dann ++ /* If we have (a = (b CMP c) ? -1 : 0); ++ Then we can simply move the generated mask. */ + -+ Backport from trunk r198394,198396-198400,198402-198404,198406. -+ 2013-04-29 James Greenhalgh ++ if (op1 == CONSTM1_RTX (mode) ++ && op2 == CONST0_RTX (mode)) ++ emit_move_insn (operands[0], mask); ++ else ++ { ++ if (!REG_P (op1)) ++ op1 = force_reg (mode, op1); ++ if (!REG_P (op2)) ++ op2 = force_reg (mode, op2); ++ emit_insn (gen_aarch64_simd_bsl (operands[0], mask, ++ op1, op2)); ++ } + -+ * lib/target-supports.exp (vect_uintfloat_cvt): Enable for AArch64. -+ -+ 2013-04-29 James Greenhalgh -+ -+ * gcc.target/aarch64/vect-vcvt.c: New. + DONE; + }) + +@@ -1746,16 +2077,32 @@ + (match_operator 3 "comparison_operator" + [(match_operand:VALL 4 "register_operand") + (match_operand:VALL 5 "nonmemory_operand")]) +- (match_operand:VALL 1 "register_operand") +- (match_operand:VALL 2 "register_operand")))] ++ (match_operand:VALL 1 "nonmemory_operand") ++ (match_operand:VALL 2 "nonmemory_operand")))] + "TARGET_SIMD" + { +- emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], ++ emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], + operands[2], operands[3], + operands[4], operands[5])); + DONE; + }) + ++(define_expand "vcond" ++ [(set (match_operand: 0 "register_operand") ++ (if_then_else: ++ (match_operator 3 "comparison_operator" ++ [(match_operand:VDQF 4 "register_operand") ++ (match_operand:VDQF 5 "nonmemory_operand")]) ++ (match_operand: 1 "nonmemory_operand") ++ (match_operand: 2 "nonmemory_operand")))] ++ "TARGET_SIMD" ++{ ++ emit_insn (gen_aarch64_vcond_internal ( ++ operands[0], operands[1], ++ operands[2], operands[3], ++ operands[4], operands[5])); ++ DONE; ++}) + + (define_expand "vcondu" + [(set (match_operand:VDQ 0 "register_operand") +@@ -1763,11 +2110,11 @@ + (match_operator 3 "comparison_operator" + [(match_operand:VDQ 4 "register_operand") + (match_operand:VDQ 5 "nonmemory_operand")]) +- (match_operand:VDQ 1 "register_operand") +- (match_operand:VDQ 2 "register_operand")))] ++ (match_operand:VDQ 1 "nonmemory_operand") ++ (match_operand:VDQ 2 "nonmemory_operand")))] + "TARGET_SIMD" + { +- emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], ++ emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], + operands[2], operands[3], + operands[4], operands[5])); + DONE; +@@ -1785,45 +2132,50 @@ + DONE; + }) + +-(define_insn "aarch64_get_lane_signed" +- [(set (match_operand: 0 "register_operand" "=r") +- (sign_extend: ++;; Lane extraction with sign extension to general purpose register. ++(define_insn "*aarch64_get_lane_extend" ++ [(set (match_operand:GPI 0 "register_operand" "=r") ++ (sign_extend:GPI + (vec_select: +- (match_operand:VQ_S 1 "register_operand" "w") ++ (match_operand:VDQQH 1 "register_operand" "w") + (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))] + "TARGET_SIMD" +- "smov\\t%0, %1.[%2]" ++ "smov\\t%0, %1.[%2]" + [(set_attr "simd_type" "simd_movgp") +- (set_attr "simd_mode" "")] ++ (set_attr "simd_mode" "")] + ) + +-(define_insn "aarch64_get_lane_unsigned" +- [(set (match_operand: 0 "register_operand" "=r") +- (zero_extend: ++(define_insn "*aarch64_get_lane_zero_extendsi" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (zero_extend:SI + (vec_select: +- (match_operand:VDQ 1 "register_operand" "w") ++ (match_operand:VDQQH 1 "register_operand" "w") + (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))] + "TARGET_SIMD" +- "umov\\t%0, %1.[%2]" ++ "umov\\t%w0, %1.[%2]" + [(set_attr "simd_type" "simd_movgp") + (set_attr "simd_mode" "")] + ) + ++;; Lane extraction of a value, neither sign nor zero extension ++;; is guaranteed so upper bits should be considered undefined. + (define_insn "aarch64_get_lane" +- [(set (match_operand: 0 "register_operand" "=w") ++ [(set (match_operand: 0 "register_operand" "=r, w") + (vec_select: +- (match_operand:VDQF 1 "register_operand" "w") +- (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] ++ (match_operand:VALL 1 "register_operand" "w, w") ++ (parallel [(match_operand:SI 2 "immediate_operand" "i, i")])))] + "TARGET_SIMD" +- "mov\\t%0.[0], %1.[%2]" +- [(set_attr "simd_type" "simd_ins") ++ "@ ++ umov\\t%0, %1.[%2] ++ dup\\t%0, %1.[%2]" ++ [(set_attr "simd_type" "simd_movgp, simd_dup") + (set_attr "simd_mode" "")] + ) + + (define_expand "aarch64_get_lanedi" +- [(match_operand:DI 0 "register_operand" "=r") +- (match_operand:DI 1 "register_operand" "w") +- (match_operand:SI 2 "immediate_operand" "i")] ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:SI 2 "immediate_operand")] + "TARGET_SIMD" + { + aarch64_simd_lane_bounds (operands[2], 0, 1); +@@ -1944,16 +2296,30 @@ + (set_attr "simd_mode" "")] + ) + +-(define_insn "aarch64_combine" ++(define_insn_and_split "aarch64_combine" + [(set (match_operand: 0 "register_operand" "=&w") + (vec_concat: (match_operand:VDC 1 "register_operand" "w") + (match_operand:VDC 2 "register_operand" "w")))] + "TARGET_SIMD" +- "mov\\t%0.d[0], %1.d[0]\;ins\\t%0.d[1], %2.d[0]" +- [(set_attr "simd_type" "simd_ins") +- (set_attr "simd_mode" "")] +-) ++ "#" ++ "&& reload_completed" ++ [(const_int 0)] ++{ ++ aarch64_split_simd_combine (operands[0], operands[1], operands[2]); ++ DONE; ++}) + ++(define_expand "aarch64_simd_combine" ++ [(set (match_operand: 0 "register_operand" "=&w") ++ (vec_concat: (match_operand:VDC 1 "register_operand" "w") ++ (match_operand:VDC 2 "register_operand" "w")))] ++ "TARGET_SIMD" ++ { ++ emit_insn (gen_move_lo_quad_ (operands[0], operands[1])); ++ emit_insn (gen_move_hi_quad_ (operands[0], operands[2])); ++ DONE; ++ }) + -+ 2013-04-29 James Greenhalgh + ;; l. + + (define_insn "aarch64_l2_internal" +@@ -2861,28 +3227,6 @@ + (set_attr "simd_mode" "")] + ) + +-;; vshl_n +- +-(define_expand "aarch64_sshl_n" +- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") +- (match_operand:VSDQ_I_DI 1 "register_operand" "w") +- (match_operand:SI 2 "immediate_operand" "i")] +- "TARGET_SIMD" +-{ +- emit_insn (gen_ashl3 (operands[0], operands[1], operands[2])); +- DONE; +-}) +- +-(define_expand "aarch64_ushl_n" +- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") +- (match_operand:VSDQ_I_DI 1 "register_operand" "w") +- (match_operand:SI 2 "immediate_operand" "i")] +- "TARGET_SIMD" +-{ +- emit_insn (gen_ashl3 (operands[0], operands[1], operands[2])); +- DONE; +-}) +- + ;; vshll_n + + (define_insn "aarch64_shll_n" +@@ -2927,28 +3271,6 @@ + (set_attr "simd_mode" "")] + ) + +-;; vshr_n +- +-(define_expand "aarch64_sshr_n" +- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") +- (match_operand:VSDQ_I_DI 1 "register_operand" "w") +- (match_operand:SI 2 "immediate_operand" "i")] +- "TARGET_SIMD" +-{ +- emit_insn (gen_ashr3 (operands[0], operands[1], operands[2])); +- DONE; +-}) +- +-(define_expand "aarch64_ushr_n" +- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") +- (match_operand:VSDQ_I_DI 1 "register_operand" "w") +- (match_operand:SI 2 "immediate_operand" "i")] +- "TARGET_SIMD" +-{ +- emit_insn (gen_lshr3 (operands[0], operands[1], operands[2])); +- DONE; +-}) +- + ;; vrshr_n + + (define_insn "aarch64_shr_n" +@@ -3034,52 +3356,180 @@ + ) + + +-;; cm(eq|ge|le|lt|gt) ++;; cm(eq|ge|gt|lt|le) ++;; Note, we have constraints for Dz and Z as different expanders ++;; have different ideas of what should be passed to this pattern. + +-(define_insn "aarch64_cm" ++(define_insn "aarch64_cm" + [(set (match_operand: 0 "register_operand" "=w,w") +- (unspec: +- [(match_operand:VSDQ_I_DI 1 "register_operand" "w,w") +- (match_operand:VSDQ_I_DI 2 "aarch64_simd_reg_or_zero" "w,Z")] +- VCMP_S))] ++ (neg: ++ (COMPARISONS: ++ (match_operand:VDQ 1 "register_operand" "w,w") ++ (match_operand:VDQ 2 "aarch64_simd_reg_or_zero" "w,ZDz") ++ )))] + "TARGET_SIMD" + "@ +- cm\t%0, %1, %2 +- cm\t%0, %1, #0" ++ cm\t%0, %, % ++ cm\t%0, %1, #0" + [(set_attr "simd_type" "simd_cmp") + (set_attr "simd_mode" "")] + ) + +-;; cm(hs|hi|tst) ++(define_insn_and_split "aarch64_cmdi" ++ [(set (match_operand:DI 0 "register_operand" "=w,w,r") ++ (neg:DI ++ (COMPARISONS:DI ++ (match_operand:DI 1 "register_operand" "w,w,r") ++ (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz,r") ++ ))) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_SIMD" ++ "@ ++ cm\t%d0, %d, %d ++ cm\t%d0, %d1, #0 ++ #" ++ "reload_completed ++ /* We need to prevent the split from ++ happening in the 'w' constraint cases. */ ++ && GP_REGNUM_P (REGNO (operands[0])) ++ && GP_REGNUM_P (REGNO (operands[1]))" ++ [(const_int 0)] ++ { ++ enum machine_mode mode = SELECT_CC_MODE (, operands[1], operands[2]); ++ rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); ++ rtx comparison = gen_rtx_ (mode, operands[1], operands[2]); ++ emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg)); ++ DONE; ++ } ++ [(set_attr "simd_type" "simd_cmp") ++ (set_attr "simd_mode" "DI")] ++) + +-(define_insn "aarch64_cm" ++;; cm(hs|hi) + -+ * gcc.target/aarch64/vect-vrnd.c: New. ++(define_insn "aarch64_cm" + [(set (match_operand: 0 "register_operand" "=w") +- (unspec: +- [(match_operand:VSDQ_I_DI 1 "register_operand" "w") +- (match_operand:VSDQ_I_DI 2 "register_operand" "w")] +- VCMP_U))] ++ (neg: ++ (UCOMPARISONS: ++ (match_operand:VDQ 1 "register_operand" "w") ++ (match_operand:VDQ 2 "register_operand" "w") ++ )))] + "TARGET_SIMD" +- "cm\t%0, %1, %2" ++ "cm\t%0, %, %" + [(set_attr "simd_type" "simd_cmp") + (set_attr "simd_mode" "")] + ) + +-;; fcm(eq|ge|le|lt|gt) ++(define_insn_and_split "aarch64_cmdi" ++ [(set (match_operand:DI 0 "register_operand" "=w,r") ++ (neg:DI ++ (UCOMPARISONS:DI ++ (match_operand:DI 1 "register_operand" "w,r") ++ (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,r") ++ ))) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_SIMD" ++ "@ ++ cm\t%d0, %d, %d ++ #" ++ "reload_completed ++ /* We need to prevent the split from ++ happening in the 'w' constraint cases. */ ++ && GP_REGNUM_P (REGNO (operands[0])) ++ && GP_REGNUM_P (REGNO (operands[1]))" ++ [(const_int 0)] ++ { ++ enum machine_mode mode = CCmode; ++ rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); ++ rtx comparison = gen_rtx_ (mode, operands[1], operands[2]); ++ emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg)); ++ DONE; ++ } ++ [(set_attr "simd_type" "simd_cmp") ++ (set_attr "simd_mode" "DI")] ++) + +-(define_insn "aarch64_cm" ++;; cmtst + -+2013-05-02 Matthew Gretton-Dann ++(define_insn "aarch64_cmtst" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (neg: ++ (ne: ++ (and:VDQ ++ (match_operand:VDQ 1 "register_operand" "w") ++ (match_operand:VDQ 2 "register_operand" "w")) ++ (vec_duplicate: (const_int 0)))))] ++ "TARGET_SIMD" ++ "cmtst\t%0, %1, %2" ++ [(set_attr "simd_type" "simd_cmp") ++ (set_attr "simd_mode" "")] ++) + -+ Backport from trunk r198302-198306,198316. -+ 2013-04-25 James Greenhalgh -+ Tejas Belagod ++(define_insn_and_split "aarch64_cmtstdi" ++ [(set (match_operand:DI 0 "register_operand" "=w,r") ++ (neg:DI ++ (ne:DI ++ (and:DI ++ (match_operand:DI 1 "register_operand" "w,r") ++ (match_operand:DI 2 "register_operand" "w,r")) ++ (const_int 0)))) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_SIMD" ++ "@ ++ cmtst\t%d0, %d1, %d2 ++ #" ++ "reload_completed ++ /* We need to prevent the split from ++ happening in the 'w' constraint cases. */ ++ && GP_REGNUM_P (REGNO (operands[0])) ++ && GP_REGNUM_P (REGNO (operands[1]))" ++ [(const_int 0)] ++ { ++ rtx and_tree = gen_rtx_AND (DImode, operands[1], operands[2]); ++ enum machine_mode mode = SELECT_CC_MODE (NE, and_tree, const0_rtx); ++ rtx cc_reg = aarch64_gen_compare_reg (NE, and_tree, const0_rtx); ++ rtx comparison = gen_rtx_NE (mode, and_tree, const0_rtx); ++ emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg)); ++ DONE; ++ } ++ [(set_attr "simd_type" "simd_cmp") ++ (set_attr "simd_mode" "DI")] ++) + -+ * gcc.target/aarch64/vaddv-intrinsic.c: New. -+ * gcc.target/aarch64/vaddv-intrinsic-compile.c: Likewise. -+ * gcc.target/aarch64/vaddv-intrinsic.x: Likewise. ++;; fcm(eq|ge|gt|le|lt) + -+ 2013-04-25 Naveen H.S ++(define_insn "aarch64_cm" + [(set (match_operand: 0 "register_operand" "=w,w") +- (unspec: +- [(match_operand:VDQF 1 "register_operand" "w,w") +- (match_operand:VDQF 2 "aarch64_simd_reg_or_zero" "w,Dz")] +- VCMP_S))] ++ (neg: ++ (COMPARISONS: ++ (match_operand:VALLF 1 "register_operand" "w,w") ++ (match_operand:VALLF 2 "aarch64_simd_reg_or_zero" "w,YDz") ++ )))] + "TARGET_SIMD" + "@ +- fcm\t%0, %1, %2 +- fcm\t%0, %1, 0" ++ fcm\t%0, %, % ++ fcm\t%0, %1, 0" + [(set_attr "simd_type" "simd_fcmp") + (set_attr "simd_mode" "")] + ) + ++;; fac(ge|gt) ++;; Note we can also handle what would be fac(le|lt) by ++;; generating fac(ge|gt). + -+ * gcc.target/aarch64/cmp.c: New. ++(define_insn "*aarch64_fac" ++ [(set (match_operand: 0 "register_operand" "=w") ++ (neg: ++ (FAC_COMPARISONS: ++ (abs:VALLF (match_operand:VALLF 1 "register_operand" "w")) ++ (abs:VALLF (match_operand:VALLF 2 "register_operand" "w")) ++ )))] ++ "TARGET_SIMD" ++ "fac\t%0, %, %" ++ [(set_attr "simd_type" "simd_fcmp") ++ (set_attr "simd_mode" "")] ++) + -+ 2013-04-25 Naveen H.S + ;; addp + + (define_insn "aarch64_addp" +@@ -3105,30 +3555,6 @@ + (set_attr "simd_mode" "DI")] + ) + +-;; v(max|min) +- +-(define_expand "aarch64_" +- [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") +- (MAXMIN:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w") +- (match_operand:VDQ_BHSI 2 "register_operand" "w")))] +- "TARGET_SIMD" +-{ +- emit_insn (gen_3 (operands[0], operands[1], operands[2])); +- DONE; +-}) +- +- +-(define_insn "aarch64_" +- [(set (match_operand:VDQF 0 "register_operand" "=w") +- (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w") +- (match_operand:VDQF 2 "register_operand" "w")] +- FMAXMIN))] +- "TARGET_SIMD" +- "\t%0., %1., %2." +- [(set_attr "simd_type" "simd_fminmax") +- (set_attr "simd_mode" "")] +-) +- + ;; sqrt + + (define_insn "sqrt2" +@@ -3140,16 +3566,6 @@ + (set_attr "simd_mode" "")] + ) + +-(define_expand "aarch64_sqrt" +- [(match_operand:VDQF 0 "register_operand" "=w") +- (match_operand:VDQF 1 "register_operand" "w")] +- "TARGET_SIMD" +-{ +- emit_insn (gen_sqrt2 (operands[0], operands[1])); +- DONE; +-}) +- +- + ;; Patterns for vector struct loads and stores. + + (define_insn "vec_load_lanesoi" +@@ -3736,3 +4152,25 @@ + "ld1r\\t{%0.}, %1" + [(set_attr "simd_type" "simd_load1r") + (set_attr "simd_mode" "")]) + -+ * gcc.target/aarch64/ngc.c: New. ++(define_insn "aarch64_frecpe" ++ [(set (match_operand:VDQF 0 "register_operand" "=w") ++ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")] ++ UNSPEC_FRECPE))] ++ "TARGET_SIMD" ++ "frecpe\\t%0., %1." ++ [(set_attr "simd_type" "simd_frecpe") ++ (set_attr "simd_mode" "")] ++) + -+2013-05-02 Matthew Gretton-Dann ++(define_insn "aarch64_frecps" ++ [(set (match_operand:VDQF 0 "register_operand" "=w") ++ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w") ++ (match_operand:VDQF 2 "register_operand" "w")] ++ UNSPEC_FRECPS))] ++ "TARGET_SIMD" ++ "frecps\\t%0., %1., %2." ++ [(set_attr "simd_type" "simd_frecps") ++ (set_attr "simd_mode" "")] ++) + -+ Backport from trunk r198298. -+ 2013-04-25 Kyrylo Tkachov +--- a/src/gcc/config/aarch64/predicates.md ++++ b/src/gcc/config/aarch64/predicates.md +@@ -31,6 +31,11 @@ + (ior (match_operand 0 "register_operand") + (match_test "op == const0_rtx")))) + ++(define_predicate "aarch64_reg_or_fp_zero" ++ (and (match_code "reg,subreg,const_double") ++ (ior (match_operand 0 "register_operand") ++ (match_test "aarch64_float_const_zero_rtx_p (op)")))) + -+ * lib/target-supports.exp -+ (check_effective_target_arm_neon_fp16_ok_nocache): New procedure. -+ (check_effective_target_arm_neon_fp16_ok): Likewise. -+ (add_options_for_arm_neon_fp16): Likewise. -+ * gcc.target/arm/neon/vcvtf16_f32.c: New test. Generated. -+ * gcc.target/arm/neon/vcvtf32_f16.c: Likewise. + (define_predicate "aarch64_reg_zero_or_m1_or_1" + (and (match_code "reg,subreg,const_int") + (ior (match_operand 0 "register_operand") +@@ -110,16 +115,11 @@ + (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, + 0)"))) + +-(define_predicate "aarch64_const_address" +- (and (match_code "symbol_ref") +- (match_test "mode == DImode && CONSTANT_ADDRESS_P (op)"))) +- + (define_predicate "aarch64_valid_symref" + (match_code "const, symbol_ref, label_ref") + { +- enum aarch64_symbol_type symbol_type; +- return (aarch64_symbolic_constant_p (op, SYMBOL_CONTEXT_ADR, &symbol_type) +- && symbol_type != SYMBOL_FORCE_TO_MEM); ++ return (aarch64_classify_symbolic_expression (op, SYMBOL_CONTEXT_ADR) ++ != SYMBOL_FORCE_TO_MEM); + }) + + (define_predicate "aarch64_tls_ie_symref" +@@ -165,15 +165,10 @@ + }) + + (define_predicate "aarch64_mov_operand" +- (and (match_code "reg,subreg,mem,const_int,symbol_ref,high") ++ (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high") + (ior (match_operand 0 "register_operand") + (ior (match_operand 0 "memory_operand") +- (ior (match_test "GET_CODE (op) == HIGH +- && aarch64_valid_symref (XEXP (op, 0), +- GET_MODE (XEXP (op, 0)))") +- (ior (match_test "CONST_INT_P (op) +- && aarch64_move_imm (INTVAL (op), mode)") +- (match_test "aarch64_const_address (op, mode)"))))))) ++ (match_test "aarch64_mov_operand_p (op, SYMBOL_CONTEXT_ADR, mode)"))))) + + (define_predicate "aarch64_movti_operand" + (and (match_code "reg,subreg,mem,const_int") +--- a/src/gcc/config/aarch64/aarch64-elf.h ++++ b/src/gcc/config/aarch64/aarch64-elf.h +@@ -106,7 +106,6 @@ + + #define ASM_COMMENT_START "//" + +-#define REGISTER_PREFIX "" + #define LOCAL_LABEL_PREFIX "." + #define USER_LABEL_PREFIX "" + +--- a/src/gcc/config/aarch64/arm_neon.h ++++ b/src/gcc/config/aarch64/arm_neon.h +@@ -29,6 +29,9 @@ + + #include + ++#define __AARCH64_UINT64_C(__C) ((uint64_t) __C) ++#define __AARCH64_INT64_C(__C) ((int64_t) __C) + -+2013-05-02 Matthew Gretton-Dann + typedef __builtin_aarch64_simd_qi int8x8_t + __attribute__ ((__vector_size__ (8))); + typedef __builtin_aarch64_simd_hi int16x4_t +@@ -446,7 +449,66 @@ + poly16x8_t val[4]; + } poly16x8x4_t; + ++/* vget_lane internal macros. */ + ++#define __aarch64_vget_lane_any(__size, __cast_ret, __cast_a, __a, __b) \ ++ (__cast_ret \ ++ __builtin_aarch64_get_lane##__size (__cast_a __a, __b)) + -+ Backport from trunk r198136-198137,198142,198176 -+ 2013-04-22 James Greenhalgh ++#define __aarch64_vget_lane_f32(__a, __b) \ ++ __aarch64_vget_lane_any (v2sf, , , __a, __b) ++#define __aarch64_vget_lane_f64(__a, __b) (__a) + -+ * gcc.target/aarch64/vrecps.c: New. -+ * gcc.target/aarch64/vrecpx.c: Likewise. ++#define __aarch64_vget_lane_p8(__a, __b) \ ++ __aarch64_vget_lane_any (v8qi, (poly8_t), (int8x8_t), __a, __b) ++#define __aarch64_vget_lane_p16(__a, __b) \ ++ __aarch64_vget_lane_any (v4hi, (poly16_t), (int16x4_t), __a, __b) + -+2013-05-02 Matthew Gretton-Dann ++#define __aarch64_vget_lane_s8(__a, __b) \ ++ __aarch64_vget_lane_any (v8qi, , ,__a, __b) ++#define __aarch64_vget_lane_s16(__a, __b) \ ++ __aarch64_vget_lane_any (v4hi, , ,__a, __b) ++#define __aarch64_vget_lane_s32(__a, __b) \ ++ __aarch64_vget_lane_any (v2si, , ,__a, __b) ++#define __aarch64_vget_lane_s64(__a, __b) (__a) + -+ Backport from trunk r198020. -+ 2013-04-16 Naveen H.S ++#define __aarch64_vget_lane_u8(__a, __b) \ ++ __aarch64_vget_lane_any (v8qi, (uint8_t), (int8x8_t), __a, __b) ++#define __aarch64_vget_lane_u16(__a, __b) \ ++ __aarch64_vget_lane_any (v4hi, (uint16_t), (int16x4_t), __a, __b) ++#define __aarch64_vget_lane_u32(__a, __b) \ ++ __aarch64_vget_lane_any (v2si, (uint32_t), (int32x2_t), __a, __b) ++#define __aarch64_vget_lane_u64(__a, __b) (__a) + -+ * gcc.target/aarch64/adds3.c: New. -+ * gcc.target/aarch64/subs3.c: New. ++#define __aarch64_vgetq_lane_f32(__a, __b) \ ++ __aarch64_vget_lane_any (v4sf, , , __a, __b) ++#define __aarch64_vgetq_lane_f64(__a, __b) \ ++ __aarch64_vget_lane_any (v2df, , , __a, __b) + -+2013-05-02 Matthew Gretton-Dann ++#define __aarch64_vgetq_lane_p8(__a, __b) \ ++ __aarch64_vget_lane_any (v16qi, (poly8_t), (int8x16_t), __a, __b) ++#define __aarch64_vgetq_lane_p16(__a, __b) \ ++ __aarch64_vget_lane_any (v8hi, (poly16_t), (int16x8_t), __a, __b) + -+ Backport from trunk r197965. -+ 2013-04-15 Kyrylo Tkachov ++#define __aarch64_vgetq_lane_s8(__a, __b) \ ++ __aarch64_vget_lane_any (v16qi, , ,__a, __b) ++#define __aarch64_vgetq_lane_s16(__a, __b) \ ++ __aarch64_vget_lane_any (v8hi, , ,__a, __b) ++#define __aarch64_vgetq_lane_s32(__a, __b) \ ++ __aarch64_vget_lane_any (v4si, , ,__a, __b) ++#define __aarch64_vgetq_lane_s64(__a, __b) \ ++ __aarch64_vget_lane_any (v2di, , ,__a, __b) + -+ * gcc.target/arm/anddi3-opt.c: New test. -+ * gcc.target/arm/anddi3-opt2.c: Likewise. -+ -+2013-05-02 Matthew Gretton-Dann -+ -+ Backport from trunk r197642. -+ 2013-04-09 Kyrylo Tkachov -+ -+ * gcc.target/arm/minmax_minus.c: New test. -+ -+2013-05-02 Matthew Gretton-Dann -+ -+ Backport from trunk r197530,197921. -+ 2013-04-05 Greta Yorsh -+ -+ * gcc.target/arm/peep-ldrd-1.c: New test. -+ * gcc.target/arm/peep-strd-1.c: Likewise. -+ -+2013-05-02 Matthew Gretton-Dann -+ -+ Backport from trunk r197523. -+ 2013-04-05 Kyrylo Tkachov -+ -+ * lib/target-supports.exp (add_options_for_arm_v8_neon): -+ Add -march=armv8-a when we use v8 NEON. -+ (check_effective_target_vect_call_btruncf): Remove arm-*-*-*. -+ (check_effective_target_vect_call_ceilf): Likewise. -+ (check_effective_target_vect_call_floorf): Likewise. -+ (check_effective_target_vect_call_roundf): Likewise. -+ (check_vect_support_and_set_flags): Remove check for arm_v8_neon. -+ * gcc.target/arm/vect-rounding-btruncf.c: New testcase. -+ * gcc.target/arm/vect-rounding-ceilf.c: Likewise. -+ * gcc.target/arm/vect-rounding-floorf.c: Likewise. -+ * gcc.target/arm/vect-rounding-roundf.c: Likewise. -+ -+2013-05-02 Matthew Gretton-Dann -+ -+ Backport from trunk r197518-197522,197516-197528. -+ 2013-04-05 Greta Yorsh -+ -+ * gcc.target/arm/negdi-1.c: New test. -+ * gcc.target/arm/negdi-2.c: Likewise. -+ * gcc.target/arm/negdi-3.c: Likewise. -+ * gcc.target/arm/negdi-4.c: Likewise. -+ -+2013-05-02 Matthew Gretton-Dann -+ -+ Backport from trunk r197489-197491. -+ 2013-04-04 Kyrylo Tkachov -+ -+ * lib/target-supports.exp (check_effective_target_arm_v8_neon_hw): -+ New procedure. -+ (check_effective_target_arm_v8_neon_ok_nocache): -+ Likewise. -+ (check_effective_target_arm_v8_neon_ok): Change to use -+ check_effective_target_arm_v8_neon_ok_nocache. -+ (add_options_for_arm_v8_neon): Use et_arm_v8_neon_flags to set ARMv8 -+ NEON flags. -+ (check_effective_target_vect_call_btruncf): -+ Enable for arm and ARMv8 NEON. -+ (check_effective_target_vect_call_ceilf): Likewise. -+ (check_effective_target_vect_call_floorf): Likewise. -+ (check_effective_target_vect_call_roundf): Likewise. -+ (check_vect_support_and_set_flags): Handle ARMv8 NEON effective -+ target. -+ -+2013-05-02 Matthew Gretton-Dann -+ -+ Backport from trunk r196795-196797,196957. -+ 2013-03-19 Ian Bolton -+ -+ * gcc.target/aarch64/sbc.c: New test. -+ -+ 2013-03-19 Ian Bolton -+ -+ * gcc.target/aarch64/ror.c: New test. -+ -+ 2013-03-19 Ian Bolton -+ -+ * gcc.target/aarch64/extr.c: New test. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. -+ -+2013-04-08 Matthew Gretton-Dann -+ -+ Backport from trunk r197052. -+ 2013-03-25 Kyrylo Tkachov -+ -+ * gcc.target/arm/vseleqdf.c: New test. -+ * gcc.target/arm/vseleqsf.c: Likewise. -+ * gcc.target/arm/vselgedf.c: Likewise. -+ * gcc.target/arm/vselgesf.c: Likewise. -+ * gcc.target/arm/vselgtdf.c: Likewise. -+ * gcc.target/arm/vselgtsf.c: Likewise. -+ * gcc.target/arm/vselledf.c: Likewise. -+ * gcc.target/arm/vsellesf.c: Likewise. -+ * gcc.target/arm/vselltdf.c: Likewise. -+ * gcc.target/arm/vselltsf.c: Likewise. -+ * gcc.target/arm/vselnedf.c: Likewise. -+ * gcc.target/arm/vselnesf.c: Likewise. -+ * gcc.target/arm/vselvcdf.c: Likewise. -+ * gcc.target/arm/vselvcsf.c: Likewise. -+ * gcc.target/arm/vselvsdf.c: Likewise. -+ * gcc.target/arm/vselvssf.c: Likewise. ++#define __aarch64_vgetq_lane_u8(__a, __b) \ ++ __aarch64_vget_lane_any (v16qi, (uint8_t), (int8x16_t), __a, __b) ++#define __aarch64_vgetq_lane_u16(__a, __b) \ ++ __aarch64_vget_lane_any (v8hi, (uint16_t), (int16x8_t), __a, __b) ++#define __aarch64_vgetq_lane_u32(__a, __b) \ ++ __aarch64_vget_lane_any (v4si, (uint32_t), (int32x4_t), __a, __b) ++#define __aarch64_vgetq_lane_u64(__a, __b) \ ++ __aarch64_vget_lane_any (v2di, (uint64_t), (int64x2_t), __a, __b) + -+2013-04-08 Matthew Gretton-Dann ++/* vadd */ + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) + vadd_s8 (int8x8_t __a, int8x8_t __b) + { +@@ -2307,155 +2369,156 @@ + return (poly16x4_t) __a; + } + ++/* vget_lane */ + -+ Backport from trunk r197051. -+ 2013-03-25 Kyrylo Tkachov ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vget_lane_f32 (float32x2_t __a, const int __b) ++{ ++ return __aarch64_vget_lane_f32 (__a, __b); ++} + -+ * gcc.target/aarch64/atomic-comp-swap-release-acquire.c: Move test -+ body from here... -+ * gcc.target/aarch64/atomic-comp-swap-release-acquire.x: ... to here. -+ * gcc.target/aarch64/atomic-op-acq_rel.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-acq_rel.x: ... to here. -+ * gcc.target/aarch64/atomic-op-acquire.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-acquire.x: ... to here. -+ * gcc.target/aarch64/atomic-op-char.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-char.x: ... to here. -+ * gcc.target/aarch64/atomic-op-consume.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-consume.x: ... to here. -+ * gcc.target/aarch64/atomic-op-int.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-int.x: ... to here. -+ * gcc.target/aarch64/atomic-op-relaxed.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-relaxed.x: ... to here. -+ * gcc.target/aarch64/atomic-op-release.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-release.x: ... to here. -+ * gcc.target/aarch64/atomic-op-seq_cst.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-seq_cst.x: ... to here. -+ * gcc.target/aarch64/atomic-op-short.c: Move test body from here... -+ * gcc.target/aarch64/atomic-op-short.x: ... to here. -+ * gcc.target/arm/atomic-comp-swap-release-acquire.c: New test. -+ * gcc.target/arm/atomic-op-acq_rel.c: Likewise. -+ * gcc.target/arm/atomic-op-acquire.c: Likewise. -+ * gcc.target/arm/atomic-op-char.c: Likewise. -+ * gcc.target/arm/atomic-op-consume.c: Likewise. -+ * gcc.target/arm/atomic-op-int.c: Likewise. -+ * gcc.target/arm/atomic-op-relaxed.c: Likewise. -+ * gcc.target/arm/atomic-op-release.c: Likewise. -+ * gcc.target/arm/atomic-op-seq_cst.c: Likewise. -+ * gcc.target/arm/atomic-op-short.c: Likewise. ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vget_lane_f64 (float64x1_t __a, const int __b) ++{ ++ return __aarch64_vget_lane_f64 (__a, __b); ++} + -+2013-04-08 Matthew Gretton-Dann ++__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) ++vget_lane_p8 (poly8x8_t __a, const int __b) ++{ ++ return __aarch64_vget_lane_p8 (__a, __b); ++} + -+ Backport from trunk r196876. -+ 2013-03-21 Christophe Lyon ++__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) ++vget_lane_p16 (poly16x4_t __a, const int __b) ++{ ++ return __aarch64_vget_lane_p16 (__a, __b); ++} + -+ * gcc.target/arm/neon-for-64bits-1.c: New tests. -+ * gcc.target/arm/neon-for-64bits-2.c: Likewise. + __extension__ static __inline int8_t __attribute__ ((__always_inline__)) + vget_lane_s8 (int8x8_t __a, const int __b) + { +- return (int8_t) __builtin_aarch64_get_lane_signedv8qi (__a, __b); ++ return __aarch64_vget_lane_s8 (__a, __b); + } + + __extension__ static __inline int16_t __attribute__ ((__always_inline__)) + vget_lane_s16 (int16x4_t __a, const int __b) + { +- return (int16_t) __builtin_aarch64_get_lane_signedv4hi (__a, __b); ++ return __aarch64_vget_lane_s16 (__a, __b); + } + + __extension__ static __inline int32_t __attribute__ ((__always_inline__)) + vget_lane_s32 (int32x2_t __a, const int __b) + { +- return (int32_t) __builtin_aarch64_get_lane_signedv2si (__a, __b); ++ return __aarch64_vget_lane_s32 (__a, __b); + } + +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vget_lane_f32 (float32x2_t __a, const int __b) ++__extension__ static __inline int64_t __attribute__ ((__always_inline__)) ++vget_lane_s64 (int64x1_t __a, const int __b) + { +- return (float32_t) __builtin_aarch64_get_lanev2sf (__a, __b); ++ return __aarch64_vget_lane_s64 (__a, __b); + } + + __extension__ static __inline uint8_t __attribute__ ((__always_inline__)) + vget_lane_u8 (uint8x8_t __a, const int __b) + { +- return (uint8_t) __builtin_aarch64_get_lane_unsignedv8qi ((int8x8_t) __a, +- __b); ++ return __aarch64_vget_lane_u8 (__a, __b); + } + + __extension__ static __inline uint16_t __attribute__ ((__always_inline__)) + vget_lane_u16 (uint16x4_t __a, const int __b) + { +- return (uint16_t) __builtin_aarch64_get_lane_unsignedv4hi ((int16x4_t) __a, +- __b); ++ return __aarch64_vget_lane_u16 (__a, __b); + } + + __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) + vget_lane_u32 (uint32x2_t __a, const int __b) + { +- return (uint32_t) __builtin_aarch64_get_lane_unsignedv2si ((int32x2_t) __a, +- __b); ++ return __aarch64_vget_lane_u32 (__a, __b); + } + +-__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) +-vget_lane_p8 (poly8x8_t __a, const int __b) ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vget_lane_u64 (uint64x1_t __a, const int __b) + { +- return (poly8_t) __builtin_aarch64_get_lane_unsignedv8qi ((int8x8_t) __a, +- __b); ++ return __aarch64_vget_lane_u64 (__a, __b); + } + +-__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) +-vget_lane_p16 (poly16x4_t __a, const int __b) ++/* vgetq_lane */ + -+2013-04-08 Matthew Gretton-Dann ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vgetq_lane_f32 (float32x4_t __a, const int __b) + { +- return (poly16_t) __builtin_aarch64_get_lane_unsignedv4hi ((int16x4_t) __a, +- __b); ++ return __aarch64_vgetq_lane_f32 (__a, __b); + } + +-__extension__ static __inline int64_t __attribute__ ((__always_inline__)) +-vget_lane_s64 (int64x1_t __a, const int __b) ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vgetq_lane_f64 (float64x2_t __a, const int __b) + { +- return (int64_t) __builtin_aarch64_get_lanedi (__a, __b); ++ return __aarch64_vgetq_lane_f64 (__a, __b); + } + +-__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) +-vget_lane_u64 (uint64x1_t __a, const int __b) ++__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) ++vgetq_lane_p8 (poly8x16_t __a, const int __b) + { +- return (uint64_t) __builtin_aarch64_get_lanedi ((int64x1_t) __a, __b); ++ return __aarch64_vgetq_lane_p8 (__a, __b); + } + ++__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) ++vgetq_lane_p16 (poly16x8_t __a, const int __b) ++{ ++ return __aarch64_vgetq_lane_p16 (__a, __b); ++} + -+ Backport from trunk r196858. -+ 2013-03-21 Naveen H.S + __extension__ static __inline int8_t __attribute__ ((__always_inline__)) + vgetq_lane_s8 (int8x16_t __a, const int __b) + { +- return (int8_t) __builtin_aarch64_get_lane_signedv16qi (__a, __b); ++ return __aarch64_vgetq_lane_s8 (__a, __b); + } + + __extension__ static __inline int16_t __attribute__ ((__always_inline__)) + vgetq_lane_s16 (int16x8_t __a, const int __b) + { +- return (int16_t) __builtin_aarch64_get_lane_signedv8hi (__a, __b); ++ return __aarch64_vgetq_lane_s16 (__a, __b); + } + + __extension__ static __inline int32_t __attribute__ ((__always_inline__)) + vgetq_lane_s32 (int32x4_t __a, const int __b) + { +- return (int32_t) __builtin_aarch64_get_lane_signedv4si (__a, __b); ++ return __aarch64_vgetq_lane_s32 (__a, __b); + } + +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vgetq_lane_f32 (float32x4_t __a, const int __b) ++__extension__ static __inline int64_t __attribute__ ((__always_inline__)) ++vgetq_lane_s64 (int64x2_t __a, const int __b) + { +- return (float32_t) __builtin_aarch64_get_lanev4sf (__a, __b); ++ return __aarch64_vgetq_lane_s64 (__a, __b); + } + +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vgetq_lane_f64 (float64x2_t __a, const int __b) +-{ +- return (float64_t) __builtin_aarch64_get_lanev2df (__a, __b); +-} +- + __extension__ static __inline uint8_t __attribute__ ((__always_inline__)) + vgetq_lane_u8 (uint8x16_t __a, const int __b) + { +- return (uint8_t) __builtin_aarch64_get_lane_unsignedv16qi ((int8x16_t) __a, +- __b); ++ return __aarch64_vgetq_lane_u8 (__a, __b); + } + + __extension__ static __inline uint16_t __attribute__ ((__always_inline__)) + vgetq_lane_u16 (uint16x8_t __a, const int __b) + { +- return (uint16_t) __builtin_aarch64_get_lane_unsignedv8hi ((int16x8_t) __a, +- __b); ++ return __aarch64_vgetq_lane_u16 (__a, __b); + } + + __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) + vgetq_lane_u32 (uint32x4_t __a, const int __b) + { +- return (uint32_t) __builtin_aarch64_get_lane_unsignedv4si ((int32x4_t) __a, +- __b); ++ return __aarch64_vgetq_lane_u32 (__a, __b); + } + +-__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) +-vgetq_lane_p8 (poly8x16_t __a, const int __b) +-{ +- return (poly8_t) __builtin_aarch64_get_lane_unsignedv16qi ((int8x16_t) __a, +- __b); +-} +- +-__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) +-vgetq_lane_p16 (poly16x8_t __a, const int __b) +-{ +- return (poly16_t) __builtin_aarch64_get_lane_unsignedv8hi ((int16x8_t) __a, +- __b); +-} +- +-__extension__ static __inline int64_t __attribute__ ((__always_inline__)) +-vgetq_lane_s64 (int64x2_t __a, const int __b) +-{ +- return __builtin_aarch64_get_lane_unsignedv2di (__a, __b); +-} +- + __extension__ static __inline uint64_t __attribute__ ((__always_inline__)) + vgetq_lane_u64 (uint64x2_t __a, const int __b) + { +- return (uint64_t) __builtin_aarch64_get_lane_unsignedv2di ((int64x2_t) __a, +- __b); ++ return __aarch64_vgetq_lane_u64 (__a, __b); + } + ++/* vreinterpret */ + -+ * gcc.target/aarch64/vect.c: Test and result vector added -+ for sabd and saba instructions. -+ * gcc.target/aarch64/vect-compile.c: Check for sabd and saba -+ instructions in assembly. -+ * gcc.target/aarch64/vect.x: Add sabd and saba test functions. -+ * gcc.target/aarch64/vect-fp.c: Test and result vector added -+ for fabd instruction. -+ * gcc.target/aarch64/vect-fp-compile.c: Check for fabd -+ instruction in assembly. -+ * gcc.target/aarch64/vect-fp.x: Add fabd test function. ---- a/src/gcc/testsuite/gcc.dg/shrink-wrap-alloca.c -+++ b/src/gcc/testsuite/gcc.dg/shrink-wrap-alloca.c -@@ -0,0 +1,11 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O2 -g" } */ + __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) + vreinterpret_p8_s8 (int8x8_t __a) + { +@@ -3805,6 +3868,85 @@ + return (uint32x4_t) __builtin_aarch64_reinterpretv4siv8hi ((int16x8_t) __a); + } + ++#define __GET_LOW(__TYPE) \ ++ uint64x2_t tmp = vreinterpretq_u64_##__TYPE (__a); \ ++ uint64_t lo = vgetq_lane_u64 (tmp, 0); \ ++ return vreinterpret_##__TYPE##_u64 (lo); + -+int *p; ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vget_low_f32 (float32x4_t __a) ++{ ++ __GET_LOW (f32); ++} + -+void -+test (int a) ++__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) ++vget_low_f64 (float64x2_t __a) +{ -+ if (a > 0) -+ p = __builtin_alloca (4); ++ return vgetq_lane_f64 (__a, 0); +} ---- a/src/gcc/testsuite/gcc.dg/shrink-wrap-pretend.c -+++ b/src/gcc/testsuite/gcc.dg/shrink-wrap-pretend.c -@@ -0,0 +1,36 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O2 -g" } */ + -+#include -+#include -+#include ++__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) ++vget_low_p8 (poly8x16_t __a) ++{ ++ __GET_LOW (p8); ++} + -+#define DEBUG_BUFFER_SIZE 80 -+int unifi_debug = 5; ++__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) ++vget_low_p16 (poly16x8_t __a) ++{ ++ __GET_LOW (p16); ++} + -+void -+unifi_trace (void* ospriv, int level, const char *fmt, ...) ++__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) ++vget_low_s8 (int8x16_t __a) +{ -+ static char s[DEBUG_BUFFER_SIZE]; -+ va_list args; -+ unsigned int len; ++ __GET_LOW (s8); ++} + -+ if (!ospriv) -+ return; ++__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) ++vget_low_s16 (int16x8_t __a) ++{ ++ __GET_LOW (s16); ++} + -+ if (unifi_debug >= level) -+ { -+ va_start (args, fmt); -+ len = vsnprintf (&(s)[0], (DEBUG_BUFFER_SIZE), fmt, args); -+ va_end (args); ++__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) ++vget_low_s32 (int32x4_t __a) ++{ ++ __GET_LOW (s32); ++} + -+ if (len >= DEBUG_BUFFER_SIZE) -+ { -+ (s)[DEBUG_BUFFER_SIZE - 2] = '\n'; -+ (s)[DEBUG_BUFFER_SIZE - 1] = 0; -+ } ++__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) ++vget_low_s64 (int64x2_t __a) ++{ ++ return vgetq_lane_s64 (__a, 0); ++} + -+ printf ("%s", s); -+ } ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vget_low_u8 (uint8x16_t __a) ++{ ++ __GET_LOW (u8); +} + ---- a/src/gcc/testsuite/gcc.dg/debug/pr57351.c -+++ b/src/gcc/testsuite/gcc.dg/debug/pr57351.c -@@ -0,0 +1,54 @@ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_neon } */ -+/* { dg-options "-std=c99 -Os -g -march=armv7-a" } */ -+/* { dg-add-options arm_neon } */ ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vget_low_u16 (uint16x8_t __a) ++{ ++ __GET_LOW (u16); ++} + -+typedef unsigned int size_t; -+typedef int ptrdiff_t; -+typedef signed char int8_t ; -+typedef signed long long int64_t; -+typedef int8_t GFC_INTEGER_1; -+typedef GFC_INTEGER_1 GFC_LOGICAL_1; -+typedef int64_t GFC_INTEGER_8; -+typedef GFC_INTEGER_8 GFC_LOGICAL_8; -+typedef ptrdiff_t index_type; -+typedef struct descriptor_dimension ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vget_low_u32 (uint32x4_t __a) +{ -+ index_type lower_bound; -+ index_type _ubound; ++ __GET_LOW (u32); +} -+descriptor_dimension; -+typedef struct { GFC_LOGICAL_1 *base_addr; size_t offset; index_type dtype; descriptor_dimension dim[7];} gfc_array_l1; -+typedef struct { GFC_LOGICAL_8 *base_addr; size_t offset; index_type dtype; descriptor_dimension dim[7];} gfc_array_l8; -+void -+all_l8 (gfc_array_l8 * const restrict retarray, -+ gfc_array_l1 * const restrict array, -+ const index_type * const restrict pdim) ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vget_low_u64 (uint64x2_t __a) +{ -+ GFC_LOGICAL_8 * restrict dest; -+ index_type n; -+ index_type len; -+ index_type delta; -+ index_type dim; -+ dim = (*pdim) - 1; -+ len = ((array)->dim[dim]._ubound + 1 - (array)->dim[dim].lower_bound); -+ for (n = 0; n < dim; n++) -+ { -+ const GFC_LOGICAL_1 * restrict src; -+ GFC_LOGICAL_8 result; -+ { -+ result = 1; -+ { -+ for (n = 0; n < len; n++, src += delta) -+ { -+ if (! *src) -+ { -+ result = 0; -+ break; -+ } -+ } -+ *dest = result; -+ } -+ } -+ } -+} ---- a/src/gcc/testsuite/gcc.dg/lower-subreg-1.c -+++ b/src/gcc/testsuite/gcc.dg/lower-subreg-1.c -@@ -1,4 +1,4 @@ --/* { dg-do compile { target { ! { mips64 || { arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ -+/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ - /* { dg-options "-O -fdump-rtl-subreg1" } */ - /* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } { "*" } { "" } } */ - /* { dg-require-effective-target ilp32 } */ ---- a/src/gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c -+++ b/src/gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c -@@ -0,0 +1,26 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O2 -g" } */ -+ -+unsigned char a, b, d, f, g; -+ -+int test (void); -+ -+int -+baz (int c) -+{ -+ if (c == 0) return test (); -+ if (b & 1) -+ { -+ g = 0; -+ int e = (a & 0x0f) - (g & 0x0f); -+ -+ if (!a) b |= 0x80; -+ a = e + test (); -+ f = g/5 + a*3879 + b *2985; -+ } -+ else -+ { -+ f = g + a*39879 + b *25; -+ } -+ return test (); -+} ---- a/src/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c -+++ b/src/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c -@@ -16,7 +16,7 @@ - E, F and G are passed on stack. So the size of the stack argument - data is 20. */ - #define STACK_ARGUMENTS_SIZE 20 --#elif defined __MMIX__ -+#elif defined __aarch64__ || defined __MMIX__ - /* No parameters on stack for bar. */ - #define STACK_ARGUMENTS_SIZE 0 - #else ---- a/src/gcc/testsuite/gcc.dg/tree-ssa/coalesce-1.c -+++ b/src/gcc/testsuite/gcc.dg/tree-ssa/coalesce-1.c -@@ -0,0 +1,195 @@ -+/* { dg-do compile } */ -+ -+/* { dg-options "-O2 -fdump-rtl-expand-details" } */ -+ -+typedef long unsigned int size_t; -+union tree_node; -+typedef union tree_node *tree; -+union gimple_statement_d; -+typedef union gimple_statement_d *gimple; -+typedef const union tree_node *const_tree; -+typedef const union gimple_statement_d *const_gimple; -+struct gimple_seq_d; -+typedef struct gimple_seq_d *gimple_seq; -+struct edge_def; -+typedef struct edge_def *edge; -+struct basic_block_def; -+typedef struct basic_block_def *basic_block; -+typedef const struct basic_block_def *const_basic_block; -+struct tree_exp -+{ -+ tree operands[1]; -+}; -+typedef struct ssa_use_operand_d -+{ -+ tree *use; -+} ssa_use_operand_t; -+struct phi_arg_d -+{ -+ struct ssa_use_operand_d imm_use; -+}; -+union tree_node -+{ -+ struct tree_exp exp; -+}; -+struct function -+{ -+}; -+extern struct function *cfun; -+struct edge_def -+{ -+ unsigned int dest_idx; -+}; -+static __inline__ void -+VEC_edge_must_be_pointer_type (void) -+{ -+ (void) ((edge) 1 == (void *) 1); -+} typedef struct VEC_edge_base -+ -+{ -+ unsigned num; -+ unsigned alloc; -+ edge vec[1]; -+} VEC_edge_base; -+typedef struct VEC_edge_none -+{ -+ VEC_edge_base base; -+} VEC_edge_none; -+ -+static __inline__ edge -+VEC_edge_base_index (const VEC_edge_base * vec_, unsigned ix_, -+ const char *file_, unsigned line_, const char *function_) -+{ -+ return vec_->vec[ix_]; -+} -+ -+typedef struct VEC_edge_gc -+{ -+ VEC_edge_base base; -+} VEC_edge_gc; -+struct basic_block_def -+{ -+ VEC_edge_gc *succs; -+}; -+static __inline__ edge -+single_succ_edge (const_basic_block bb) -+{ -+ return (VEC_edge_base_index -+ ((((bb)->succs) ? &((bb)->succs)->base : 0), (0), -+ "/home/gcc/virgin-gcc/gcc/basic-block.h", 563, __FUNCTION__)); -+} -+ -+edge find_edge (basic_block, basic_block); -+typedef tree *def_operand_p; -+typedef ssa_use_operand_t *use_operand_p; -+struct gimple_seq_node_d; -+typedef struct gimple_seq_node_d *gimple_seq_node; -+struct gimple_seq_node_d -+{ -+ gimple stmt; -+}; -+typedef struct -+{ -+ gimple_seq_node ptr; -+ gimple_seq seq; -+ basic_block bb; -+} gimple_stmt_iterator; -+struct gimple_statement_phi -+{ -+ struct phi_arg_d args[1]; -+}; -+union gimple_statement_d -+{ -+ struct gimple_statement_phi gimple_phi; -+}; -+extern size_t const gimple_ops_offset_[]; -+static __inline__ tree * -+gimple_ops (gimple gs) -+{ -+ size_t off; -+ off = gimple_ops_offset_[gimple_statement_structure (gs)]; -+ return (tree *) ((char *) gs + off); -+} -+ -+static __inline__ tree -+gimple_op (const_gimple gs, unsigned i) -+{ -+ return gimple_ops ((((union -+ { -+ const union gimple_statement_d * _q; -+ union gimple_statement_d * _nq;}) (((gs))))._nq))[i]; -+} -+ -+static __inline__ struct phi_arg_d * -+gimple_phi_arg (gimple gs, unsigned index) -+{ -+ return &(gs->gimple_phi.args[index]); -+} -+ -+static __inline__ tree -+gimple_switch_label (const_gimple gs, unsigned index) -+{ -+ return gimple_op (gs, index + 1); -+} -+ -+gimple_stmt_iterator gsi_start_phis (basic_block); -+extern basic_block label_to_block_fn (struct function *, tree); -+ -+static __inline__ tree -+get_use_from_ptr (use_operand_p use) -+{ -+ return *(use->use); -+} -+ -+static __inline__ use_operand_p -+gimple_phi_arg_imm_use_ptr (gimple gs, int i) -+{ -+ return &gimple_phi_arg (gs, i)->imm_use; -+} -+ -+struct switch_conv_info -+{ -+ basic_block final_bb; -+ basic_block switch_bb; -+ const char *reason; -+ tree *default_values; -+}; -+static struct switch_conv_info info; -+ -+static void -+gather_default_values (tree default_case) -+{ -+ gimple_stmt_iterator gsi; -+ basic_block bb = -+ (label_to_block_fn ((cfun + 0), default_case->exp.operands[2])); -+ edge e; -+ int i = 0; -+ if (bb == info.final_bb) -+ e = find_edge (info.switch_bb, bb); -+ else -+ e = single_succ_edge (bb); -+ for (gsi = gsi_start_phis (info.final_bb); -+ gsi_gsi_start_phis (info.final_bb); gsi_next (&gsi)) -+ { -+ gimple phi = gsi.ptr->stmt; -+ tree val = get_use_from_ptr (gimple_phi_arg_imm_use_ptr -+ ((((phi))), (((e)->dest_idx)))); -+ info.default_values[i++] = val; -+ } -+} -+ -+unsigned char -+process_switch (gimple swtch) -+{ -+ unsigned int i, branch_num = gimple_switch_num_labels (swtch); -+ tree index_type; -+ info.reason = "switch has no labels\n"; -+ gather_default_values (gimple_switch_label (swtch, 0)); -+} -+ -+/* Verify that out-of-ssa coalescing did its job by verifying there are not -+ any partition copies inserted. */ -+ -+/* { dg-final { scan-rtl-dump-not "partition copy" "expand"} } */ -+/* { dg-final { cleanup-rtl-dump "expand" } } */ -+ ---- a/src/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c -+++ b/src/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c -@@ -1,6 +1,6 @@ - /* { dg-do run { target vect_cmdline_needed } } */ --/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */ --/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */ -+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -fvect-cost-model=dynamic" } */ -+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -fvect-cost-model=dynamic -mno-sse" { target { i?86-*-* x86_64-*-* } } } */ - - #include - ---- a/src/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-11.c -+++ b/src/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-11.c -@@ -0,0 +1,25 @@ -+/* { dg-do compile } */ -+/* { dg-options "-O1 -fdump-tree-optimized" } */ -+ -+int f(int a, int b, int c) -+{ -+ if (a == 0 && b > c) -+ return 0; -+ return a; ++ return vgetq_lane_u64 (__a, 0); +} + -+int g(int a, int b, int c) -+{ -+ if (a == 42 && b > c) -+ return 42; -+ return a; -+} ++#undef __GET_LOW + -+int h(int a, int b, int c, int d) -+{ -+ if (a == d && b > c) -+ return d; -+ return a; -+} -+/* { dg-final { scan-tree-dump-times "if" 0 "optimized"} } */ -+/* { dg-final { cleanup-tree-dump "optimized" } } */ ---- a/src/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c -+++ b/src/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c -@@ -1,6 +1,6 @@ - /* { dg-do run { target vect_cmdline_needed } } */ --/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */ --/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */ -+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -fvect-cost-model=dynamic" } */ -+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -fvect-cost-model=dynamic -mno-sse" { target { i?86-*-* x86_64-*-* } } } */ - - #include - ---- a/src/gcc/testsuite/gcc.dg/tls/pr42894.c -+++ b/src/gcc/testsuite/gcc.dg/tls/pr42894.c -@@ -1,6 +1,5 @@ - /* PR target/42894 */ - /* { dg-do compile } */ --/* { dg-options "-march=armv5te -mthumb" { target arm*-*-* } } */ - /* { dg-require-effective-target tls } */ - - extern __thread int t; ---- a/src/gcc/testsuite/gcc.dg/builtin-apply2.c -+++ b/src/gcc/testsuite/gcc.dg/builtin-apply2.c -@@ -1,6 +1,6 @@ - /* { dg-do run } */ - /* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "aarch64*-*-* avr-*-* " } { "*" } { "" } } */ --/* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { "arm*-*-*" } { "-mfloat-abi=hard" } { "" } } */ -+/* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { arm*-*-* && arm_hf_eabi } { "*" } { "" } } */ - - /* PR target/12503 */ - /* Origin: */ ---- a/src/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c -+++ b/src/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c -@@ -1,4 +1,6 @@ --/* { dg-require-effective-target vect_int } */ -+/* { dg-require-effective-target vect_int } -+ { dg-skip-if "AArch64 tiny code model does not support programs larger than 1MiB" {aarch64_tiny} {"*"} {""} } -+ */ - - #include - #include "tree-vect.h" ---- a/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C -+++ b/src/gcc/testsuite/g++.dg/asan/large-func-test-1.C -@@ -37,9 +37,9 @@ - - // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow on address\[^\n\r]*" } - // { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } --// { dg-output "READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } -+// { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } - // { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } --// { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } --// { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } -+// { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } -+// { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } - // { dg-output " #0( 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } - // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } ---- a/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C -+++ b/src/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C -@@ -45,9 +45,9 @@ + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) + vcombine_s8 (int8x8_t __a, int8x8_t __b) + { +@@ -4468,160 +4610,6 @@ + return result; } - // { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } --// { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } --// { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } --// { dg-output "previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } -+// { dg-output "\[^\n\r]*WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } -+// { dg-output "\[^\n\r]*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } -+// { dg-output "\[^\n\r]*previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } - // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } - // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } - // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } ---- a/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c -@@ -15,7 +15,7 @@ - /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ --/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ --/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ ---- a/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c -@@ -2,6 +2,7 @@ - - /* { dg-do run { target setrlimit } } */ - /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ -+/* { dg-require-effective-target hw } */ - /* { dg-shouldfail "asan" } */ - - #include ---- a/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c -@@ -19,4 +19,4 @@ +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vabs_f32 (float32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("fabs %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) +-vabs_s8 (int8x8_t a) +-{ +- int8x8_t result; +- __asm__ ("abs %0.8b,%1.8b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +-vabs_s16 (int16x4_t a) +-{ +- int16x4_t result; +- __asm__ ("abs %0.4h,%1.4h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +-vabs_s32 (int32x2_t a) +-{ +- int32x2_t result; +- __asm__ ("abs %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vabsq_f32 (float32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("fabs %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vabsq_f64 (float64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("fabs %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) +-vabsq_s8 (int8x16_t a) +-{ +- int8x16_t result; +- __asm__ ("abs %0.16b,%1.16b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +-vabsq_s16 (int16x8_t a) +-{ +- int16x8_t result; +- __asm__ ("abs %0.8h,%1.8h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +-vabsq_s32 (int32x4_t a) +-{ +- int32x4_t result; +- __asm__ ("abs %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) +-vabsq_s64 (int64x2_t a) +-{ +- int64x2_t result; +- __asm__ ("abs %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vacged_f64 (float64_t a, float64_t b) +-{ +- float64_t result; +- __asm__ ("facge %d0,%d1,%d2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vacges_f32 (float32_t a, float32_t b) +-{ +- float32_t result; +- __asm__ ("facge %s0,%s1,%s2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vacgtd_f64 (float64_t a, float64_t b) +-{ +- float64_t result; +- __asm__ ("facgt %d0,%d1,%d2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vacgts_f32 (float32_t a, float32_t b) +-{ +- float32_t result; +- __asm__ ("facgt %s0,%s1,%s2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline int16_t __attribute__ ((__always_inline__)) + vaddlv_s8 (int8x8_t a) + { +@@ -4732,116 +4720,6 @@ + return result; + } - /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ --/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame
" } */ -+/* { dg-output "\[^\n\r]*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame
" } */ ---- a/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/use-after-free-1.c -@@ -11,12 +11,12 @@ +-__extension__ static __inline int8_t __attribute__ ((__always_inline__)) +-vaddv_s8 (int8x8_t a) +-{ +- int8_t result; +- __asm__ ("addv %b0,%1.8b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16_t __attribute__ ((__always_inline__)) +-vaddv_s16 (int16x4_t a) +-{ +- int16_t result; +- __asm__ ("addv %h0,%1.4h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) +-vaddv_u8 (uint8x8_t a) +-{ +- uint8_t result; +- __asm__ ("addv %b0,%1.8b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) +-vaddv_u16 (uint16x4_t a) +-{ +- uint16_t result; +- __asm__ ("addv %h0,%1.4h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8_t __attribute__ ((__always_inline__)) +-vaddvq_s8 (int8x16_t a) +-{ +- int8_t result; +- __asm__ ("addv %b0,%1.16b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16_t __attribute__ ((__always_inline__)) +-vaddvq_s16 (int16x8_t a) +-{ +- int16_t result; +- __asm__ ("addv %h0,%1.8h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +-vaddvq_s32 (int32x4_t a) +-{ +- int32_t result; +- __asm__ ("addv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) +-vaddvq_u8 (uint8x16_t a) +-{ +- uint8_t result; +- __asm__ ("addv %b0,%1.16b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) +-vaddvq_u16 (uint16x8_t a) +-{ +- uint16_t result; +- __asm__ ("addv %h0,%1.8h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +-vaddvq_u32 (uint32x4_t a) +-{ +- uint32_t result; +- __asm__ ("addv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) + vbsl_f32 (uint32x2_t a, float32x2_t b, float32x2_t c) + { +@@ -5095,358 +4973,6 @@ + return result; + } - /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free on address\[^\n\r]*" } */ - /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ --/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ --/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ --/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ --/* { dg-output "previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ ---- a/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/clone-test-1.c -@@ -3,6 +3,7 @@ +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcage_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("facge %0.2s, %1.2s, %2.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcageq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("facge %0.4s, %1.4s, %2.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcageq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("facge %0.2d, %1.2d, %2.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcagt_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("facgt %0.2s, %1.2s, %2.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcagtq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("facgt %0.4s, %1.4s, %2.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcagtq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("facgt %0.2d, %1.2d, %2.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcale_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("facge %0.2s, %2.2s, %1.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcaleq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("facge %0.4s, %2.4s, %1.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcaleq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("facge %0.2d, %2.2d, %1.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcalt_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("facgt %0.2s, %2.2s, %1.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcaltq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("facgt %0.4s, %2.4s, %1.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcaltq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("facgt %0.2d, %2.2d, %1.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vceq_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("fcmeq %0.2s, %1.2s, %2.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) +-vceq_f64 (float64x1_t a, float64x1_t b) +-{ +- uint64x1_t result; +- __asm__ ("fcmeq %d0, %d1, %d2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vceqd_f64 (float64_t a, float64_t b) +-{ +- float64_t result; +- __asm__ ("fcmeq %d0,%d1,%d2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vceqq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("fcmeq %0.4s, %1.4s, %2.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vceqq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("fcmeq %0.2d, %1.2d, %2.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vceqs_f32 (float32_t a, float32_t b) +-{ +- float32_t result; +- __asm__ ("fcmeq %s0,%s1,%s2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vceqzd_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcmeq %d0,%d1,#0" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vceqzs_f32 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcmeq %s0,%s1,#0" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcge_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("fcmge %0.2s, %1.2s, %2.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) +-vcge_f64 (float64x1_t a, float64x1_t b) +-{ +- uint64x1_t result; +- __asm__ ("fcmge %d0, %d1, %d2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcgeq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("fcmge %0.4s, %1.4s, %2.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcgeq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("fcmge %0.2d, %1.2d, %2.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcgt_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("fcmgt %0.2s, %1.2s, %2.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) +-vcgt_f64 (float64x1_t a, float64x1_t b) +-{ +- uint64x1_t result; +- __asm__ ("fcmgt %d0, %d1, %d2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcgtq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("fcmgt %0.4s, %1.4s, %2.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcgtq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("fcmgt %0.2d, %1.2d, %2.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcle_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("fcmge %0.2s, %2.2s, %1.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) +-vcle_f64 (float64x1_t a, float64x1_t b) +-{ +- uint64x1_t result; +- __asm__ ("fcmge %d0, %d2, %d1" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcleq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("fcmge %0.4s, %2.4s, %1.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcleq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("fcmge %0.2d, %2.2d, %1.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) + vcls_s8 (int8x8_t a) + { +@@ -5513,50 +5039,6 @@ + return result; + } - /* { dg-do run { target { *-*-linux* } } } */ - /* { dg-require-effective-target clone } */ -+/* { dg-require-effective-target hw } */ - /* { dg-options "-D_GNU_SOURCE" } */ +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vclt_f32 (float32x2_t a, float32x2_t b) +-{ +- uint32x2_t result; +- __asm__ ("fcmgt %0.2s, %2.2s, %1.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) +-vclt_f64 (float64x1_t a, float64x1_t b) +-{ +- uint64x1_t result; +- __asm__ ("fcmgt %d0, %d2, %d1" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcltq_f32 (float32x4_t a, float32x4_t b) +-{ +- uint32x4_t result; +- __asm__ ("fcmgt %0.4s, %2.4s, %1.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcltq_f64 (float64x2_t a, float64x2_t b) +-{ +- uint64x2_t result; +- __asm__ ("fcmgt %0.2d, %2.2d, %1.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) + vclz_s8 (int8x8_t a) + { +@@ -5915,100 +5397,12 @@ - #include ---- a/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c -@@ -25,7 +25,7 @@ + /* vcvt_f32_f16 not supported */ - /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ --/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ --/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ ---- a/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c -+++ b/src/gcc/testsuite/c-c++-common/asan/null-deref-1.c -@@ -18,6 +18,6 @@ +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vcvt_f32_f64 (float64x2_t a) +-{ +- float32x2_t result; +- __asm__ ("fcvtn %0.2s,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vcvt_f32_s32 (int32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("scvtf %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vcvt_f32_u32 (uint32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("ucvtf %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vcvt_f64_f32 (float32x2_t a) +-{ +- float64x2_t result; +- __asm__ ("fcvtl %0.2d,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) +-vcvt_f64_s64 (uint64x1_t a) +-{ +- float64x1_t result; +- __asm__ ("scvtf %d0, %d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) +-vcvt_f64_u64 (uint64x1_t a) +-{ +- float64x1_t result; +- __asm__ ("ucvtf %d0, %d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + /* vcvt_high_f16_f32 not supported */ - /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */ - /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ --/* { dg-output "AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */ -+/* { dg-output "\[^\n\r]*AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */ - /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ - /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ ---- a/src/gcc/objcp/ChangeLog.linaro -+++ b/src/gcc/objcp/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ -+2013-09-10 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-08-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.08 released. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/cp/ChangeLog.linaro -+++ b/src/gcc/cp/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ -+2013-09-10 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-08-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.08 released. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/tree-ssa-loop-ivopts.c -+++ b/src/gcc/tree-ssa-loop-ivopts.c -@@ -4827,22 +4827,36 @@ - for (i = 0; i < n_iv_cands (data); i++) - { - struct iv_cand *cand = iv_cand (data, i); -- struct iv_use *closest = NULL; -+ struct iv_use *closest_before = NULL; -+ struct iv_use *closest_after = NULL; - if (cand->pos != IP_ORIGINAL) - continue; -+ - for (j = 0; j < n_iv_uses (data); j++) - { - struct iv_use *use = iv_use (data, j); - unsigned uid = gimple_uid (use->stmt); -- if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at) -- || uid > gimple_uid (cand->incremented_at)) -+ -+ if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at)) - continue; -- if (closest == NULL || uid > gimple_uid (closest->stmt)) -- closest = use; -+ -+ if (uid < gimple_uid (cand->incremented_at) -+ && (closest_before == NULL -+ || uid > gimple_uid (closest_before->stmt))) -+ closest_before = use; -+ -+ if (uid > gimple_uid (cand->incremented_at) -+ && (closest_after == NULL -+ || uid < gimple_uid (closest_after->stmt))) -+ closest_after = use; - } -- if (closest == NULL || !autoinc_possible_for_pair (data, closest, cand)) -- continue; -- cand->ainc_use = closest; -+ -+ if (closest_before != NULL -+ && autoinc_possible_for_pair (data, closest_before, cand)) -+ cand->ainc_use = closest_before; -+ else if (closest_after != NULL -+ && autoinc_possible_for_pair (data, closest_after, cand)) -+ cand->ainc_use = closest_after; - } - } - ---- a/src/gcc/rtl.def -+++ b/src/gcc/rtl.def -@@ -937,8 +937,9 @@ - relational operator. Operands should have only one alternative. - 1: A C expression giving an additional condition for recognizing - the generated pattern. -- 2: A template or C code to produce assembler output. */ --DEF_RTL_EXPR(DEFINE_COND_EXEC, "define_cond_exec", "Ess", RTX_EXTRA) -+ 2: A template or C code to produce assembler output. -+ 3: A vector of attributes to append to the resulting cond_exec insn. */ -+DEF_RTL_EXPR(DEFINE_COND_EXEC, "define_cond_exec", "EssV", RTX_EXTRA) - - /* Definition of an operand predicate. The difference between - DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE is that genrecog will ---- a/src/gcc/go/ChangeLog.linaro -+++ b/src/gcc/go/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ -+2013-09-10 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-08-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.08 released. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/opts.c -+++ b/src/gcc/opts.c -@@ -484,6 +484,7 @@ - { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 }, - { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 }, - { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 }, -+ { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP }, - { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 }, - { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 }, - -@@ -497,7 +498,7 @@ - { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 }, -- { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model, NULL, 1 }, -+ { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC }, - { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 }, - -@@ -822,6 +823,17 @@ - } - } - -+ /* Tune vectorization related parametees according to cost model. */ -+ if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP) -+ { -+ maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS, -+ 6, opts->x_param_values, opts_set->x_param_values); -+ maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS, -+ 0, opts->x_param_values, opts_set->x_param_values); -+ maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT, -+ 0, opts->x_param_values, opts_set->x_param_values); -+ } -+ - /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion - is disabled. */ - if (!opts->x_flag_tree_vectorize || !opts->x_flag_tree_loop_if_convert) -@@ -1592,7 +1604,7 @@ - if (!opts_set->x_flag_tree_vectorize) - opts->x_flag_tree_vectorize = value; - if (!opts_set->x_flag_vect_cost_model) -- opts->x_flag_vect_cost_model = value; -+ opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC; - if (!opts_set->x_flag_tree_loop_distribute_patterns) - opts->x_flag_tree_loop_distribute_patterns = value; - break; ---- a/src/gcc/ada/ChangeLog.linaro -+++ b/src/gcc/ada/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ -+2013-09-10 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-08-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.08 released. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/common/config/aarch64/aarch64-common.c -+++ b/src/gcc/common/config/aarch64/aarch64-common.c -@@ -44,6 +44,8 @@ - { - /* Enable section anchors by default at -O1 or higher. */ - { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, -+ /* Enable redundant extension instructions removal at -O2 and higher. */ -+ { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - ---- a/src/gcc/common/config/i386/i386-common.c -+++ b/src/gcc/common/config/i386/i386-common.c -@@ -729,7 +729,6 @@ - - opts->x_flag_pcc_struct_return = 2; - opts->x_flag_asynchronous_unwind_tables = 2; -- opts->x_flag_vect_cost_model = 1; - } - - /* On the x86 -fsplit-stack and -fstack-protector both use the same ---- a/src/gcc/fortran/ChangeLog.linaro -+++ b/src/gcc/fortran/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ -+2013-09-10 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-08-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.08 released. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/configure.ac -+++ b/src/gcc/configure.ac -@@ -813,7 +813,7 @@ - ) - AC_SUBST(CONFIGURE_SPECS) - --ACX_PKGVERSION([GCC]) -+ACX_PKGVERSION([Linaro GCC `cat $srcdir/LINARO-VERSION`]) - ACX_BUGURL([http://gcc.gnu.org/bugs.html]) - - # Sanity check enable_languages in case someone does not run the toplevel -@@ -4202,8 +4202,9 @@ - # ??? Once 2.11 is released, probably need to add first known working - # version to the per-target configury. - case "$cpu_type" in -- alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \ -- | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa) -+ aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \ -+ | mips | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 \ -+ | xtensa) - insn="nop" - ;; - ia64 | s390) ---- a/src/gcc/tree-vectorizer.h -+++ b/src/gcc/tree-vectorizer.h -@@ -838,6 +838,14 @@ - return (DR_MISALIGNMENT (data_ref_info) != -1); - } - -+ -+/* Return true if the vect cost model is unlimited. */ -+static inline bool -+unlimited_cost_model () -+{ -+ return flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED; -+} -+ - /* Source location */ - extern LOC vect_location; - ---- a/src/gcc/tree-vect-loop.c -+++ b/src/gcc/tree-vect-loop.c -@@ -2629,7 +2629,7 @@ - void *target_cost_data = LOOP_VINFO_TARGET_COST_DATA (loop_vinfo); - - /* Cost model disabled. */ -- if (!flag_vect_cost_model) -+ if (unlimited_cost_model ()) - { - dump_printf_loc (MSG_NOTE, vect_location, "cost model disabled."); - *ret_min_profitable_niters = 0; ---- a/src/gcc/flag-types.h -+++ b/src/gcc/flag-types.h -@@ -191,4 +191,13 @@ - FP_CONTRACT_FAST = 2 - }; - -+/* Vectorizer cost-model. */ -+enum vect_cost_model { -+ VECT_COST_MODEL_UNLIMITED = 0, -+ VECT_COST_MODEL_CHEAP = 1, -+ VECT_COST_MODEL_DYNAMIC = 2, -+ VECT_COST_MODEL_DEFAULT = 3 -+}; -+ -+ - #endif /* ! GCC_FLAG_TYPES_H */ ---- a/src/gcc/tree-vect-data-refs.c -+++ b/src/gcc/tree-vect-data-refs.c -@@ -1328,7 +1328,7 @@ - *new_slot = slot; - } - -- if (!supportable_dr_alignment && !flag_vect_cost_model) -+ if (!supportable_dr_alignment && unlimited_cost_model ()) - slot->count += VECT_MAX_COST; - } - -@@ -1438,7 +1438,7 @@ - res.peel_info.dr = NULL; - res.body_cost_vec = stmt_vector_for_cost(); - -- if (flag_vect_cost_model) -+ if (!unlimited_cost_model ()) - { - res.inside_cost = INT_MAX; - res.outside_cost = INT_MAX; -@@ -1668,7 +1668,7 @@ - vectorization factor. - We do this automtically for cost model, since we calculate cost - for every peeling option. */ -- if (!flag_vect_cost_model) -+ if (unlimited_cost_model ()) - possible_npeel_number = vf /nelements; - - /* Handle the aligned case. We may decide to align some other -@@ -1676,7 +1676,7 @@ - if (DR_MISALIGNMENT (dr) == 0) - { - npeel_tmp = 0; -- if (!flag_vect_cost_model) -+ if (unlimited_cost_model ()) - possible_npeel_number++; - } - -@@ -1926,6 +1926,30 @@ + /* vcvt_high_f32_f16 not supported */ - if (do_peeling) - { -+ unsigned max_allowed_peel -+ = PARAM_VALUE (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT); -+ if (max_allowed_peel != (unsigned)-1) -+ { -+ unsigned max_peel = npeel; -+ if (max_peel == 0) -+ { -+ gimple dr_stmt = DR_STMT (dr0); -+ stmt_vec_info vinfo = vinfo_for_stmt (dr_stmt); -+ tree vtype = STMT_VINFO_VECTYPE (vinfo); -+ max_peel = TYPE_VECTOR_SUBPARTS (vtype) - 1; -+ } -+ if (max_peel > max_allowed_peel) -+ { -+ do_peeling = false; -+ if (dump_enabled_p ()) -+ dump_printf_loc (MSG_NOTE, vect_location, -+ "Disable peeling, max peels reached: %d\n", max_peel); -+ } -+ } -+ } -+ -+ if (do_peeling) -+ { - stmt_info_for_cost *si; - void *data = LOOP_VINFO_TARGET_COST_DATA (loop_vinfo); + static float32x2_t vdup_n_f32 (float32_t); -@@ -1979,16 +2003,14 @@ - /* (2) Versioning to force alignment. */ +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vcvt_high_f32_f64 (float32x2_t a, float64x2_t b) +-{ +- float32x4_t result = vcombine_f32 (a, vdup_n_f32 (0.0f)); +- __asm__ ("fcvtn2 %0.4s,%2.2d" +- : "+w"(result) +- : "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vcvt_high_f64_f32 (float32x4_t a) +-{ +- float64x2_t result; +- __asm__ ("fcvtl2 %0.2d,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + #define vcvt_n_f32_s32(a, b) \ + __extension__ \ + ({ \ +@@ -6057,160 +5451,6 @@ + result; \ + }) - /* Try versioning if: -- 1) flag_tree_vect_loop_version is TRUE -- 2) optimize loop for speed -- 3) there is at least one unsupported misaligned data ref with an unknown -+ 1) optimize loop for speed -+ 2) there is at least one unsupported misaligned data ref with an unknown - misalignment, and -- 4) all misaligned data refs with a known misalignment are supported, and -- 5) the number of runtime alignment checks is within reason. */ -+ 3) all misaligned data refs with a known misalignment are supported, and -+ 4) the number of runtime alignment checks is within reason. */ - - do_versioning = -- flag_tree_vect_loop_version -- && optimize_loop_nest_for_speed_p (loop) -+ optimize_loop_nest_for_speed_p (loop) - && (!loop->inner); /* FORNOW */ - - if (do_versioning) ---- a/src/gcc/coretypes.h -+++ b/src/gcc/coretypes.h -@@ -62,6 +62,8 @@ - typedef union gimple_statement_d *gimple; - typedef const union gimple_statement_d *const_gimple; - typedef gimple gimple_seq; -+struct gimple_stmt_iterator_d; -+typedef struct gimple_stmt_iterator_d gimple_stmt_iterator; - union section; - typedef union section section; - struct gcc_options; ---- a/src/gcc/tree-ssa-phiopt.c -+++ b/src/gcc/tree-ssa-phiopt.c -@@ -108,6 +108,26 @@ - This opportunity can sometimes occur as a result of other - optimizations. - -+ -+ Another case caught by value replacement looks like this: -+ -+ bb0: -+ t1 = a == CONST; -+ t2 = b > c; -+ t3 = t1 & t2; -+ if (t3 != 0) goto bb1; else goto bb2; -+ bb1: -+ bb2: -+ x = PHI (CONST, a) -+ -+ Gets replaced with: -+ bb0: -+ bb2: -+ t1 = a == CONST; -+ t2 = b > c; -+ t3 = t1 & t2; -+ x = a; -+ - ABS Replacement - --------------- - -@@ -153,7 +173,7 @@ - - Adjacent Load Hoisting - ---------------------- -- -+ - This transformation replaces - - bb0: -@@ -275,7 +295,7 @@ - phi optimizations. Both share much of the infrastructure in how - to match applicable basic block patterns. DO_STORE_ELIM is true - when we want to do conditional store replacement, false otherwise. -- DO_HOIST_LOADS is true when we want to hoist adjacent loads out -+ DO_HOIST_LOADS is true when we want to hoist adjacent loads out - of diamond control flow patterns, false otherwise. */ - static unsigned int - tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads) -@@ -378,7 +398,7 @@ - continue; - } - else -- continue; -+ continue; - - e1 = EDGE_SUCC (bb1, 0); - -@@ -426,7 +446,7 @@ - - if (!candorest) - continue; -- -+ - phi = single_non_singleton_phi_for_edges (phis, e1, e2); - if (!phi) - continue; -@@ -714,6 +734,93 @@ - return false; - } - -+/* RHS is a source argument in a BIT_AND_EXPR which feeds a conditional -+ of the form SSA_NAME NE 0. -+ -+ If RHS is fed by a simple EQ_EXPR comparison of two values, see if -+ the two input values of the EQ_EXPR match arg0 and arg1. -+ -+ If so update *code and return TRUE. Otherwise return FALSE. */ -+ -+static bool -+rhs_is_fed_for_value_replacement (const_tree arg0, const_tree arg1, -+ enum tree_code *code, const_tree rhs) -+{ -+ /* Obviously if RHS is not an SSA_NAME, we can't look at the defining -+ statement. */ -+ if (TREE_CODE (rhs) == SSA_NAME) -+ { -+ gimple def1 = SSA_NAME_DEF_STMT (rhs); -+ -+ /* Verify the defining statement has an EQ_EXPR on the RHS. */ -+ if (is_gimple_assign (def1) && gimple_assign_rhs_code (def1) == EQ_EXPR) -+ { -+ /* Finally verify the source operands of the EQ_EXPR are equal -+ to arg0 and arg1. */ -+ tree op0 = gimple_assign_rhs1 (def1); -+ tree op1 = gimple_assign_rhs2 (def1); -+ if ((operand_equal_for_phi_arg_p (arg0, op0) -+ && operand_equal_for_phi_arg_p (arg1, op1)) -+ || (operand_equal_for_phi_arg_p (arg0, op1) -+ && operand_equal_for_phi_arg_p (arg1, op0))) -+ { -+ /* We will perform the optimization. */ -+ *code = gimple_assign_rhs_code (def1); -+ return true; -+ } -+ } -+ } -+ return false; -+} -+ -+/* Return TRUE if arg0/arg1 are equal to the rhs/lhs or lhs/rhs of COND. -+ -+ Also return TRUE if arg0/arg1 are equal to the source arguments of a -+ an EQ comparison feeding a BIT_AND_EXPR which feeds COND. -+ -+ Return FALSE otherwise. */ -+ -+static bool -+operand_equal_for_value_replacement (const_tree arg0, const_tree arg1, -+ enum tree_code *code, gimple cond) -+{ -+ gimple def; -+ tree lhs = gimple_cond_lhs (cond); -+ tree rhs = gimple_cond_rhs (cond); -+ -+ if ((operand_equal_for_phi_arg_p (arg0, lhs) -+ && operand_equal_for_phi_arg_p (arg1, rhs)) -+ || (operand_equal_for_phi_arg_p (arg1, lhs) -+ && operand_equal_for_phi_arg_p (arg0, rhs))) -+ return true; -+ -+ /* Now handle more complex case where we have an EQ comparison -+ which feeds a BIT_AND_EXPR which feeds COND. -+ -+ First verify that COND is of the form SSA_NAME NE 0. */ -+ if (*code != NE_EXPR || !integer_zerop (rhs) -+ || TREE_CODE (lhs) != SSA_NAME) -+ return false; -+ -+ /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR. */ -+ def = SSA_NAME_DEF_STMT (lhs); -+ if (!is_gimple_assign (def) || gimple_assign_rhs_code (def) != BIT_AND_EXPR) -+ return false; -+ -+ /* Now verify arg0/arg1 correspond to the source arguments of an -+ EQ comparison feeding the BIT_AND_EXPR. */ -+ -+ tree tmp = gimple_assign_rhs1 (def); -+ if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp)) -+ return true; -+ -+ tmp = gimple_assign_rhs2 (def); -+ if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp)) -+ return true; -+ -+ return false; -+} -+ - /* The function value_replacement does the main work of doing the value - replacement. Return non-zero if the replacement is done. Otherwise return - 0. If we remove the middle basic block, return 2. -@@ -783,10 +890,7 @@ - We now need to verify that the two arguments in the PHI node match - the two arguments to the equality comparison. */ - -- if ((operand_equal_for_phi_arg_p (arg0, gimple_cond_lhs (cond)) -- && operand_equal_for_phi_arg_p (arg1, gimple_cond_rhs (cond))) -- || (operand_equal_for_phi_arg_p (arg1, gimple_cond_lhs (cond)) -- && operand_equal_for_phi_arg_p (arg0, gimple_cond_rhs (cond)))) -+ if (operand_equal_for_value_replacement (arg0, arg1, &code, cond)) - { - edge e; - tree arg; -@@ -1807,7 +1911,7 @@ - - /* Given a "diamond" control-flow pattern where BB0 tests a condition, - BB1 and BB2 are "then" and "else" blocks dependent on this test, -- and BB3 rejoins control flow following BB1 and BB2, look for -+ and BB3 rejoins control flow following BB1 and BB2, look for - opportunities to hoist loads as follows. If BB3 contains a PHI of - two loads, one each occurring in BB1 and BB2, and the loads are - provably of adjacent fields in the same structure, then move both -@@ -1857,7 +1961,7 @@ - - arg1 = gimple_phi_arg_def (phi_stmt, 0); - arg2 = gimple_phi_arg_def (phi_stmt, 1); -- -+ - if (TREE_CODE (arg1) != SSA_NAME - || TREE_CODE (arg2) != SSA_NAME - || SSA_NAME_IS_DEFAULT_DEF (arg1) ---- a/src/gcc/tree-ssa-coalesce.c -+++ b/src/gcc/tree-ssa-coalesce.c -@@ -979,8 +979,7 @@ - continue; - - register_ssa_partition (map, arg); -- if ((SSA_NAME_VAR (arg) == SSA_NAME_VAR (res) -- && TREE_TYPE (arg) == TREE_TYPE (res)) -+ if (gimple_can_coalesce_p (arg, res) - || (e->flags & EDGE_ABNORMAL)) - { - saw_copy = true; -@@ -1021,8 +1020,7 @@ - if (gimple_assign_copy_p (stmt) - && TREE_CODE (lhs) == SSA_NAME - && TREE_CODE (rhs1) == SSA_NAME -- && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs1) -- && TREE_TYPE (lhs) == TREE_TYPE (rhs1)) -+ && gimple_can_coalesce_p (lhs, rhs1)) - { - v1 = SSA_NAME_VERSION (lhs); - v2 = SSA_NAME_VERSION (rhs1); -@@ -1073,8 +1071,7 @@ - v1 = SSA_NAME_VERSION (outputs[match]); - v2 = SSA_NAME_VERSION (input); - -- if (SSA_NAME_VAR (outputs[match]) == SSA_NAME_VAR (input) -- && TREE_TYPE (outputs[match]) == TREE_TYPE (input)) -+ if (gimple_can_coalesce_p (outputs[match], input)) - { - cost = coalesce_cost (REG_BR_PROB_BASE, - optimize_bb_for_size_p (bb)); -@@ -1108,8 +1105,7 @@ - first = var; - else - { -- gcc_assert (SSA_NAME_VAR (var) == SSA_NAME_VAR (first) -- && TREE_TYPE (var) == TREE_TYPE (first)); -+ gcc_assert (gimple_can_coalesce_p (var, first)); - v1 = SSA_NAME_VERSION (first); - v2 = SSA_NAME_VERSION (var); - bitmap_set_bit (used_in_copy, v1); -@@ -1246,8 +1242,7 @@ - var2 = ssa_name (y); - - /* Assert the coalesces have the same base variable. */ -- gcc_assert (SSA_NAME_VAR (var1) == SSA_NAME_VAR (var2) -- && TREE_TYPE (var1) == TREE_TYPE (var2)); -+ gcc_assert (gimple_can_coalesce_p (var1, var2)); - - if (debug) - fprintf (debug, "Coalesce list: "); -@@ -1377,3 +1372,38 @@ - - return map; - } -+ -+/* Given SSA_NAMEs NAME1 and NAME2, return true if they are candidates for -+ coalescing together, false otherwise. -+ -+ This must stay consistent with var_map_base_init in tree-ssa-live.c. */ -+ -+bool -+gimple_can_coalesce_p (tree name1, tree name2) -+{ -+ /* First check the SSA_NAME's associated DECL. We only want to -+ coalesce if they have the same DECL or both have no associated DECL. */ -+ if (SSA_NAME_VAR (name1) != SSA_NAME_VAR (name2)) -+ return false; -+ -+ /* Now check the types. If the types are the same, then we should -+ try to coalesce V1 and V2. */ -+ tree t1 = TREE_TYPE (name1); -+ tree t2 = TREE_TYPE (name2); -+ if (t1 == t2) -+ return true; -+ -+ /* If the types are not the same, check for a canonical type match. This -+ (for example) allows coalescing when the types are fundamentally the -+ same, but just have different names. -+ -+ Note pointer types with different address spaces may have the same -+ canonical type. Those are rejected for coalescing by the -+ types_compatible_p check. */ -+ if (TYPE_CANONICAL (t1) -+ && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2) -+ && types_compatible_p (t1, t2)) -+ return true; -+ -+ return false; -+} ---- a/src/gcc/lower-subreg.c -+++ b/src/gcc/lower-subreg.c -@@ -966,7 +966,20 @@ - rtx reg; - - reg = gen_reg_rtx (orig_mode); -+ -+#ifdef AUTO_INC_DEC -+ { -+ rtx move = emit_move_insn (reg, src); -+ if (MEM_P (src)) -+ { -+ rtx note = find_reg_note (insn, REG_INC, NULL_RTX); -+ if (note) -+ add_reg_note (move, REG_INC, XEXP (note, 0)); -+ } -+ } -+#else - emit_move_insn (reg, src); -+#endif - src = reg; - } - -@@ -1056,6 +1069,16 @@ - mdest = simplify_gen_subreg (orig_mode, dest, GET_MODE (dest), 0); - minsn = emit_move_insn (real_dest, mdest); - -+#ifdef AUTO_INC_DEC -+ if (MEM_P (real_dest) -+ && !(resolve_reg_p (real_dest) || resolve_subreg_p (real_dest))) -+ { -+ rtx note = find_reg_note (insn, REG_INC, NULL_RTX); -+ if (note) -+ add_reg_note (minsn, REG_INC, XEXP (note, 0)); -+ } -+#endif -+ - smove = single_set (minsn); - gcc_assert (smove != NULL_RTX); - ---- a/src/gcc/gimple-fold.c -+++ b/src/gcc/gimple-fold.c -@@ -1151,6 +1151,8 @@ - gimplify_and_update_call_from_tree (gsi, result); - changed = true; - } -+ else if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD) -+ changed |= targetm.gimple_fold_builtin (gsi); - } - - return changed; ---- a/src/gcc/tree-ssa-live.c -+++ b/src/gcc/tree-ssa-live.c -@@ -88,8 +88,12 @@ - as it restricts the sets we compute conflicts for. - Using TREE_TYPE to generate sets is the easies as - type equivalency also holds for SSA names with the same -- underlying decl. */ -- m->base.from = TREE_TYPE (var); -+ underlying decl. -+ -+ Check gimple_can_coalesce_p when changing this code. */ -+ m->base.from = (TYPE_CANONICAL (TREE_TYPE (var)) -+ ? TYPE_CANONICAL (TREE_TYPE (var)) -+ : TREE_TYPE (var)); - /* If base variable hasn't been seen, set it up. */ - slot = (struct tree_int_map **) htab_find_slot (tree_to_index, - m, INSERT); ---- a/src/gcc/lto/ChangeLog.linaro -+++ b/src/gcc/lto/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ -+2013-09-10 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-08-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.08 released. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/po/ChangeLog.linaro -+++ b/src/gcc/po/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ -+2013-10-15 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.10 released. -+ -+2013-09-10 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.09 released. -+ -+2013-08-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.08 released. -+ -+2013-07-19 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.07-1 released. -+ -+2013-07-05 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.07 released. -+ -+2013-06-11 Rob Savoye -+ -+ GCC Linaro gcc-linaro-4.8-2013.06 released. -+ -+2013-05-14 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.05 released. -+ -+2013-04-09 Matthew Gretton-Dann -+ -+ GCC Linaro 4.8-2013.04 released. ---- a/src/gcc/common.opt -+++ b/src/gcc/common.opt -@@ -2233,13 +2233,33 @@ - Common Report Var(flag_tree_slp_vectorize) Init(2) Optimization - Enable basic block vectorization (SLP) on trees - -+fvect-cost-model= -+Common Joined RejectNegative Enum(vect_cost_model) Var(flag_vect_cost_model) Init(VECT_COST_MODEL_DEFAULT) -+Specifies the cost model for vectorization -+ -+Enum -+Name(vect_cost_model) Type(enum vect_cost_model) UnknownError(unknown vectorizer cost model %qs) -+ -+EnumValue -+Enum(vect_cost_model) String(unlimited) Value(VECT_COST_MODEL_UNLIMITED) -+ -+EnumValue -+Enum(vect_cost_model) String(dynamic) Value(VECT_COST_MODEL_DYNAMIC) -+ -+EnumValue -+Enum(vect_cost_model) String(cheap) Value(VECT_COST_MODEL_CHEAP) -+ - fvect-cost-model --Common Report Var(flag_vect_cost_model) Optimization --Enable use of cost model in vectorization -+Common RejectNegative Alias(fvect-cost-model=,dynamic) -+Enables the dynamic vectorizer cost model. Preserved for backward compatibility. - -+fno-vect-cost-model -+Common RejectNegative Alias(fvect-cost-model=,unlimited) -+Enables the unlimited vectorizer cost model. Preserved for backward compatibility. -+ - ftree-vect-loop-version --Common Report Var(flag_tree_vect_loop_version) Init(1) Optimization --Enable loop versioning when doing loop vectorization on trees -+Common Ignore -+Does nothing. Preserved for backward compatibility. - - ftree-scev-cprop - Common Report Var(flag_tree_scev_cprop) Init(1) Optimization ---- a/src/gcc/combine.c -+++ b/src/gcc/combine.c -@@ -11996,6 +11996,13 @@ - } - } - -+ /* We may have changed the comparison operands. Re-canonicalize. */ -+ if (swap_commutative_operands_p (op0, op1)) -+ { -+ tem = op0, op0 = op1, op1 = tem; -+ code = swap_condition (code); -+ } -+ - /* If this machine only supports a subset of valid comparisons, see if we - can convert an unsupported one into a supported one. */ - target_canonicalize_comparison (&code, &op0, &op1, 0); ---- a/src/gcc/config.gcc -+++ b/src/gcc/config.gcc -@@ -325,10 +325,11 @@ - ;; - arm*-*-*) - cpu_type=arm -- extra_headers="mmintrin.h arm_neon.h" -+ extra_headers="mmintrin.h arm_neon.h arm_acle.h" - target_type_format_char='%' - c_target_objs="arm-c.o" - cxx_target_objs="arm-c.o" -+ need_64bit_hwint=yes - extra_options="${extra_options} arm/arm-tables.opt" - ;; - avr-*-*) -@@ -877,7 +878,7 @@ - tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" - ;; - esac -- tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi" -+ tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi arm/t-mlibs" - tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h" - # Define multilib configuration for arm-linux-androideabi. - case ${target} in -@@ -885,10 +886,6 @@ - tmake_file="$tmake_file arm/t-linux-androideabi" - ;; - esac -- # The BPABI long long divmod functions return a 128-bit value in -- # registers r0-r3. Correctly modeling that requires the use of -- # TImode. -- need_64bit_hwint=yes - # The EABI requires the use of __cxa_atexit. - default_use_cxa_atexit=yes - with_tls=${with_tls:-gnu} -@@ -897,10 +894,6 @@ - tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h glibc-stdint.h" - tmake_file="arm/t-arm arm/t-arm-elf arm/t-bpabi" - tm_file="$tm_file arm/bpabi.h arm/uclinux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h" -- # The BPABI long long divmod functions return a 128-bit value in -- # registers r0-r3. Correctly modeling that requires the use of -- # TImode. -- need_64bit_hwint=yes - # The EABI requires the use of __cxa_atexit. - default_use_cxa_atexit=yes - ;; -@@ -909,10 +902,6 @@ - arm*eb-*-eabi*) - tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" - esac -- # The BPABI long long divmod functions return a 128-bit value in -- # registers r0-r3. Correctly modeling that requires the use of -- # TImode. -- need_64bit_hwint=yes - default_use_cxa_atexit=yes - tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/bpabi.h" - tmake_file="arm/t-arm arm/t-arm-elf" -@@ -3310,6 +3299,43 @@ - if test "x$with_arch" != x && test "x$with_cpu" != x; then - echo "Warning: --with-arch overrides --with-cpu=$with_cpu" 1>&2 - fi -+ -+ # Add extra multilibs -+ if test "x$with_multilib_list" != x; then -+ arm_multilibs=`echo $with_multilib_list | sed -e 's/,/ /g'` -+ for arm_multilib in ${arm_multilibs}; do -+ case ${arm_multilib} in -+ aprofile) -+ # Note that arm/t-aprofile is a -+ # stand-alone make file fragment to be -+ # used only with itself. We do not -+ # specifically use the -+ # TM_MULTILIB_OPTION framework because -+ # this shorthand is more -+ # pragmatic. Additionally it is only -+ # designed to work without any -+ # with-cpu, with-arch with-mode -+ # with-fpu or with-float options. -+ if test "x$with_arch" != x \ -+ || test "x$with_cpu" != x \ -+ || test "x$with_float" != x \ -+ || test "x$with_fpu" != x \ -+ || test "x$with_mode" != x ; then -+ echo "Error: You cannot use any of --with-arch/cpu/fpu/float/mode with --with-multilib-list=aprofile" 1>&2 -+ exit 1 -+ fi -+ tmake_file="${tmake_file} arm/t-aprofile" -+ break -+ ;; -+ default) -+ ;; -+ *) -+ echo "Error: --with-multilib-list=${with_multilib_list} not supported." 1>&2 -+ exit 1 -+ ;; -+ esac -+ done -+ fi - ;; - - fr*-*-*linux*) ---- a/src/gcc/Makefile.in -+++ b/src/gcc/Makefile.in -@@ -4282,7 +4282,8 @@ - gcov.texi trouble.texi bugreport.texi service.texi \ - contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi \ - fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi \ -- implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi -+ implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi \ -+ arm-acle-intrinsics.texi - - # we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with - # the generated tm.texi; the latter might have a more recent timestamp, ---- a/src/gcc/gimple.h -+++ b/src/gcc/gimple.h -@@ -130,7 +130,7 @@ - - /* Iterator object for GIMPLE statement sequences. */ - --typedef struct -+struct gimple_stmt_iterator_d - { - /* Sequence node holding the current statement. */ - gimple_seq_node ptr; -@@ -141,9 +141,8 @@ - block/sequence is removed. */ - gimple_seq *seq; - basic_block bb; --} gimple_stmt_iterator; -+}; +-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +-vcvt_s32_f32 (float32x2_t a) +-{ +- int32x2_t result; +- __asm__ ("fcvtzs %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcvt_u32_f32 (float32x2_t a) +-{ +- uint32x2_t result; +- __asm__ ("fcvtzu %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +-vcvta_s32_f32 (float32x2_t a) +-{ +- int32x2_t result; +- __asm__ ("fcvtas %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcvta_u32_f32 (float32x2_t a) +-{ +- uint32x2_t result; +- __asm__ ("fcvtau %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtad_s64_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcvtas %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtad_u64_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcvtau %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +-vcvtaq_s32_f32 (float32x4_t a) +-{ +- int32x4_t result; +- __asm__ ("fcvtas %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) +-vcvtaq_s64_f64 (float64x2_t a) +-{ +- int64x2_t result; +- __asm__ ("fcvtas %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcvtaq_u32_f32 (float32x4_t a) +-{ +- uint32x4_t result; +- __asm__ ("fcvtau %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcvtaq_u64_f64 (float64x2_t a) +-{ +- uint64x2_t result; +- __asm__ ("fcvtau %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvtas_s64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtas %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvtas_u64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtau %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int64_t __attribute__ ((__always_inline__)) +-vcvtd_f64_s64 (int64_t a) +-{ +- int64_t result; +- __asm__ ("scvtf %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) +-vcvtd_f64_u64 (uint64_t a) +-{ +- uint64_t result; +- __asm__ ("ucvtf %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + #define vcvtd_n_f64_s64(a, b) \ + __extension__ \ + ({ \ +@@ -6259,402 +5499,6 @@ + result; \ + }) +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtd_s64_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcvtzs %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - - /* Data structure definitions for GIMPLE tuples. NOTE: word markers - are for 64 bit hosts. */ - -@@ -1033,6 +1032,9 @@ - extern bool useless_type_conversion_p (tree, tree); - extern bool types_compatible_p (tree, tree); - -+/* In tree-ssa-coalesce.c */ -+extern bool gimple_can_coalesce_p (tree, tree); -+ - /* Return the first node in GIMPLE sequence S. */ - - static inline gimple_seq_node ---- a/src/gcc/config/i386/linux-common.h -+++ b/src/gcc/config/i386/linux-common.h -@@ -40,7 +40,7 @@ - #undef LIB_SPEC - #define LIB_SPEC \ - LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \ -- GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC) -+ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC " " ANDROID_LIB_SPEC) - - #undef STARTFILE_SPEC - #define STARTFILE_SPEC \ ---- a/src/gcc/config/i386/i386.c -+++ b/src/gcc/config/i386/i386.c -@@ -42262,20 +42262,17 @@ - unsigned *cost = (unsigned *) data; - unsigned retval = 0; - -- if (flag_vect_cost_model) -- { -- tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; -- int stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign); -+ tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; -+ int stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign); - -- /* Statements in an inner loop relative to the loop being -- vectorized are weighted more heavily. The value here is -- arbitrary and could potentially be improved with analysis. */ -- if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) -- count *= 50; /* FIXME. */ -+ /* Statements in an inner loop relative to the loop being -+ vectorized are weighted more heavily. The value here is -+ arbitrary and could potentially be improved with analysis. */ -+ if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) -+ count *= 50; /* FIXME. */ - -- retval = (unsigned) (count * stmt_cost); -- cost[where] += retval; -- } -+ retval = (unsigned) (count * stmt_cost); -+ cost[where] += retval; - - return retval; - } ---- a/src/gcc/config/gnu-user.h -+++ b/src/gcc/config/gnu-user.h -@@ -73,10 +73,14 @@ - #undef CPLUSPLUS_CPP_SPEC - #define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" - -+#define GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC \ -+ "%{shared:-lc} \ -+ %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}" -+ - #define GNU_USER_TARGET_LIB_SPEC \ -- "%{pthread:-lpthread} \ -- %{shared:-lc} \ -- %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}" -+ "%{pthread:-lpthread} " \ -+ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC -+ - #undef LIB_SPEC - #define LIB_SPEC GNU_USER_TARGET_LIB_SPEC - ---- a/src/gcc/config/aarch64/aarch64-simd.md -+++ b/src/gcc/config/aarch64/aarch64-simd.md -@@ -21,7 +21,7 @@ - - ; Main data types used by the insntructions - --(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,SF,HI,QI" -+(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,TI,DI,DF,SI,SF,HI,QI" - (const_string "unknown")) - - -@@ -44,6 +44,7 @@ - ; simd_dup duplicate element. - ; simd_dupgp duplicate general purpose register. - ; simd_ext bitwise extract from pair. -+; simd_fabd floating point absolute difference. - ; simd_fadd floating point add/sub. - ; simd_fcmp floating point compare. - ; simd_fcvti floating point convert to integer. -@@ -58,9 +59,9 @@ - ; simd_fmul floating point multiply. - ; simd_fmul_elt floating point multiply (by element). - ; simd_fnegabs floating point neg/abs. --; simd_frcpe floating point reciprocal estimate. --; simd_frcps floating point reciprocal step. --; simd_frecx floating point reciprocal exponent. -+; simd_frecpe floating point reciprocal estimate. -+; simd_frecps floating point reciprocal step. -+; simd_frecpx floating point reciprocal exponent. - ; simd_frint floating point round to integer. - ; simd_fsqrt floating point square root. - ; simd_icvtf integer convert to floating point. -@@ -147,6 +148,7 @@ - simd_dup,\ - simd_dupgp,\ - simd_ext,\ -+ simd_fabd,\ - simd_fadd,\ - simd_fcmp,\ - simd_fcvti,\ -@@ -161,9 +163,9 @@ - simd_fmul,\ - simd_fmul_elt,\ - simd_fnegabs,\ -- simd_frcpe,\ -- simd_frcps,\ -- simd_frecx,\ -+ simd_frecpe,\ -+ simd_frecps,\ -+ simd_frecpx,\ - simd_frint,\ - simd_fsqrt,\ - simd_icvtf,\ -@@ -193,6 +195,7 @@ - simd_move,\ - simd_move_imm,\ - simd_mul,\ -+ simd_mul_d_long,\ - simd_mul_elt,\ - simd_mull,\ - simd_mull_elt,\ -@@ -233,6 +236,12 @@ - simd_trn,\ - simd_uzp,\ - simd_zip,\ -+ simd_crypto_aes,\ -+ simd_crypto_sha1_xor,\ -+ simd_crypto_sha1_fast,\ -+ simd_crypto_sha1_slow,\ -+ simd_crypto_sha256_fast,\ -+ simd_crypto_sha256_slow,\ - none" - (const_string "none")) - -@@ -303,8 +312,8 @@ - (eq_attr "simd_type" "simd_store3,simd_store4") (const_string "neon_vst1_3_4_regs") - (eq_attr "simd_type" "simd_store1s,simd_store2s") (const_string "neon_vst1_vst2_lane") - (eq_attr "simd_type" "simd_store3s,simd_store4s") (const_string "neon_vst3_vst4_lane") -- (and (eq_attr "simd_type" "simd_frcpe,simd_frcps") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vrecps_vrsqrts_ddd") -- (and (eq_attr "simd_type" "simd_frcpe,simd_frcps") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vrecps_vrsqrts_qqq") -+ (and (eq_attr "simd_type" "simd_frecpe,simd_frecps") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vrecps_vrsqrts_ddd") -+ (and (eq_attr "simd_type" "simd_frecpe,simd_frecps") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vrecps_vrsqrts_qqq") - (eq_attr "simd_type" "none") (const_string "none") - ] - (const_string "unknown"))) -@@ -355,18 +364,6 @@ - (set_attr "simd_mode" "")] - ) - --(define_insn "aarch64_dup_lane" -- [(set (match_operand:SDQ_I 0 "register_operand" "=w") -- (vec_select: -- (match_operand: 1 "register_operand" "w") -- (parallel [(match_operand:SI 2 "immediate_operand" "i")]) -- ))] -- "TARGET_SIMD" -- "dup\\t%0, %1.[%2]" -- [(set_attr "simd_type" "simd_dup") -- (set_attr "simd_mode" "")] --) +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtd_u64_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcvtzu %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - - (define_insn "aarch64_simd_dup" - [(set (match_operand:VDQF 0 "register_operand" "=w") - (vec_duplicate:VDQF (match_operand: 1 "register_operand" "w")))] -@@ -394,7 +391,7 @@ - case 4: return "ins\t%0.d[0], %1"; - case 5: return "mov\t%0, %1"; - case 6: -- return aarch64_output_simd_mov_immediate (&operands[1], -+ return aarch64_output_simd_mov_immediate (operands[1], - mode, 64); - default: gcc_unreachable (); - } -@@ -414,16 +411,20 @@ - { - switch (which_alternative) - { -- case 0: return "ld1\t{%0.}, %1"; -- case 1: return "st1\t{%1.}, %0"; -- case 2: return "orr\t%0., %1., %1."; -- case 3: return "umov\t%0, %1.d[0]\;umov\t%H0, %1.d[1]"; -- case 4: return "ins\t%0.d[0], %1\;ins\t%0.d[1], %H1"; -- case 5: return "#"; -+ case 0: -+ return "ld1\t{%0.}, %1"; -+ case 1: -+ return "st1\t{%1.}, %0"; -+ case 2: -+ return "orr\t%0., %1., %1."; -+ case 3: -+ case 4: -+ case 5: -+ return "#"; - case 6: -- return aarch64_output_simd_mov_immediate (&operands[1], -- mode, 128); -- default: gcc_unreachable (); -+ return aarch64_output_simd_mov_immediate (operands[1], mode, 128); -+ default: -+ gcc_unreachable (); - } - } - [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm") -@@ -452,6 +453,77 @@ - aarch64_simd_disambiguate_copy (operands, dest, src, 2); - }) - -+(define_split -+ [(set (match_operand:VQ 0 "register_operand" "") -+ (match_operand:VQ 1 "register_operand" ""))] -+ "TARGET_SIMD && reload_completed -+ && ((FP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1]))) -+ || (GP_REGNUM_P (REGNO (operands[0])) && FP_REGNUM_P (REGNO (operands[1]))))" -+ [(const_int 0)] -+{ -+ aarch64_split_simd_move (operands[0], operands[1]); -+ DONE; -+}) -+ -+(define_expand "aarch64_split_simd_mov" -+ [(set (match_operand:VQ 0) -+ (match_operand:VQ 1))] -+ "TARGET_SIMD" -+ { -+ rtx dst = operands[0]; -+ rtx src = operands[1]; -+ -+ if (GP_REGNUM_P (REGNO (src))) -+ { -+ rtx src_low_part = gen_lowpart (mode, src); -+ rtx src_high_part = gen_highpart (mode, src); -+ -+ emit_insn -+ (gen_move_lo_quad_ (dst, src_low_part)); -+ emit_insn -+ (gen_move_hi_quad_ (dst, src_high_part)); -+ } -+ -+ else -+ { -+ rtx dst_low_part = gen_lowpart (mode, dst); -+ rtx dst_high_part = gen_highpart (mode, dst); -+ rtx lo = aarch64_simd_vect_par_cnst_half (mode, false); -+ rtx hi = aarch64_simd_vect_par_cnst_half (mode, true); -+ -+ emit_insn -+ (gen_aarch64_simd_mov_from_low (dst_low_part, src, lo)); -+ emit_insn -+ (gen_aarch64_simd_mov_from_high (dst_high_part, src, hi)); -+ } -+ DONE; -+ } -+) -+ -+(define_insn "aarch64_simd_mov_from_low" -+ [(set (match_operand: 0 "register_operand" "=r") -+ (vec_select: -+ (match_operand:VQ 1 "register_operand" "w") -+ (match_operand:VQ 2 "vect_par_cnst_lo_half" "")))] -+ "TARGET_SIMD && reload_completed" -+ "umov\t%0, %1.d[0]" -+ [(set_attr "simd_type" "simd_movgp") -+ (set_attr "simd_mode" "") -+ (set_attr "length" "4") -+ ]) -+ -+(define_insn "aarch64_simd_mov_from_high" -+ [(set (match_operand: 0 "register_operand" "=r") -+ (vec_select: -+ (match_operand:VQ 1 "register_operand" "w") -+ (match_operand:VQ 2 "vect_par_cnst_hi_half" "")))] -+ "TARGET_SIMD && reload_completed" -+ "umov\t%0, %1.d[1]" -+ [(set_attr "simd_type" "simd_movgp") -+ (set_attr "simd_mode" "") -+ (set_attr "length" "4") -+ ]) -+ - (define_insn "orn3" - [(set (match_operand:VDQ 0 "register_operand" "=w") - (ior:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w")) -@@ -503,8 +575,8 @@ - ) - - (define_insn "neg2" -- [(set (match_operand:VDQM 0 "register_operand" "=w") -- (neg:VDQM (match_operand:VDQM 1 "register_operand" "w")))] -+ [(set (match_operand:VDQ 0 "register_operand" "=w") -+ (neg:VDQ (match_operand:VDQ 1 "register_operand" "w")))] - "TARGET_SIMD" - "neg\t%0., %1." - [(set_attr "simd_type" "simd_negabs") -@@ -520,6 +592,51 @@ - (set_attr "simd_mode" "")] - ) - -+(define_insn "abd_3" -+ [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") -+ (abs:VDQ_BHSI (minus:VDQ_BHSI -+ (match_operand:VDQ_BHSI 1 "register_operand" "w") -+ (match_operand:VDQ_BHSI 2 "register_operand" "w"))))] -+ "TARGET_SIMD" -+ "sabd\t%0., %1., %2." -+ [(set_attr "simd_type" "simd_abd") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "aba_3" -+ [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") -+ (plus:VDQ_BHSI (abs:VDQ_BHSI (minus:VDQ_BHSI -+ (match_operand:VDQ_BHSI 1 "register_operand" "w") -+ (match_operand:VDQ_BHSI 2 "register_operand" "w"))) -+ (match_operand:VDQ_BHSI 3 "register_operand" "0")))] -+ "TARGET_SIMD" -+ "saba\t%0., %1., %2." -+ [(set_attr "simd_type" "simd_abd") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "fabd_3" -+ [(set (match_operand:VDQF 0 "register_operand" "=w") -+ (abs:VDQF (minus:VDQF -+ (match_operand:VDQF 1 "register_operand" "w") -+ (match_operand:VDQF 2 "register_operand" "w"))))] -+ "TARGET_SIMD" -+ "fabd\t%0., %1., %2." -+ [(set_attr "simd_type" "simd_fabd") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "*fabd_scalar3" -+ [(set (match_operand:GPF 0 "register_operand" "=w") -+ (abs:GPF (minus:GPF -+ (match_operand:GPF 1 "register_operand" "w") -+ (match_operand:GPF 2 "register_operand" "w"))))] -+ "TARGET_SIMD" -+ "fabd\t%0, %1, %2" -+ [(set_attr "simd_type" "simd_fabd") -+ (set_attr "mode" "")] -+) -+ - (define_insn "and3" - [(set (match_operand:VDQ 0 "register_operand" "=w") - (and:VDQ (match_operand:VDQ 1 "register_operand" "w") -@@ -904,12 +1021,12 @@ - ) - - ;; Max/Min operations. --(define_insn "3" -+(define_insn "3" - [(set (match_operand:VQ_S 0 "register_operand" "=w") - (MAXMIN:VQ_S (match_operand:VQ_S 1 "register_operand" "w") - (match_operand:VQ_S 2 "register_operand" "w")))] - "TARGET_SIMD" -- "\t%0., %1., %2." -+ "\t%0., %1., %2." - [(set_attr "simd_type" "simd_minmax") - (set_attr "simd_mode" "")] - ) -@@ -917,29 +1034,39 @@ - ;; Move into low-half clearing high half to 0. - - (define_insn "move_lo_quad_" -- [(set (match_operand:VQ 0 "register_operand" "=w") -+ [(set (match_operand:VQ 0 "register_operand" "=w,w,w") - (vec_concat:VQ -- (match_operand: 1 "register_operand" "w") -+ (match_operand: 1 "register_operand" "w,r,r") - (vec_duplicate: (const_int 0))))] - "TARGET_SIMD" -- "mov\\t%d0, %d1"; -- [(set_attr "simd_type" "simd_dup") -- (set_attr "simd_mode" "")] -+ "@ -+ dup\\t%d0, %1.d[0] -+ fmov\\t%d0, %1 -+ dup\\t%d0, %1" -+ [(set_attr "v8type" "*,fmov,*") -+ (set_attr "simd_type" "simd_dup,*,simd_dup") -+ (set_attr "simd_mode" "") -+ (set_attr "simd" "yes,*,yes") -+ (set_attr "fp" "*,yes,*") -+ (set_attr "length" "4")] - ) - - ;; Move into high-half. - - (define_insn "aarch64_simd_move_hi_quad_" -- [(set (match_operand:VQ 0 "register_operand" "+w") -+ [(set (match_operand:VQ 0 "register_operand" "+w,w") - (vec_concat:VQ - (vec_select: - (match_dup 0) - (match_operand:VQ 2 "vect_par_cnst_lo_half" "")) -- (match_operand: 1 "register_operand" "w")))] -+ (match_operand: 1 "register_operand" "w,r")))] - "TARGET_SIMD" -- "ins\\t%0.d[1], %1.d[0]"; -- [(set_attr "simd_type" "simd_ins") -- (set_attr "simd_mode" "")] -+ "@ -+ ins\\t%0.d[1], %1.d[0] -+ ins\\t%0.d[1], %1" -+ [(set_attr "simd_type" "simd_ins,simd_ins") -+ (set_attr "simd_mode" "") -+ (set_attr "length" "4")] - ) - - (define_expand "move_hi_quad_" -@@ -1045,6 +1172,104 @@ - - ;; Widening arithmetic. - -+(define_insn "*aarch64_mlal_lo" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (plus: -+ (mult: -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 2 "register_operand" "w") -+ (match_operand:VQW 3 "vect_par_cnst_lo_half" ""))) -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 4 "register_operand" "w") -+ (match_dup 3)))) -+ (match_operand: 1 "register_operand" "0")))] -+ "TARGET_SIMD" -+ "mlal\t%0., %2., %4." -+ [(set_attr "simd_type" "simd_mlal") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "*aarch64_mlal_hi" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (plus: -+ (mult: -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 2 "register_operand" "w") -+ (match_operand:VQW 3 "vect_par_cnst_hi_half" ""))) -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 4 "register_operand" "w") -+ (match_dup 3)))) -+ (match_operand: 1 "register_operand" "0")))] -+ "TARGET_SIMD" -+ "mlal2\t%0., %2., %4." -+ [(set_attr "simd_type" "simd_mlal") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "*aarch64_mlsl_lo" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (minus: -+ (match_operand: 1 "register_operand" "0") -+ (mult: -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 2 "register_operand" "w") -+ (match_operand:VQW 3 "vect_par_cnst_lo_half" ""))) -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 4 "register_operand" "w") -+ (match_dup 3))))))] -+ "TARGET_SIMD" -+ "mlsl\t%0., %2., %4." -+ [(set_attr "simd_type" "simd_mlal") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "*aarch64_mlsl_hi" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (minus: -+ (match_operand: 1 "register_operand" "0") -+ (mult: -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 2 "register_operand" "w") -+ (match_operand:VQW 3 "vect_par_cnst_hi_half" ""))) -+ (ANY_EXTEND: (vec_select: -+ (match_operand:VQW 4 "register_operand" "w") -+ (match_dup 3))))))] -+ "TARGET_SIMD" -+ "mlsl2\t%0., %2., %4." -+ [(set_attr "simd_type" "simd_mlal") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "*aarch64_mlal" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (plus: -+ (mult: -+ (ANY_EXTEND: -+ (match_operand:VDW 1 "register_operand" "w")) -+ (ANY_EXTEND: -+ (match_operand:VDW 2 "register_operand" "w"))) -+ (match_operand: 3 "register_operand" "0")))] -+ "TARGET_SIMD" -+ "mlal\t%0., %1., %2." -+ [(set_attr "simd_type" "simd_mlal") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "*aarch64_mlsl" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (minus: -+ (match_operand: 1 "register_operand" "0") -+ (mult: -+ (ANY_EXTEND: -+ (match_operand:VDW 2 "register_operand" "w")) -+ (ANY_EXTEND: -+ (match_operand:VDW 3 "register_operand" "w")))))] -+ "TARGET_SIMD" -+ "mlsl\t%0., %2., %3." -+ [(set_attr "simd_type" "simd_mlal") -+ (set_attr "simd_mode" "")] -+) -+ - (define_insn "aarch64_simd_vec_mult_lo_" - [(set (match_operand: 0 "register_operand" "=w") - (mult: (ANY_EXTEND: (vec_select: -@@ -1196,7 +1421,9 @@ - (set_attr "simd_mode" "")] - ) - --(define_insn "aarch64_frint" -+;; Vector versions of the floating-point frint patterns. -+;; Expands to btrunc, ceil, floor, nearbyint, rint, round. -+(define_insn "2" - [(set (match_operand:VDQF 0 "register_operand" "=w") - (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")] - FRINT))] -@@ -1206,16 +1433,9 @@ - (set_attr "simd_mode" "")] - ) - --;; Vector versions of the floating-point frint patterns. --;; Expands to btrunc, ceil, floor, nearbyint, rint, round. --(define_expand "2" -- [(set (match_operand:VDQF 0 "register_operand") -- (unspec:VDQF [(match_operand:VDQF 1 "register_operand")] -- FRINT))] -- "TARGET_SIMD" -- {}) +-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +-vcvtm_s32_f32 (float32x2_t a) +-{ +- int32x2_t result; +- __asm__ ("fcvtms %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "aarch64_fcvt" -+;; Vector versions of the fcvt standard patterns. -+;; Expands to lbtrunc, lround, lceil, lfloor -+(define_insn "l2" - [(set (match_operand: 0 "register_operand" "=w") - (FIXUORS: (unspec: - [(match_operand:VDQF 1 "register_operand" "w")] -@@ -1226,16 +1446,141 @@ - (set_attr "simd_mode" "")] - ) - --;; Vector versions of the fcvt standard patterns. --;; Expands to lbtrunc, lround, lceil, lfloor --(define_expand "l2" -+(define_expand "2" - [(set (match_operand: 0 "register_operand") - (FIXUORS: (unspec: - [(match_operand:VDQF 1 "register_operand")] -- FCVT)))] -+ UNSPEC_FRINTZ)))] - "TARGET_SIMD" - {}) - -+(define_expand "2" -+ [(set (match_operand: 0 "register_operand") -+ (FIXUORS: (unspec: -+ [(match_operand:VDQF 1 "register_operand")] -+ UNSPEC_FRINTZ)))] -+ "TARGET_SIMD" -+ {}) -+ -+(define_expand "ftrunc2" -+ [(set (match_operand:VDQF 0 "register_operand") -+ (unspec:VDQF [(match_operand:VDQF 1 "register_operand")] -+ UNSPEC_FRINTZ))] -+ "TARGET_SIMD" -+ {}) -+ -+(define_insn "2" -+ [(set (match_operand:VDQF 0 "register_operand" "=w") -+ (FLOATUORS:VDQF -+ (match_operand: 1 "register_operand" "w")))] -+ "TARGET_SIMD" -+ "cvtf\\t%0., %1." -+ [(set_attr "simd_type" "simd_icvtf") -+ (set_attr "simd_mode" "")] -+) -+ -+;; Conversions between vectors of floats and doubles. -+;; Contains a mix of patterns to match standard pattern names -+;; and those for intrinsics. -+ -+;; Float widening operations. -+ -+(define_insn "vec_unpacks_lo_v4sf" -+ [(set (match_operand:V2DF 0 "register_operand" "=w") -+ (float_extend:V2DF -+ (vec_select:V2SF -+ (match_operand:V4SF 1 "register_operand" "w") -+ (parallel [(const_int 0) (const_int 1)]) -+ )))] -+ "TARGET_SIMD" -+ "fcvtl\\t%0.2d, %1.2s" -+ [(set_attr "simd_type" "simd_fcvtl") -+ (set_attr "simd_mode" "V2DF")] -+) -+ -+(define_insn "aarch64_float_extend_lo_v2df" -+ [(set (match_operand:V2DF 0 "register_operand" "=w") -+ (float_extend:V2DF -+ (match_operand:V2SF 1 "register_operand" "w")))] -+ "TARGET_SIMD" -+ "fcvtl\\t%0.2d, %1.2s" -+ [(set_attr "simd_type" "simd_fcvtl") -+ (set_attr "simd_mode" "V2DF")] -+) -+ -+(define_insn "vec_unpacks_hi_v4sf" -+ [(set (match_operand:V2DF 0 "register_operand" "=w") -+ (float_extend:V2DF -+ (vec_select:V2SF -+ (match_operand:V4SF 1 "register_operand" "w") -+ (parallel [(const_int 2) (const_int 3)]) -+ )))] -+ "TARGET_SIMD" -+ "fcvtl2\\t%0.2d, %1.4s" -+ [(set_attr "simd_type" "simd_fcvtl") -+ (set_attr "simd_mode" "V2DF")] -+) -+ -+;; Float narrowing operations. -+ -+(define_insn "aarch64_float_truncate_lo_v2sf" -+ [(set (match_operand:V2SF 0 "register_operand" "=w") -+ (float_truncate:V2SF -+ (match_operand:V2DF 1 "register_operand" "w")))] -+ "TARGET_SIMD" -+ "fcvtn\\t%0.2s, %1.2d" -+ [(set_attr "simd_type" "simd_fcvtl") -+ (set_attr "simd_mode" "V2SF")] -+) -+ -+(define_insn "aarch64_float_truncate_hi_v4sf" -+ [(set (match_operand:V4SF 0 "register_operand" "=w") -+ (vec_concat:V4SF -+ (match_operand:V2SF 1 "register_operand" "0") -+ (float_truncate:V2SF -+ (match_operand:V2DF 2 "register_operand" "w"))))] -+ "TARGET_SIMD" -+ "fcvtn2\\t%0.4s, %2.2d" -+ [(set_attr "simd_type" "simd_fcvtl") -+ (set_attr "simd_mode" "V4SF")] -+) -+ -+(define_expand "vec_pack_trunc_v2df" -+ [(set (match_operand:V4SF 0 "register_operand") -+ (vec_concat:V4SF -+ (float_truncate:V2SF -+ (match_operand:V2DF 1 "register_operand")) -+ (float_truncate:V2SF -+ (match_operand:V2DF 2 "register_operand")) -+ ))] -+ "TARGET_SIMD" -+ { -+ rtx tmp = gen_reg_rtx (V2SFmode); -+ emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[1])); -+ emit_insn (gen_aarch64_float_truncate_hi_v4sf (operands[0], -+ tmp, operands[2])); -+ DONE; -+ } -+) -+ -+(define_expand "vec_pack_trunc_df" -+ [(set (match_operand:V2SF 0 "register_operand") -+ (vec_concat:V2SF -+ (float_truncate:SF -+ (match_operand:DF 1 "register_operand")) -+ (float_truncate:SF -+ (match_operand:DF 2 "register_operand")) -+ ))] -+ "TARGET_SIMD" -+ { -+ rtx tmp = gen_reg_rtx (V2SFmode); -+ emit_insn (gen_move_lo_quad_v2df (tmp, operands[1])); -+ emit_insn (gen_move_hi_quad_v2df (tmp, operands[2])); -+ emit_insn (gen_aarch64_float_truncate_lo_v2sf (operands[0], tmp)); -+ DONE; -+ } -+) -+ - (define_insn "aarch64_vmls" - [(set (match_operand:VDQF 0 "register_operand" "=w") - (minus:VDQF (match_operand:VDQF 1 "register_operand" "0") -@@ -1261,51 +1606,70 @@ - ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring - ;; NaNs. - --(define_insn "smax3" -+(define_insn "3" - [(set (match_operand:VDQF 0 "register_operand" "=w") -- (smax:VDQF (match_operand:VDQF 1 "register_operand" "w") -+ (FMAXMIN:VDQF (match_operand:VDQF 1 "register_operand" "w") - (match_operand:VDQF 2 "register_operand" "w")))] - "TARGET_SIMD" -- "fmaxnm\\t%0., %1., %2." -+ "fnm\\t%0., %1., %2." - [(set_attr "simd_type" "simd_fminmax") - (set_attr "simd_mode" "")] - ) - --(define_insn "smin3" -+(define_insn "3" - [(set (match_operand:VDQF 0 "register_operand" "=w") -- (smin:VDQF (match_operand:VDQF 1 "register_operand" "w") -- (match_operand:VDQF 2 "register_operand" "w")))] -+ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w") -+ (match_operand:VDQF 2 "register_operand" "w")] -+ FMAXMIN_UNS))] - "TARGET_SIMD" -- "fminnm\\t%0., %1., %2." -+ "\\t%0., %1., %2." - [(set_attr "simd_type" "simd_fminmax") - (set_attr "simd_mode" "")] - ) - --;; FP 'across lanes' max and min ops. -+;; 'across lanes' add. - --(define_insn "reduc_s_v4sf" -- [(set (match_operand:V4SF 0 "register_operand" "=w") -- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")] -- FMAXMINV))] -+(define_insn "reduc_plus_" -+ [(set (match_operand:VDQV 0 "register_operand" "=w") -+ (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] -+ SUADDV))] - "TARGET_SIMD" -- "fnmv\\t%s0, %1.4s"; -- [(set_attr "simd_type" "simd_fminmaxv") -- (set_attr "simd_mode" "V4SF")] -+ "addv\\t%0, %1." -+ [(set_attr "simd_type" "simd_addv") -+ (set_attr "simd_mode" "")] - ) - --(define_insn "reduc_s_" -+(define_insn "reduc_plus_v2di" -+ [(set (match_operand:V2DI 0 "register_operand" "=w") -+ (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] -+ SUADDV))] -+ "TARGET_SIMD" -+ "addp\\t%d0, %1.2d" -+ [(set_attr "simd_type" "simd_addv") -+ (set_attr "simd_mode" "V2DI")] -+) -+ -+(define_insn "reduc_plus_v2si" -+ [(set (match_operand:V2SI 0 "register_operand" "=w") -+ (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] -+ SUADDV))] -+ "TARGET_SIMD" -+ "addp\\t%0.2s, %1.2s, %1.2s" -+ [(set_attr "simd_type" "simd_addv") -+ (set_attr "simd_mode" "V2SI")] -+) -+ -+(define_insn "reduc_plus_" - [(set (match_operand:V2F 0 "register_operand" "=w") - (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] -- FMAXMINV))] -+ SUADDV))] - "TARGET_SIMD" -- "fnmp\\t%0., %1., %1."; -- [(set_attr "simd_type" "simd_fminmax") -+ "faddp\\t%0, %1." -+ [(set_attr "simd_type" "simd_fadd") - (set_attr "simd_mode" "")] - ) - --;; FP 'across lanes' add. +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcvtm_u32_f32 (float32x2_t a) +-{ +- uint32x2_t result; +- __asm__ ("fcvtmu %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "aarch64_addvv4sf" -+(define_insn "aarch64_addpv4sf" - [(set (match_operand:V4SF 0 "register_operand" "=w") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")] - UNSPEC_FADDV))] -@@ -1315,169 +1679,106 @@ - (set_attr "simd_mode" "V4SF")] - ) - --(define_expand "reduc_uplus_v4sf" -- [(set (match_operand:V4SF 0 "register_operand" "=w") -- (match_operand:V4SF 1 "register_operand" "w"))] -+(define_expand "reduc_plus_v4sf" -+ [(set (match_operand:V4SF 0 "register_operand") -+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand")] -+ SUADDV))] - "TARGET_SIMD" - { - rtx tmp = gen_reg_rtx (V4SFmode); -- emit_insn (gen_aarch64_addvv4sf (tmp, operands[1])); -- emit_insn (gen_aarch64_addvv4sf (operands[0], tmp)); -+ emit_insn (gen_aarch64_addpv4sf (tmp, operands[1])); -+ emit_insn (gen_aarch64_addpv4sf (operands[0], tmp)); - DONE; - }) - --(define_expand "reduc_splus_v4sf" -- [(set (match_operand:V4SF 0 "register_operand" "=w") -- (match_operand:V4SF 1 "register_operand" "w"))] -+(define_insn "clz2" -+ [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") -+ (clz:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))] - "TARGET_SIMD" +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtmd_s64_f64 (float64_t a) -{ -- rtx tmp = gen_reg_rtx (V4SFmode); -- emit_insn (gen_aarch64_addvv4sf (tmp, operands[1])); -- emit_insn (gen_aarch64_addvv4sf (operands[0], tmp)); -- DONE; --}) +- float64_t result; +- __asm__ ("fcvtms %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "aarch64_addv" -- [(set (match_operand:V2F 0 "register_operand" "=w") -- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] -- UNSPEC_FADDV))] -- "TARGET_SIMD" -- "faddp\\t%0, %1." -- [(set_attr "simd_type" "simd_fadd") -- (set_attr "simd_mode" "")] -+ "clz\\t%0., %1." -+ [(set_attr "simd_type" "simd_cls") -+ (set_attr "simd_mode" "")] - ) - --(define_expand "reduc_uplus_" -- [(set (match_operand:V2F 0 "register_operand" "=w") -- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] -- UNSPEC_FADDV))] -- "TARGET_SIMD" -- "" --) -+;; 'across lanes' max and min ops. - --(define_expand "reduc_splus_" -- [(set (match_operand:V2F 0 "register_operand" "=w") -- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] -- UNSPEC_FADDV))] -- "TARGET_SIMD" -- "" --) +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtmd_u64_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcvtmu %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --;; Reduction across lanes. +-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +-vcvtmq_s32_f32 (float32x4_t a) +-{ +- int32x4_t result; +- __asm__ ("fcvtms %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "aarch64_addv" -+(define_insn "reduc__" - [(set (match_operand:VDQV 0 "register_operand" "=w") - (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] -- UNSPEC_ADDV))] -+ MAXMINV))] - "TARGET_SIMD" -- "addv\\t%0, %1." -- [(set_attr "simd_type" "simd_addv") -+ "v\\t%0, %1." -+ [(set_attr "simd_type" "simd_minmaxv") - (set_attr "simd_mode" "")] - ) - --(define_expand "reduc_splus_" -- [(set (match_operand:VDQV 0 "register_operand" "=w") -- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] -- UNSPEC_ADDV))] -- "TARGET_SIMD" -- "" --) +-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) +-vcvtmq_s64_f64 (float64x2_t a) +-{ +- int64x2_t result; +- __asm__ ("fcvtms %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_expand "reduc_uplus_" -- [(set (match_operand:VDQV 0 "register_operand" "=w") -- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] -- UNSPEC_ADDV))] -- "TARGET_SIMD" -- "" --) +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcvtmq_u32_f32 (float32x4_t a) +-{ +- uint32x4_t result; +- __asm__ ("fcvtmu %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "aarch64_addvv2di" -+(define_insn "reduc__v2di" - [(set (match_operand:V2DI 0 "register_operand" "=w") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] -- UNSPEC_ADDV))] -+ MAXMINV))] - "TARGET_SIMD" -- "addp\\t%d0, %1.2d" -- [(set_attr "simd_type" "simd_add") -+ "p\\t%d0, %1.2d" -+ [(set_attr "simd_type" "simd_minmaxv") - (set_attr "simd_mode" "V2DI")] - ) - --(define_expand "reduc_uplus_v2di" -- [(set (match_operand:V2DI 0 "register_operand" "=w") -- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] -- UNSPEC_ADDV))] -- "TARGET_SIMD" -- "" --) +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcvtmq_u64_f64 (float64x2_t a) +-{ +- uint64x2_t result; +- __asm__ ("fcvtmu %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_expand "reduc_splus_v2di" -- [(set (match_operand:V2DI 0 "register_operand" "=w") -- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] -- UNSPEC_ADDV))] -- "TARGET_SIMD" -- "" --) +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvtms_s64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtms %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "aarch64_addvv2si" -+(define_insn "reduc__v2si" - [(set (match_operand:V2SI 0 "register_operand" "=w") - (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] -- UNSPEC_ADDV))] -+ MAXMINV))] - "TARGET_SIMD" -- "addp\\t%0.2s, %1.2s, %1.2s" -- [(set_attr "simd_type" "simd_add") -+ "p\\t%0.2s, %1.2s, %1.2s" -+ [(set_attr "simd_type" "simd_minmaxv") - (set_attr "simd_mode" "V2SI")] - ) - --(define_expand "reduc_uplus_v2si" -- [(set (match_operand:V2SI 0 "register_operand" "=w") -- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] -- UNSPEC_ADDV))] -+(define_insn "reduc__" -+ [(set (match_operand:V2F 0 "register_operand" "=w") -+ (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")] -+ FMAXMINV))] - "TARGET_SIMD" -- "" --) +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvtms_u64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtmu %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_expand "reduc_splus_v2si" -- [(set (match_operand:V2SI 0 "register_operand" "=w") -- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] -- UNSPEC_ADDV))] -- "TARGET_SIMD" -- "" --) +-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +-vcvtn_s32_f32 (float32x2_t a) +-{ +- int32x2_t result; +- __asm__ ("fcvtns %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "reduc__" -- [(set (match_operand:VDQV 0 "register_operand" "=w") -- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")] -- MAXMINV))] -- "TARGET_SIMD" -- "v\\t%0, %1." -- [(set_attr "simd_type" "simd_minmaxv") -+ "p\\t%0, %1." -+ [(set_attr "simd_type" "simd_fminmaxv") - (set_attr "simd_mode" "")] - ) - --(define_insn "reduc__v2si" -- [(set (match_operand:V2SI 0 "register_operand" "=w") -- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")] -- MAXMINV))] -+(define_insn "reduc__v4sf" -+ [(set (match_operand:V4SF 0 "register_operand" "=w") -+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")] -+ FMAXMINV))] - "TARGET_SIMD" -- "p\\t%0.2s, %1.2s, %1.2s" -- [(set_attr "simd_type" "simd_minmax") -- (set_attr "simd_mode" "V2SI")] -+ "v\\t%s0, %1.4s" -+ [(set_attr "simd_type" "simd_fminmaxv") -+ (set_attr "simd_mode" "V4SF")] - ) - --;; vbsl_* intrinsics may compile to any of bsl/bif/bit depending on register --;; allocation. For an intrinsic of form: --;; vD = bsl_* (vS, vN, vM) -+;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register -+;; allocation. -+;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which -+;; to select. -+;; -+;; Thus our BSL is of the form: -+;; op0 = bsl (mask, op2, op3) - ;; We can use any of: --;; bsl vS, vN, vM (if D = S) --;; bit vD, vN, vS (if D = M, so 1-bits in vS choose bits from vN, else vM) --;; bif vD, vM, vS (if D = N, so 0-bits in vS choose bits from vM, else vN) -+;; -+;; if (op0 = mask) -+;; bsl mask, op1, op2 -+;; if (op0 = op1) (so 1-bits in mask choose bits from op2, else op0) -+;; bit op0, op2, mask -+;; if (op0 = op2) (so 0-bits in mask choose bits from op1, else op0) -+;; bif op0, op1, mask - - (define_insn "aarch64_simd_bsl_internal" - [(set (match_operand:VALL 0 "register_operand" "=w,w,w") -- (unspec:VALL -- [(match_operand: 1 "register_operand" " 0,w,w") -- (match_operand:VALL 2 "register_operand" " w,w,0") -- (match_operand:VALL 3 "register_operand" " w,0,w")] -- UNSPEC_BSL))] -+ (ior:VALL -+ (and:VALL -+ (match_operand: 1 "register_operand" " 0,w,w") -+ (match_operand:VALL 2 "register_operand" " w,w,0")) -+ (and:VALL -+ (not: -+ (match_dup: 1)) -+ (match_operand:VALL 3 "register_operand" " w,0,w")) -+ ))] - "TARGET_SIMD" - "@ - bsl\\t%0., %2., %3. -@@ -1486,28 +1787,32 @@ - ) - - (define_expand "aarch64_simd_bsl" -- [(set (match_operand:VALL 0 "register_operand") -- (unspec:VALL [(match_operand: 1 "register_operand") -- (match_operand:VALL 2 "register_operand") -- (match_operand:VALL 3 "register_operand")] -- UNSPEC_BSL))] -- "TARGET_SIMD" -+ [(match_operand:VALL 0 "register_operand") -+ (match_operand: 1 "register_operand") -+ (match_operand:VALL 2 "register_operand") -+ (match_operand:VALL 3 "register_operand")] -+ "TARGET_SIMD" - { - /* We can't alias operands together if they have different modes. */ - operands[1] = gen_lowpart (mode, operands[1]); -+ emit_insn (gen_aarch64_simd_bsl_internal (operands[0], operands[1], -+ operands[2], operands[3])); -+ DONE; - }) - --(define_expand "aarch64_vcond_internal" -+(define_expand "aarch64_vcond_internal" - [(set (match_operand:VDQ 0 "register_operand") - (if_then_else:VDQ - (match_operator 3 "comparison_operator" - [(match_operand:VDQ 4 "register_operand") - (match_operand:VDQ 5 "nonmemory_operand")]) -- (match_operand:VDQ 1 "register_operand") -- (match_operand:VDQ 2 "register_operand")))] -+ (match_operand:VDQ 1 "nonmemory_operand") -+ (match_operand:VDQ 2 "nonmemory_operand")))] - "TARGET_SIMD" - { - int inverse = 0, has_zero_imm_form = 0; -+ rtx op1 = operands[1]; -+ rtx op2 = operands[2]; - rtx mask = gen_reg_rtx (mode); - - switch (GET_CODE (operands[3])) -@@ -1566,30 +1871,47 @@ - } - - if (inverse) -- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[2], -- operands[1])); -- else -- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[1], -- operands[2])); -+ { -+ op1 = operands[2]; -+ op2 = operands[1]; -+ } - -+ /* If we have (a = (b CMP c) ? -1 : 0); -+ Then we can simply move the generated mask. */ -+ -+ if (op1 == CONSTM1_RTX (mode) -+ && op2 == CONST0_RTX (mode)) -+ emit_move_insn (operands[0], mask); -+ else -+ { -+ if (!REG_P (op1)) -+ op1 = force_reg (mode, op1); -+ if (!REG_P (op2)) -+ op2 = force_reg (mode, op2); -+ emit_insn (gen_aarch64_simd_bsl (operands[0], mask, -+ op1, op2)); -+ } -+ - DONE; - }) - --(define_expand "aarch64_vcond_internal" -- [(set (match_operand:VDQF 0 "register_operand") -+(define_expand "aarch64_vcond_internal" -+ [(set (match_operand:VDQF_COND 0 "register_operand") - (if_then_else:VDQF - (match_operator 3 "comparison_operator" - [(match_operand:VDQF 4 "register_operand") - (match_operand:VDQF 5 "nonmemory_operand")]) -- (match_operand:VDQF 1 "register_operand") -- (match_operand:VDQF 2 "register_operand")))] -+ (match_operand:VDQF_COND 1 "nonmemory_operand") -+ (match_operand:VDQF_COND 2 "nonmemory_operand")))] - "TARGET_SIMD" - { - int inverse = 0; - int use_zero_form = 0; - int swap_bsl_operands = 0; -- rtx mask = gen_reg_rtx (mode); -- rtx tmp = gen_reg_rtx (mode); -+ rtx op1 = operands[1]; -+ rtx op2 = operands[2]; -+ rtx mask = gen_reg_rtx (mode); -+ rtx tmp = gen_reg_rtx (mode); - - rtx (*base_comparison) (rtx, rtx, rtx); - rtx (*complimentary_comparison) (rtx, rtx, rtx); -@@ -1609,7 +1931,7 @@ - /* Fall through. */ - default: - if (!REG_P (operands[5])) -- operands[5] = force_reg (mode, operands[5]); -+ operands[5] = force_reg (mode, operands[5]); - } - - switch (GET_CODE (operands[3])) -@@ -1622,8 +1944,8 @@ - case UNGE: - case ORDERED: - case UNORDERED: -- base_comparison = gen_aarch64_cmge; -- complimentary_comparison = gen_aarch64_cmgt; -+ base_comparison = gen_aarch64_cmge; -+ complimentary_comparison = gen_aarch64_cmgt; - break; - case LE: - case UNLE: -@@ -1631,14 +1953,14 @@ - /* Fall through. */ - case GT: - case UNGT: -- base_comparison = gen_aarch64_cmgt; -- complimentary_comparison = gen_aarch64_cmge; -+ base_comparison = gen_aarch64_cmgt; -+ complimentary_comparison = gen_aarch64_cmge; - break; - case EQ: - case NE: - case UNEQ: -- base_comparison = gen_aarch64_cmeq; -- complimentary_comparison = gen_aarch64_cmeq; -+ base_comparison = gen_aarch64_cmeq; -+ complimentary_comparison = gen_aarch64_cmeq; - break; - default: - gcc_unreachable (); -@@ -1666,10 +1988,10 @@ - switch (GET_CODE (operands[3])) - { - case LT: -- base_comparison = gen_aarch64_cmlt; -+ base_comparison = gen_aarch64_cmlt; - break; - case LE: -- base_comparison = gen_aarch64_cmle; -+ base_comparison = gen_aarch64_cmle; - break; - default: - /* Do nothing, other zero form cases already have the correct -@@ -1712,9 +2034,9 @@ - true iff !(a != b && a ORDERED b), swapping the operands to BSL - will then give us (a == b || a UNORDERED b) as intended. */ - -- emit_insn (gen_aarch64_cmgt (mask, operands[4], operands[5])); -- emit_insn (gen_aarch64_cmgt (tmp, operands[5], operands[4])); -- emit_insn (gen_ior3 (mask, mask, tmp)); -+ emit_insn (gen_aarch64_cmgt (mask, operands[4], operands[5])); -+ emit_insn (gen_aarch64_cmgt (tmp, operands[5], operands[4])); -+ emit_insn (gen_ior3 (mask, mask, tmp)); - swap_bsl_operands = 1; - break; - case UNORDERED: -@@ -1723,9 +2045,9 @@ - swap_bsl_operands = 1; - /* Fall through. */ - case ORDERED: -- emit_insn (gen_aarch64_cmgt (tmp, operands[4], operands[5])); -- emit_insn (gen_aarch64_cmge (mask, operands[5], operands[4])); -- emit_insn (gen_ior3 (mask, mask, tmp)); -+ emit_insn (gen_aarch64_cmgt (tmp, operands[4], operands[5])); -+ emit_insn (gen_aarch64_cmge (mask, operands[5], operands[4])); -+ emit_insn (gen_ior3 (mask, mask, tmp)); - break; - default: - gcc_unreachable (); -@@ -1732,11 +2054,27 @@ - } - - if (swap_bsl_operands) -- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[2], -- operands[1])); -- else -- emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[1], -- operands[2])); -+ { -+ op1 = operands[2]; -+ op2 = operands[1]; -+ } -+ -+ /* If we have (a = (b CMP c) ? -1 : 0); -+ Then we can simply move the generated mask. */ -+ -+ if (op1 == CONSTM1_RTX (mode) -+ && op2 == CONST0_RTX (mode)) -+ emit_move_insn (operands[0], mask); -+ else -+ { -+ if (!REG_P (op1)) -+ op1 = force_reg (mode, op1); -+ if (!REG_P (op2)) -+ op2 = force_reg (mode, op2); -+ emit_insn (gen_aarch64_simd_bsl (operands[0], mask, -+ op1, op2)); -+ } -+ - DONE; - }) - -@@ -1746,16 +2084,32 @@ - (match_operator 3 "comparison_operator" - [(match_operand:VALL 4 "register_operand") - (match_operand:VALL 5 "nonmemory_operand")]) -- (match_operand:VALL 1 "register_operand") -- (match_operand:VALL 2 "register_operand")))] -+ (match_operand:VALL 1 "nonmemory_operand") -+ (match_operand:VALL 2 "nonmemory_operand")))] - "TARGET_SIMD" - { -- emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], -+ emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], - operands[2], operands[3], - operands[4], operands[5])); - DONE; - }) - -+(define_expand "vcond" -+ [(set (match_operand: 0 "register_operand") -+ (if_then_else: -+ (match_operator 3 "comparison_operator" -+ [(match_operand:VDQF 4 "register_operand") -+ (match_operand:VDQF 5 "nonmemory_operand")]) -+ (match_operand: 1 "nonmemory_operand") -+ (match_operand: 2 "nonmemory_operand")))] -+ "TARGET_SIMD" -+{ -+ emit_insn (gen_aarch64_vcond_internal ( -+ operands[0], operands[1], -+ operands[2], operands[3], -+ operands[4], operands[5])); -+ DONE; -+}) - - (define_expand "vcondu" - [(set (match_operand:VDQ 0 "register_operand") -@@ -1763,11 +2117,11 @@ - (match_operator 3 "comparison_operator" - [(match_operand:VDQ 4 "register_operand") - (match_operand:VDQ 5 "nonmemory_operand")]) -- (match_operand:VDQ 1 "register_operand") -- (match_operand:VDQ 2 "register_operand")))] -+ (match_operand:VDQ 1 "nonmemory_operand") -+ (match_operand:VDQ 2 "nonmemory_operand")))] - "TARGET_SIMD" - { -- emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], -+ emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], - operands[2], operands[3], - operands[4], operands[5])); - DONE; -@@ -1785,45 +2139,50 @@ - DONE; - }) - --(define_insn "aarch64_get_lane_signed" -- [(set (match_operand: 0 "register_operand" "=r") -- (sign_extend: -+;; Lane extraction with sign extension to general purpose register. -+(define_insn "*aarch64_get_lane_extend" -+ [(set (match_operand:GPI 0 "register_operand" "=r") -+ (sign_extend:GPI - (vec_select: -- (match_operand:VQ_S 1 "register_operand" "w") -+ (match_operand:VDQQH 1 "register_operand" "w") - (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))] - "TARGET_SIMD" -- "smov\\t%0, %1.[%2]" -+ "smov\\t%0, %1.[%2]" - [(set_attr "simd_type" "simd_movgp") -- (set_attr "simd_mode" "")] -+ (set_attr "simd_mode" "")] - ) - --(define_insn "aarch64_get_lane_unsigned" -- [(set (match_operand: 0 "register_operand" "=r") -- (zero_extend: -+(define_insn "*aarch64_get_lane_zero_extendsi" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (zero_extend:SI - (vec_select: -- (match_operand:VDQ 1 "register_operand" "w") -+ (match_operand:VDQQH 1 "register_operand" "w") - (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))] - "TARGET_SIMD" -- "umov\\t%0, %1.[%2]" -+ "umov\\t%w0, %1.[%2]" - [(set_attr "simd_type" "simd_movgp") - (set_attr "simd_mode" "")] - ) - -+;; Lane extraction of a value, neither sign nor zero extension -+;; is guaranteed so upper bits should be considered undefined. - (define_insn "aarch64_get_lane" -- [(set (match_operand: 0 "register_operand" "=w") -+ [(set (match_operand: 0 "register_operand" "=r, w") - (vec_select: -- (match_operand:VDQF 1 "register_operand" "w") -- (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] -+ (match_operand:VALL 1 "register_operand" "w, w") -+ (parallel [(match_operand:SI 2 "immediate_operand" "i, i")])))] - "TARGET_SIMD" -- "mov\\t%0.[0], %1.[%2]" -- [(set_attr "simd_type" "simd_ins") -+ "@ -+ umov\\t%0, %1.[%2] -+ dup\\t%0, %1.[%2]" -+ [(set_attr "simd_type" "simd_movgp, simd_dup") - (set_attr "simd_mode" "")] - ) - - (define_expand "aarch64_get_lanedi" -- [(match_operand:DI 0 "register_operand" "=r") -- (match_operand:DI 1 "register_operand" "w") -- (match_operand:SI 2 "immediate_operand" "i")] -+ [(match_operand:DI 0 "register_operand") -+ (match_operand:DI 1 "register_operand") -+ (match_operand:SI 2 "immediate_operand")] - "TARGET_SIMD" - { - aarch64_simd_lane_bounds (operands[2], 0, 1); -@@ -1944,16 +2303,30 @@ - (set_attr "simd_mode" "")] - ) - --(define_insn "aarch64_combine" -+(define_insn_and_split "aarch64_combine" - [(set (match_operand: 0 "register_operand" "=&w") - (vec_concat: (match_operand:VDC 1 "register_operand" "w") - (match_operand:VDC 2 "register_operand" "w")))] - "TARGET_SIMD" -- "mov\\t%0.d[0], %1.d[0]\;ins\\t%0.d[1], %2.d[0]" -- [(set_attr "simd_type" "simd_ins") -- (set_attr "simd_mode" "")] --) -+ "#" -+ "&& reload_completed" -+ [(const_int 0)] -+{ -+ aarch64_split_simd_combine (operands[0], operands[1], operands[2]); -+ DONE; -+}) - -+(define_expand "aarch64_simd_combine" -+ [(set (match_operand: 0 "register_operand" "=&w") -+ (vec_concat: (match_operand:VDC 1 "register_operand" "w") -+ (match_operand:VDC 2 "register_operand" "w")))] -+ "TARGET_SIMD" -+ { -+ emit_insn (gen_move_lo_quad_ (operands[0], operands[1])); -+ emit_insn (gen_move_hi_quad_ (operands[0], operands[2])); -+ DONE; -+ }) -+ - ;; l. - - (define_insn "aarch64_l2_internal" -@@ -2861,28 +3234,6 @@ - (set_attr "simd_mode" "")] - ) - --;; vshl_n -- --(define_expand "aarch64_sshl_n" -- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") -- (match_operand:VSDQ_I_DI 1 "register_operand" "w") -- (match_operand:SI 2 "immediate_operand" "i")] -- "TARGET_SIMD" +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcvtn_u32_f32 (float32x2_t a) -{ -- emit_insn (gen_ashl3 (operands[0], operands[1], operands[2])); -- DONE; --}) +- uint32x2_t result; +- __asm__ ("fcvtnu %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_expand "aarch64_ushl_n" -- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") -- (match_operand:VSDQ_I_DI 1 "register_operand" "w") -- (match_operand:SI 2 "immediate_operand" "i")] -- "TARGET_SIMD" +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtnd_s64_f64 (float64_t a) -{ -- emit_insn (gen_ashl3 (operands[0], operands[1], operands[2])); -- DONE; --}) +- float64_t result; +- __asm__ ("fcvtns %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - - ;; vshll_n - - (define_insn "aarch64_shll_n" -@@ -2927,28 +3278,6 @@ - (set_attr "simd_mode" "")] - ) - --;; vshr_n +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtnd_u64_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcvtnu %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_expand "aarch64_sshr_n" -- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") -- (match_operand:VSDQ_I_DI 1 "register_operand" "w") -- (match_operand:SI 2 "immediate_operand" "i")] -- "TARGET_SIMD" +-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +-vcvtnq_s32_f32 (float32x4_t a) -{ -- emit_insn (gen_ashr3 (operands[0], operands[1], operands[2])); -- DONE; --}) +- int32x4_t result; +- __asm__ ("fcvtns %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_expand "aarch64_ushr_n" -- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w") -- (match_operand:VSDQ_I_DI 1 "register_operand" "w") -- (match_operand:SI 2 "immediate_operand" "i")] -- "TARGET_SIMD" +-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) +-vcvtnq_s64_f64 (float64x2_t a) -{ -- emit_insn (gen_lshr3 (operands[0], operands[1], operands[2])); -- DONE; --}) +- int64x2_t result; +- __asm__ ("fcvtns %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - - ;; vrshr_n - - (define_insn "aarch64_shr_n" -@@ -3059,7 +3388,8 @@ - (COMPARISONS:DI - (match_operand:DI 1 "register_operand" "w,w,r") - (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz,r") -- )))] -+ ))) -+ (clobber (reg:CC CC_REGNUM))] - "TARGET_SIMD" - "@ - cm\t%d0, %d, %d -@@ -3070,15 +3400,7 @@ - happening in the 'w' constraint cases. */ - && GP_REGNUM_P (REGNO (operands[0])) - && GP_REGNUM_P (REGNO (operands[1]))" -- [(set (reg:CC CC_REGNUM) -- (compare:CC -- (match_dup 1) -- (match_dup 2))) -- (set (match_dup 0) -- (neg:DI -- (COMPARISONS:DI -- (match_operand 3 "cc_register" "") -- (const_int 0))))] -+ [(const_int 0)] - { - enum machine_mode mode = SELECT_CC_MODE (, operands[1], operands[2]); - rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); -@@ -3111,7 +3433,8 @@ - (UCOMPARISONS:DI - (match_operand:DI 1 "register_operand" "w,r") - (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,r") -- )))] -+ ))) -+ (clobber (reg:CC CC_REGNUM))] - "TARGET_SIMD" - "@ - cm\t%d0, %d, %d -@@ -3121,17 +3444,9 @@ - happening in the 'w' constraint cases. */ - && GP_REGNUM_P (REGNO (operands[0])) - && GP_REGNUM_P (REGNO (operands[1]))" -- [(set (reg:CC CC_REGNUM) -- (compare:CC -- (match_dup 1) -- (match_dup 2))) -- (set (match_dup 0) -- (neg:DI -- (UCOMPARISONS:DI -- (match_operand 3 "cc_register" "") -- (const_int 0))))] -+ [(const_int 0)] - { -- enum machine_mode mode = SELECT_CC_MODE (, operands[1], operands[2]); -+ enum machine_mode mode = CCmode; - rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); - rtx comparison = gen_rtx_ (mode, operands[1], operands[2]); - emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg)); -@@ -3164,7 +3479,8 @@ - (and:DI - (match_operand:DI 1 "register_operand" "w,r") - (match_operand:DI 2 "register_operand" "w,r")) -- (const_int 0))))] -+ (const_int 0)))) -+ (clobber (reg:CC CC_REGNUM))] - "TARGET_SIMD" - "@ - cmtst\t%d0, %d1, %d2 -@@ -3174,16 +3490,7 @@ - happening in the 'w' constraint cases. */ - && GP_REGNUM_P (REGNO (operands[0])) - && GP_REGNUM_P (REGNO (operands[1]))" -- [(set (reg:CC_NZ CC_REGNUM) -- (compare:CC_NZ -- (and:DI (match_dup 1) -- (match_dup 2)) -- (const_int 0))) -- (set (match_dup 0) -- (neg:DI -- (ne:DI -- (match_operand 3 "cc_register" "") -- (const_int 0))))] -+ [(const_int 0)] - { - rtx and_tree = gen_rtx_AND (DImode, operands[1], operands[2]); - enum machine_mode mode = SELECT_CC_MODE (NE, and_tree, const0_rtx); -@@ -3213,6 +3520,23 @@ - (set_attr "simd_mode" "")] - ) - -+;; fac(ge|gt) -+;; Note we can also handle what would be fac(le|lt) by -+;; generating fac(ge|gt). -+ -+(define_insn "*aarch64_fac" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (neg: -+ (FAC_COMPARISONS: -+ (abs:VALLF (match_operand:VALLF 1 "register_operand" "w")) -+ (abs:VALLF (match_operand:VALLF 2 "register_operand" "w")) -+ )))] -+ "TARGET_SIMD" -+ "fac\t%0, %, %" -+ [(set_attr "simd_type" "simd_fcmp") -+ (set_attr "simd_mode" "")] -+) -+ - ;; addp - - (define_insn "aarch64_addp" -@@ -3238,30 +3562,6 @@ - (set_attr "simd_mode" "DI")] - ) - --;; v(max|min) +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcvtnq_u32_f32 (float32x4_t a) +-{ +- uint32x4_t result; +- __asm__ ("fcvtnu %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_expand "aarch64_" -- [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") -- (MAXMIN:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w") -- (match_operand:VDQ_BHSI 2 "register_operand" "w")))] -- "TARGET_SIMD" +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcvtnq_u64_f64 (float64x2_t a) -{ -- emit_insn (gen_3 (operands[0], operands[1], operands[2])); -- DONE; --}) +- uint64x2_t result; +- __asm__ ("fcvtnu %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvtns_s64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtns %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - --(define_insn "aarch64_" -- [(set (match_operand:VDQF 0 "register_operand" "=w") -- (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w") -- (match_operand:VDQF 2 "register_operand" "w")] -- FMAXMIN))] -- "TARGET_SIMD" -- "\t%0., %1., %2." -- [(set_attr "simd_type" "simd_fminmax") -- (set_attr "simd_mode" "")] --) +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvtns_u64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtnu %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - - ;; sqrt - - (define_insn "sqrt2" -@@ -3273,16 +3573,6 @@ - (set_attr "simd_mode" "")] - ) - --(define_expand "aarch64_sqrt" -- [(match_operand:VDQF 0 "register_operand" "=w") -- (match_operand:VDQF 1 "register_operand" "w")] -- "TARGET_SIMD" +-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +-vcvtp_s32_f32 (float32x2_t a) -{ -- emit_insn (gen_sqrt2 (operands[0], operands[1])); -- DONE; --}) +- int32x2_t result; +- __asm__ ("fcvtps %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vcvtp_u32_f32 (float32x2_t a) +-{ +- uint32x2_t result; +- __asm__ ("fcvtpu %0.2s, %1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - - ;; Patterns for vector struct loads and stores. - - (define_insn "vec_load_lanesoi" -@@ -3869,3 +4159,147 @@ - "ld1r\\t{%0.}, %1" - [(set_attr "simd_type" "simd_load1r") - (set_attr "simd_mode" "")]) -+ -+(define_insn "aarch64_frecpe" -+ [(set (match_operand:VDQF 0 "register_operand" "=w") -+ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")] -+ UNSPEC_FRECPE))] -+ "TARGET_SIMD" -+ "frecpe\\t%0., %1." -+ [(set_attr "simd_type" "simd_frecpe") -+ (set_attr "simd_mode" "")] -+) -+ -+(define_insn "aarch64_frecps" -+ [(set (match_operand:VDQF 0 "register_operand" "=w") -+ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w") -+ (match_operand:VDQF 2 "register_operand" "w")] -+ UNSPEC_FRECPS))] -+ "TARGET_SIMD" -+ "frecps\\t%0., %1., %2." -+ [(set_attr "simd_type" "simd_frecps") -+ (set_attr "simd_mode" "")] -+) -+ -+;; aes -+ -+(define_insn "aarch64_crypto_aesv16qi" -+ [(set (match_operand:V16QI 0 "register_operand" "=w") -+ (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0") -+ (match_operand:V16QI 2 "register_operand" "w")] -+ CRYPTO_AES))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "aes\\t%0.16b, %2.16b" -+ [(set_attr "simd_type" "simd_crypto_aes") -+ (set_attr "simd_mode" "V16QI")]) -+ -+(define_insn "aarch64_crypto_aesv16qi" -+ [(set (match_operand:V16QI 0 "register_operand" "=w") -+ (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "w")] -+ CRYPTO_AESMC))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "aes\\t%0.16b, %1.16b" -+ [(set_attr "simd_type" "simd_crypto_aes") -+ (set_attr "simd_mode" "V16QI")]) -+ -+;; sha1 -+ -+(define_insn "aarch64_crypto_sha1hsi" -+ [(set (match_operand:SI 0 "register_operand" "=w") -+ (unspec:SI [(match_operand:SI 1 -+ "register_operand" "w")] -+ UNSPEC_SHA1H))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "sha1h\\t%s0, %s1" -+ [(set_attr "simd_type" "simd_crypto_sha1_fast") -+ (set_attr "simd_mode" "SI")]) -+ -+(define_insn "aarch64_crypto_sha1su1v4si" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") -+ (match_operand:V4SI 2 "register_operand" "w")] -+ UNSPEC_SHA1SU1))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "sha1su1\\t%0.4s, %2.4s" -+ [(set_attr "simd_type" "simd_crypto_sha1_fast") -+ (set_attr "simd_mode" "V4SI")]) -+ -+(define_insn "aarch64_crypto_sha1v4si" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") -+ (match_operand:SI 2 "register_operand" "w") -+ (match_operand:V4SI 3 "register_operand" "w")] -+ CRYPTO_SHA1))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "sha1\\t%q0, %s2, %3.4s" -+ [(set_attr "simd_type" "simd_crypto_sha1_slow") -+ (set_attr "simd_mode" "V4SI")]) -+ -+(define_insn "aarch64_crypto_sha1su0v4si" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") -+ (match_operand:V4SI 2 "register_operand" "w") -+ (match_operand:V4SI 3 "register_operand" "w")] -+ UNSPEC_SHA1SU0))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "sha1su0\\t%0.4s, %2.4s, %3.4s" -+ [(set_attr "simd_type" "simd_crypto_sha1_xor") -+ (set_attr "simd_mode" "V4SI")]) -+ -+ -+;; sha256 -+ -+(define_insn "aarch64_crypto_sha256hv4si" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") -+ (match_operand:V4SI 2 "register_operand" "w") -+ (match_operand:V4SI 3 "register_operand" "w")] -+ CRYPTO_SHA256))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "sha256h\\t%q0, %q2, %3.4s" -+ [(set_attr "simd_type" "simd_crypto_sha256_slow") -+ (set_attr "simd_mode" "V4SI")]) -+ -+(define_insn "aarch64_crypto_sha256su0v4si" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") -+ (match_operand:V4SI 2 "register_operand" "w")] -+ UNSPEC_SHA256SU0))] -+ "TARGET_SIMD &&TARGET_CRYPTO" -+ "sha256su0\\t%0.4s, %2.4s" -+ [(set_attr "simd_type" "simd_crypto_sha256_fast") -+ (set_attr "simd_mode" "V4SI")]) -+ -+(define_insn "aarch64_crypto_sha256su1v4si" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") -+ (match_operand:V4SI 2 "register_operand" "w") -+ (match_operand:V4SI 3 "register_operand" "w")] -+ UNSPEC_SHA256SU1))] -+ "TARGET_SIMD &&TARGET_CRYPTO" -+ "sha256su1\\t%0.4s, %2.4s, %3.4s" -+ [(set_attr "simd_type""simd_crypto_sha256_slow") -+ (set_attr "simd_mode" "V4SI")]) -+ -+ -+;; pmull -+ -+(define_insn "aarch64_crypto_pmulldi" -+ [(set (match_operand:TI 0 "register_operand" "=w") -+ (unspec:TI [(match_operand:DI 1 "register_operand" "w") -+ (match_operand:DI 2 "register_operand" "w")] -+ UNSPEC_PMULL))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "pmull\\t%0.1q, %1.1d, %2.1d" -+ [(set_attr "simd_type" "simd_mul_d_long") -+ (set_attr "simd_mode" "TI")]) -+ -+(define_insn "aarch64_crypto_pmullv2di" -+ [(set (match_operand:TI 0 "register_operand" "=w") -+ (unspec:TI [(match_operand:V2DI 1 "register_operand" "w") -+ (match_operand:V2DI 2 "register_operand" "w")] -+ UNSPEC_PMULL2))] -+ "TARGET_SIMD && TARGET_CRYPTO" -+ "pmull2\\t%0.1q, %1.2d, %2.2d" -+ [(set_attr "simd_type" "simd_mul_d_long") -+ (set_attr "simd_mode" "TI")]) -\ No newline at end of file ---- a/src/gcc/config/aarch64/predicates.md -+++ b/src/gcc/config/aarch64/predicates.md -@@ -115,16 +115,11 @@ - (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, - 0)"))) - --(define_predicate "aarch64_const_address" -- (and (match_code "symbol_ref") -- (match_test "mode == DImode && CONSTANT_ADDRESS_P (op)"))) +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vcvtpd_s64_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("fcvtps %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} - - (define_predicate "aarch64_valid_symref" - (match_code "const, symbol_ref, label_ref") - { -- enum aarch64_symbol_type symbol_type; -- return (aarch64_symbolic_constant_p (op, SYMBOL_CONTEXT_ADR, &symbol_type) -- && symbol_type != SYMBOL_FORCE_TO_MEM); -+ return (aarch64_classify_symbolic_expression (op, SYMBOL_CONTEXT_ADR) -+ != SYMBOL_FORCE_TO_MEM); - }) - - (define_predicate "aarch64_tls_ie_symref" -@@ -170,15 +165,10 @@ - }) - - (define_predicate "aarch64_mov_operand" -- (and (match_code "reg,subreg,mem,const_int,symbol_ref,high") -+ (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high") - (ior (match_operand 0 "register_operand") - (ior (match_operand 0 "memory_operand") -- (ior (match_test "GET_CODE (op) == HIGH -- && aarch64_valid_symref (XEXP (op, 0), -- GET_MODE (XEXP (op, 0)))") -- (ior (match_test "CONST_INT_P (op) -- && aarch64_move_imm (INTVAL (op), mode)") -- (match_test "aarch64_const_address (op, mode)"))))))) -+ (match_test "aarch64_mov_operand_p (op, SYMBOL_CONTEXT_ADR, mode)"))))) - - (define_predicate "aarch64_movti_operand" - (and (match_code "reg,subreg,mem,const_int") ---- a/src/gcc/config/aarch64/aarch64-elf.h -+++ b/src/gcc/config/aarch64/aarch64-elf.h -@@ -106,7 +106,6 @@ - - #define ASM_COMMENT_START "//" - --#define REGISTER_PREFIX "" - #define LOCAL_LABEL_PREFIX "." - #define USER_LABEL_PREFIX "" - ---- a/src/gcc/config/aarch64/arm_neon.h -+++ b/src/gcc/config/aarch64/arm_neon.h -@@ -29,6 +29,9 @@ - - #include - -+#define __AARCH64_UINT64_C(__C) ((uint64_t) __C) -+#define __AARCH64_INT64_C(__C) ((int64_t) __C) -+ - typedef __builtin_aarch64_simd_qi int8x8_t - __attribute__ ((__vector_size__ (8))); - typedef __builtin_aarch64_simd_hi int16x4_t -@@ -72,6 +75,8 @@ - __attribute__ ((__vector_size__ (16))); - typedef __builtin_aarch64_simd_poly16 poly16x8_t - __attribute__ ((__vector_size__ (16))); -+typedef __builtin_aarch64_simd_poly64 poly64x2_t -+ __attribute__ ((__vector_size__ (16))); - typedef __builtin_aarch64_simd_uqi uint8x16_t - __attribute__ ((__vector_size__ (16))); - typedef __builtin_aarch64_simd_uhi uint16x8_t -@@ -85,6 +90,8 @@ - typedef double float64_t; - typedef __builtin_aarch64_simd_poly8 poly8_t; - typedef __builtin_aarch64_simd_poly16 poly16_t; -+typedef __builtin_aarch64_simd_poly64 poly64_t; -+typedef __builtin_aarch64_simd_poly128 poly128_t; - - typedef struct int8x8x2_t - { -@@ -446,7 +453,66 @@ - poly16x8_t val[4]; - } poly16x8x4_t; - -+/* vget_lane internal macros. */ - -+#define __aarch64_vget_lane_any(__size, __cast_ret, __cast_a, __a, __b) \ -+ (__cast_ret \ -+ __builtin_aarch64_get_lane##__size (__cast_a __a, __b)) -+ -+#define __aarch64_vget_lane_f32(__a, __b) \ -+ __aarch64_vget_lane_any (v2sf, , , __a, __b) -+#define __aarch64_vget_lane_f64(__a, __b) (__a) -+ -+#define __aarch64_vget_lane_p8(__a, __b) \ -+ __aarch64_vget_lane_any (v8qi, (poly8_t), (int8x8_t), __a, __b) -+#define __aarch64_vget_lane_p16(__a, __b) \ -+ __aarch64_vget_lane_any (v4hi, (poly16_t), (int16x4_t), __a, __b) -+ -+#define __aarch64_vget_lane_s8(__a, __b) \ -+ __aarch64_vget_lane_any (v8qi, , ,__a, __b) -+#define __aarch64_vget_lane_s16(__a, __b) \ -+ __aarch64_vget_lane_any (v4hi, , ,__a, __b) -+#define __aarch64_vget_lane_s32(__a, __b) \ -+ __aarch64_vget_lane_any (v2si, , ,__a, __b) -+#define __aarch64_vget_lane_s64(__a, __b) (__a) -+ -+#define __aarch64_vget_lane_u8(__a, __b) \ -+ __aarch64_vget_lane_any (v8qi, (uint8_t), (int8x8_t), __a, __b) -+#define __aarch64_vget_lane_u16(__a, __b) \ -+ __aarch64_vget_lane_any (v4hi, (uint16_t), (int16x4_t), __a, __b) -+#define __aarch64_vget_lane_u32(__a, __b) \ -+ __aarch64_vget_lane_any (v2si, (uint32_t), (int32x2_t), __a, __b) -+#define __aarch64_vget_lane_u64(__a, __b) (__a) -+ -+#define __aarch64_vgetq_lane_f32(__a, __b) \ -+ __aarch64_vget_lane_any (v4sf, , , __a, __b) -+#define __aarch64_vgetq_lane_f64(__a, __b) \ -+ __aarch64_vget_lane_any (v2df, , , __a, __b) -+ -+#define __aarch64_vgetq_lane_p8(__a, __b) \ -+ __aarch64_vget_lane_any (v16qi, (poly8_t), (int8x16_t), __a, __b) -+#define __aarch64_vgetq_lane_p16(__a, __b) \ -+ __aarch64_vget_lane_any (v8hi, (poly16_t), (int16x8_t), __a, __b) -+ -+#define __aarch64_vgetq_lane_s8(__a, __b) \ -+ __aarch64_vget_lane_any (v16qi, , ,__a, __b) -+#define __aarch64_vgetq_lane_s16(__a, __b) \ -+ __aarch64_vget_lane_any (v8hi, , ,__a, __b) -+#define __aarch64_vgetq_lane_s32(__a, __b) \ -+ __aarch64_vget_lane_any (v4si, , ,__a, __b) -+#define __aarch64_vgetq_lane_s64(__a, __b) \ -+ __aarch64_vget_lane_any (v2di, , ,__a, __b) -+ -+#define __aarch64_vgetq_lane_u8(__a, __b) \ -+ __aarch64_vget_lane_any (v16qi, (uint8_t), (int8x16_t), __a, __b) -+#define __aarch64_vgetq_lane_u16(__a, __b) \ -+ __aarch64_vget_lane_any (v8hi, (uint16_t), (int16x8_t), __a, __b) -+#define __aarch64_vgetq_lane_u32(__a, __b) \ -+ __aarch64_vget_lane_any (v4si, (uint32_t), (int32x4_t), __a, __b) -+#define __aarch64_vgetq_lane_u64(__a, __b) \ -+ __aarch64_vget_lane_any (v2di, (uint64_t), (int64x2_t), __a, __b) -+ -+/* vadd */ - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vadd_s8 (int8x8_t __a, int8x8_t __b) - { -@@ -2307,155 +2373,156 @@ - return (poly16x4_t) __a; - } - -+/* vget_lane */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vget_lane_f32 (float32x2_t __a, const int __b) -+{ -+ return __aarch64_vget_lane_f32 (__a, __b); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vget_lane_f64 (float64x1_t __a, const int __b) -+{ -+ return __aarch64_vget_lane_f64 (__a, __b); -+} -+ -+__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) -+vget_lane_p8 (poly8x8_t __a, const int __b) -+{ -+ return __aarch64_vget_lane_p8 (__a, __b); -+} -+ -+__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) -+vget_lane_p16 (poly16x4_t __a, const int __b) -+{ -+ return __aarch64_vget_lane_p16 (__a, __b); -+} -+ - __extension__ static __inline int8_t __attribute__ ((__always_inline__)) - vget_lane_s8 (int8x8_t __a, const int __b) - { -- return (int8_t) __builtin_aarch64_get_lane_signedv8qi (__a, __b); -+ return __aarch64_vget_lane_s8 (__a, __b); - } - - __extension__ static __inline int16_t __attribute__ ((__always_inline__)) - vget_lane_s16 (int16x4_t __a, const int __b) - { -- return (int16_t) __builtin_aarch64_get_lane_signedv4hi (__a, __b); -+ return __aarch64_vget_lane_s16 (__a, __b); - } - - __extension__ static __inline int32_t __attribute__ ((__always_inline__)) - vget_lane_s32 (int32x2_t __a, const int __b) - { -- return (int32_t) __builtin_aarch64_get_lane_signedv2si (__a, __b); -+ return __aarch64_vget_lane_s32 (__a, __b); - } - --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vget_lane_f32 (float32x2_t __a, const int __b) -+__extension__ static __inline int64_t __attribute__ ((__always_inline__)) -+vget_lane_s64 (int64x1_t __a, const int __b) - { -- return (float32_t) __builtin_aarch64_get_lanev2sf (__a, __b); -+ return __aarch64_vget_lane_s64 (__a, __b); - } - - __extension__ static __inline uint8_t __attribute__ ((__always_inline__)) - vget_lane_u8 (uint8x8_t __a, const int __b) - { -- return (uint8_t) __builtin_aarch64_get_lane_unsignedv8qi ((int8x8_t) __a, -- __b); -+ return __aarch64_vget_lane_u8 (__a, __b); - } - - __extension__ static __inline uint16_t __attribute__ ((__always_inline__)) - vget_lane_u16 (uint16x4_t __a, const int __b) - { -- return (uint16_t) __builtin_aarch64_get_lane_unsignedv4hi ((int16x4_t) __a, -- __b); -+ return __aarch64_vget_lane_u16 (__a, __b); - } - - __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) - vget_lane_u32 (uint32x2_t __a, const int __b) - { -- return (uint32_t) __builtin_aarch64_get_lane_unsignedv2si ((int32x2_t) __a, -- __b); -+ return __aarch64_vget_lane_u32 (__a, __b); - } - --__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) --vget_lane_p8 (poly8x8_t __a, const int __b) -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vget_lane_u64 (uint64x1_t __a, const int __b) - { -- return (poly8_t) __builtin_aarch64_get_lane_unsignedv8qi ((int8x8_t) __a, -- __b); -+ return __aarch64_vget_lane_u64 (__a, __b); - } - --__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) --vget_lane_p16 (poly16x4_t __a, const int __b) -+/* vgetq_lane */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vgetq_lane_f32 (float32x4_t __a, const int __b) - { -- return (poly16_t) __builtin_aarch64_get_lane_unsignedv4hi ((int16x4_t) __a, -- __b); -+ return __aarch64_vgetq_lane_f32 (__a, __b); - } - --__extension__ static __inline int64_t __attribute__ ((__always_inline__)) --vget_lane_s64 (int64x1_t __a, const int __b) -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vgetq_lane_f64 (float64x2_t __a, const int __b) - { -- return (int64_t) __builtin_aarch64_get_lanedi (__a, __b); -+ return __aarch64_vgetq_lane_f64 (__a, __b); - } - --__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) --vget_lane_u64 (uint64x1_t __a, const int __b) -+__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) -+vgetq_lane_p8 (poly8x16_t __a, const int __b) - { -- return (uint64_t) __builtin_aarch64_get_lanedi ((int64x1_t) __a, __b); -+ return __aarch64_vgetq_lane_p8 (__a, __b); - } - -+__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) -+vgetq_lane_p16 (poly16x8_t __a, const int __b) -+{ -+ return __aarch64_vgetq_lane_p16 (__a, __b); -+} -+ - __extension__ static __inline int8_t __attribute__ ((__always_inline__)) - vgetq_lane_s8 (int8x16_t __a, const int __b) - { -- return (int8_t) __builtin_aarch64_get_lane_signedv16qi (__a, __b); -+ return __aarch64_vgetq_lane_s8 (__a, __b); - } - - __extension__ static __inline int16_t __attribute__ ((__always_inline__)) - vgetq_lane_s16 (int16x8_t __a, const int __b) - { -- return (int16_t) __builtin_aarch64_get_lane_signedv8hi (__a, __b); -+ return __aarch64_vgetq_lane_s16 (__a, __b); - } - - __extension__ static __inline int32_t __attribute__ ((__always_inline__)) - vgetq_lane_s32 (int32x4_t __a, const int __b) - { -- return (int32_t) __builtin_aarch64_get_lane_signedv4si (__a, __b); -+ return __aarch64_vgetq_lane_s32 (__a, __b); - } - --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vgetq_lane_f32 (float32x4_t __a, const int __b) -+__extension__ static __inline int64_t __attribute__ ((__always_inline__)) -+vgetq_lane_s64 (int64x2_t __a, const int __b) - { -- return (float32_t) __builtin_aarch64_get_lanev4sf (__a, __b); -+ return __aarch64_vgetq_lane_s64 (__a, __b); - } - -__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vgetq_lane_f64 (float64x2_t __a, const int __b) --{ -- return (float64_t) __builtin_aarch64_get_lanev2df (__a, __b); --} -- - __extension__ static __inline uint8_t __attribute__ ((__always_inline__)) - vgetq_lane_u8 (uint8x16_t __a, const int __b) - { -- return (uint8_t) __builtin_aarch64_get_lane_unsignedv16qi ((int8x16_t) __a, -- __b); -+ return __aarch64_vgetq_lane_u8 (__a, __b); - } - - __extension__ static __inline uint16_t __attribute__ ((__always_inline__)) - vgetq_lane_u16 (uint16x8_t __a, const int __b) - { -- return (uint16_t) __builtin_aarch64_get_lane_unsignedv8hi ((int16x8_t) __a, -- __b); -+ return __aarch64_vgetq_lane_u16 (__a, __b); - } - - __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) - vgetq_lane_u32 (uint32x4_t __a, const int __b) - { -- return (uint32_t) __builtin_aarch64_get_lane_unsignedv4si ((int32x4_t) __a, -- __b); -+ return __aarch64_vgetq_lane_u32 (__a, __b); - } - --__extension__ static __inline poly8_t __attribute__ ((__always_inline__)) --vgetq_lane_p8 (poly8x16_t __a, const int __b) --{ -- return (poly8_t) __builtin_aarch64_get_lane_unsignedv16qi ((int8x16_t) __a, -- __b); --} -- --__extension__ static __inline poly16_t __attribute__ ((__always_inline__)) --vgetq_lane_p16 (poly16x8_t __a, const int __b) --{ -- return (poly16_t) __builtin_aarch64_get_lane_unsignedv8hi ((int16x8_t) __a, -- __b); --} -- --__extension__ static __inline int64_t __attribute__ ((__always_inline__)) --vgetq_lane_s64 (int64x2_t __a, const int __b) --{ -- return __builtin_aarch64_get_lane_unsignedv2di (__a, __b); --} -- - __extension__ static __inline uint64_t __attribute__ ((__always_inline__)) - vgetq_lane_u64 (uint64x2_t __a, const int __b) - { -- return (uint64_t) __builtin_aarch64_get_lane_unsignedv2di ((int64x2_t) __a, -- __b); -+ return __aarch64_vgetq_lane_u64 (__a, __b); - } - -+/* vreinterpret */ -+ - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) - vreinterpret_p8_s8 (int8x8_t __a) - { -@@ -3805,6 +3872,85 @@ - return (uint32x4_t) __builtin_aarch64_reinterpretv4siv8hi ((int16x8_t) __a); - } - -+#define __GET_LOW(__TYPE) \ -+ uint64x2_t tmp = vreinterpretq_u64_##__TYPE (__a); \ -+ uint64_t lo = vgetq_lane_u64 (tmp, 0); \ -+ return vreinterpret_##__TYPE##_u64 (lo); -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vget_low_f32 (float32x4_t __a) -+{ -+ __GET_LOW (f32); -+} -+ -+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) -+vget_low_f64 (float64x2_t __a) -+{ -+ return vgetq_lane_f64 (__a, 0); -+} -+ -+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) -+vget_low_p8 (poly8x16_t __a) -+{ -+ __GET_LOW (p8); -+} -+ -+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) -+vget_low_p16 (poly16x8_t __a) -+{ -+ __GET_LOW (p16); -+} -+ -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vget_low_s8 (int8x16_t __a) -+{ -+ __GET_LOW (s8); -+} -+ -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vget_low_s16 (int16x8_t __a) -+{ -+ __GET_LOW (s16); -+} -+ -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vget_low_s32 (int32x4_t __a) -+{ -+ __GET_LOW (s32); -+} -+ -+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -+vget_low_s64 (int64x2_t __a) -+{ -+ return vgetq_lane_s64 (__a, 0); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vget_low_u8 (uint8x16_t __a) -+{ -+ __GET_LOW (u8); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vget_low_u16 (uint16x8_t __a) -+{ -+ __GET_LOW (u16); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vget_low_u32 (uint32x4_t __a) -+{ -+ __GET_LOW (u32); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vget_low_u64 (uint64x2_t __a) -+{ -+ return vgetq_lane_u64 (__a, 0); -+} -+ -+#undef __GET_LOW -+ - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vcombine_s8 (int8x8_t __a, int8x8_t __b) - { -@@ -4468,160 +4614,6 @@ - return result; - } - --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vabs_f32 (float32x2_t a) --{ -- float32x2_t result; -- __asm__ ("fabs %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vabs_s8 (int8x8_t a) --{ -- int8x8_t result; -- __asm__ ("abs %0.8b,%1.8b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vabs_s16 (int16x4_t a) --{ -- int16x4_t result; -- __asm__ ("abs %0.4h,%1.4h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vabs_s32 (int32x2_t a) --{ -- int32x2_t result; -- __asm__ ("abs %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vabsq_f32 (float32x4_t a) +-vcvtpd_u64_f64 (float64_t a) -{ -- float32x4_t result; -- __asm__ ("fabs %0.4s,%1.4s" +- float64_t result; +- __asm__ ("fcvtpu %d0,%d1" - : "=w"(result) - : "w"(a) - : /* No clobbers */); - return result; -} - --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vabsq_f64 (float64x2_t a) +-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +-vcvtpq_s32_f32 (float32x4_t a) -{ -- float64x2_t result; -- __asm__ ("fabs %0.2d,%1.2d" +- int32x4_t result; +- __asm__ ("fcvtps %0.4s, %1.4s" - : "=w"(result) - : "w"(a) - : /* No clobbers */); - return result; -} - --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vabsq_s8 (int8x16_t a) +-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) +-vcvtpq_s64_f64 (float64x2_t a) -{ -- int8x16_t result; -- __asm__ ("abs %0.16b,%1.16b" +- int64x2_t result; +- __asm__ ("fcvtps %0.2d, %1.2d" - : "=w"(result) - : "w"(a) - : /* No clobbers */); - return result; -} - --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vabsq_s16 (int16x8_t a) +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcvtpq_u32_f32 (float32x4_t a) -{ -- int16x8_t result; -- __asm__ ("abs %0.8h,%1.8h" +- uint32x4_t result; +- __asm__ ("fcvtpu %0.4s, %1.4s" - : "=w"(result) - : "w"(a) - : /* No clobbers */); - return result; -} - --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vabsq_s32 (int32x4_t a) +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcvtpq_u64_f64 (float64x2_t a) -{ -- int32x4_t result; -- __asm__ ("abs %0.4s,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vabsq_s64 (int64x2_t a) --{ -- int64x2_t result; -- __asm__ ("abs %0.2d,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vacged_f64 (float64_t a, float64_t b) --{ -- float64_t result; -- __asm__ ("facge %d0,%d1,%d2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vacges_f32 (float32_t a, float32_t b) --{ -- float32_t result; -- __asm__ ("facge %s0,%s1,%s2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vacgtd_f64 (float64_t a, float64_t b) --{ -- float64_t result; -- __asm__ ("facgt %d0,%d1,%d2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vacgts_f32 (float32_t a, float32_t b) --{ -- float32_t result; -- __asm__ ("facgt %s0,%s1,%s2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline int16_t __attribute__ ((__always_inline__)) - vaddlv_s8 (int8x8_t a) - { -@@ -4732,116 +4724,6 @@ - return result; - } - --__extension__ static __inline int8_t __attribute__ ((__always_inline__)) --vaddv_s8 (int8x8_t a) --{ -- int8_t result; -- __asm__ ("addv %b0,%1.8b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16_t __attribute__ ((__always_inline__)) --vaddv_s16 (int16x4_t a) --{ -- int16_t result; -- __asm__ ("addv %h0,%1.4h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) --vaddv_u8 (uint8x8_t a) --{ -- uint8_t result; -- __asm__ ("addv %b0,%1.8b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) --vaddv_u16 (uint16x4_t a) --{ -- uint16_t result; -- __asm__ ("addv %h0,%1.4h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int8_t __attribute__ ((__always_inline__)) --vaddvq_s8 (int8x16_t a) --{ -- int8_t result; -- __asm__ ("addv %b0,%1.16b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16_t __attribute__ ((__always_inline__)) --vaddvq_s16 (int16x8_t a) --{ -- int16_t result; -- __asm__ ("addv %h0,%1.8h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32_t __attribute__ ((__always_inline__)) --vaddvq_s32 (int32x4_t a) --{ -- int32_t result; -- __asm__ ("addv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) --vaddvq_u8 (uint8x16_t a) --{ -- uint8_t result; -- __asm__ ("addv %b0,%1.16b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) --vaddvq_u16 (uint16x8_t a) --{ -- uint16_t result; -- __asm__ ("addv %h0,%1.8h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) --vaddvq_u32 (uint32x4_t a) --{ -- uint32_t result; -- __asm__ ("addv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) - vbsl_f32 (uint32x2_t a, float32x2_t b, float32x2_t c) - { -@@ -5095,358 +4977,6 @@ - return result; - } - --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcage_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("facge %0.2s, %1.2s, %2.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcageq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("facge %0.4s, %1.4s, %2.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcageq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("facge %0.2d, %1.2d, %2.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcagt_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("facgt %0.2s, %1.2s, %2.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcagtq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("facgt %0.4s, %1.4s, %2.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcagtq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("facgt %0.2d, %1.2d, %2.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcale_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("facge %0.2s, %2.2s, %1.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcaleq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("facge %0.4s, %2.4s, %1.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcaleq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("facge %0.2d, %2.2d, %1.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcalt_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("facgt %0.2s, %2.2s, %1.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcaltq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("facgt %0.4s, %2.4s, %1.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcaltq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("facgt %0.2d, %2.2d, %1.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vceq_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("fcmeq %0.2s, %1.2s, %2.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vceq_f64 (float64x1_t a, float64x1_t b) --{ -- uint64x1_t result; -- __asm__ ("fcmeq %d0, %d1, %d2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vceqd_f64 (float64_t a, float64_t b) --{ -- float64_t result; -- __asm__ ("fcmeq %d0,%d1,%d2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vceqq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("fcmeq %0.4s, %1.4s, %2.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vceqq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("fcmeq %0.2d, %1.2d, %2.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vceqs_f32 (float32_t a, float32_t b) --{ -- float32_t result; -- __asm__ ("fcmeq %s0,%s1,%s2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vceqzd_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcmeq %d0,%d1,#0" +- uint64x2_t result; +- __asm__ ("fcvtpu %0.2d, %1.2d" - : "=w"(result) - : "w"(a) - : /* No clobbers */); @@ -20645,22819 +15783,16199 @@ -} - -__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vceqzs_f32 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcmeq %s0,%s1,#0" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcge_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("fcmge %0.2s, %1.2s, %2.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vcge_f64 (float64x1_t a, float64x1_t b) --{ -- uint64x1_t result; -- __asm__ ("fcmge %d0, %d1, %d2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcgeq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("fcmge %0.4s, %1.4s, %2.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcgeq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("fcmge %0.2d, %1.2d, %2.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcgt_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("fcmgt %0.2s, %1.2s, %2.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vcgt_f64 (float64x1_t a, float64x1_t b) --{ -- uint64x1_t result; -- __asm__ ("fcmgt %d0, %d1, %d2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcgtq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("fcmgt %0.4s, %1.4s, %2.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcgtq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("fcmgt %0.2d, %1.2d, %2.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcle_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("fcmge %0.2s, %2.2s, %1.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vcle_f64 (float64x1_t a, float64x1_t b) --{ -- uint64x1_t result; -- __asm__ ("fcmge %d0, %d2, %d1" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcleq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("fcmge %0.4s, %2.4s, %1.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcleq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("fcmge %0.2d, %2.2d, %1.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vcls_s8 (int8x8_t a) - { -@@ -5513,50 +5043,6 @@ - return result; - } - --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vclt_f32 (float32x2_t a, float32x2_t b) --{ -- uint32x2_t result; -- __asm__ ("fcmgt %0.2s, %2.2s, %1.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vclt_f64 (float64x1_t a, float64x1_t b) --{ -- uint64x1_t result; -- __asm__ ("fcmgt %d0, %d2, %d1" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcltq_f32 (float32x4_t a, float32x4_t b) --{ -- uint32x4_t result; -- __asm__ ("fcmgt %0.4s, %2.4s, %1.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcltq_f64 (float64x2_t a, float64x2_t b) --{ -- uint64x2_t result; -- __asm__ ("fcmgt %0.2d, %2.2d, %1.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vclz_s8 (int8x8_t a) - { -@@ -5915,72 +5401,6 @@ - - /* vcvt_f32_f16 not supported */ - --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vcvt_f32_f64 (float64x2_t a) --{ -- float32x2_t result; -- __asm__ ("fcvtn %0.2s,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vcvt_f32_s32 (int32x2_t a) --{ -- float32x2_t result; -- __asm__ ("scvtf %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vcvt_f32_u32 (uint32x2_t a) --{ -- float32x2_t result; -- __asm__ ("ucvtf %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vcvt_f64_f32 (float32x2_t a) --{ -- float64x2_t result; -- __asm__ ("fcvtl %0.2d,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) --vcvt_f64_s64 (uint64x1_t a) --{ -- float64x1_t result; -- __asm__ ("scvtf %d0, %d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) --vcvt_f64_u64 (uint64x1_t a) --{ -- float64x1_t result; -- __asm__ ("ucvtf %d0, %d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - /* vcvt_high_f16_f32 not supported */ - - /* vcvt_high_f32_f16 not supported */ -@@ -5987,28 +5407,6 @@ - - static float32x2_t vdup_n_f32 (float32_t); - --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vcvt_high_f32_f64 (float32x2_t a, float64x2_t b) --{ -- float32x4_t result = vcombine_f32 (a, vdup_n_f32 (0.0f)); -- __asm__ ("fcvtn2 %0.4s,%2.2d" -- : "+w"(result) -- : "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vcvt_high_f64_f32 (float32x4_t a) --{ -- float64x2_t result; -- __asm__ ("fcvtl2 %0.2d,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - #define vcvt_n_f32_s32(a, b) \ - __extension__ \ - ({ \ -@@ -6057,160 +5455,6 @@ - result; \ - }) - --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vcvt_s32_f32 (float32x2_t a) --{ -- int32x2_t result; -- __asm__ ("fcvtzs %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcvt_u32_f32 (float32x2_t a) --{ -- uint32x2_t result; -- __asm__ ("fcvtzu %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vcvta_s32_f32 (float32x2_t a) --{ -- int32x2_t result; -- __asm__ ("fcvtas %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcvta_u32_f32 (float32x2_t a) --{ -- uint32x2_t result; -- __asm__ ("fcvtau %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtad_s64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtas %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtad_u64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtau %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vcvtaq_s32_f32 (float32x4_t a) --{ -- int32x4_t result; -- __asm__ ("fcvtas %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vcvtaq_s64_f64 (float64x2_t a) --{ -- int64x2_t result; -- __asm__ ("fcvtas %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcvtaq_u32_f32 (float32x4_t a) --{ -- uint32x4_t result; -- __asm__ ("fcvtau %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcvtaq_u64_f64 (float64x2_t a) --{ -- uint64x2_t result; -- __asm__ ("fcvtau %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtas_s64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtas %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtas_u64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtau %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64_t __attribute__ ((__always_inline__)) --vcvtd_f64_s64 (int64_t a) --{ -- int64_t result; -- __asm__ ("scvtf %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) --vcvtd_f64_u64 (uint64_t a) --{ -- uint64_t result; -- __asm__ ("ucvtf %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - #define vcvtd_n_f64_s64(a, b) \ - __extension__ \ - ({ \ -@@ -6259,402 +5503,6 @@ - result; \ - }) - --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtd_s64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtzs %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtd_u64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtzu %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vcvtm_s32_f32 (float32x2_t a) --{ -- int32x2_t result; -- __asm__ ("fcvtms %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcvtm_u32_f32 (float32x2_t a) --{ -- uint32x2_t result; -- __asm__ ("fcvtmu %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtmd_s64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtms %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtmd_u64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtmu %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vcvtmq_s32_f32 (float32x4_t a) --{ -- int32x4_t result; -- __asm__ ("fcvtms %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vcvtmq_s64_f64 (float64x2_t a) --{ -- int64x2_t result; -- __asm__ ("fcvtms %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcvtmq_u32_f32 (float32x4_t a) --{ -- uint32x4_t result; -- __asm__ ("fcvtmu %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcvtmq_u64_f64 (float64x2_t a) --{ -- uint64x2_t result; -- __asm__ ("fcvtmu %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtms_s64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtms %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtms_u64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtmu %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vcvtn_s32_f32 (float32x2_t a) --{ -- int32x2_t result; -- __asm__ ("fcvtns %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcvtn_u32_f32 (float32x2_t a) --{ -- uint32x2_t result; -- __asm__ ("fcvtnu %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtnd_s64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtns %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtnd_u64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtnu %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vcvtnq_s32_f32 (float32x4_t a) --{ -- int32x4_t result; -- __asm__ ("fcvtns %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vcvtnq_s64_f64 (float64x2_t a) --{ -- int64x2_t result; -- __asm__ ("fcvtns %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcvtnq_u32_f32 (float32x4_t a) --{ -- uint32x4_t result; -- __asm__ ("fcvtnu %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcvtnq_u64_f64 (float64x2_t a) --{ -- uint64x2_t result; -- __asm__ ("fcvtnu %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtns_s64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtns %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtns_u64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtnu %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vcvtp_s32_f32 (float32x2_t a) --{ -- int32x2_t result; -- __asm__ ("fcvtps %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vcvtp_u32_f32 (float32x2_t a) --{ -- uint32x2_t result; -- __asm__ ("fcvtpu %0.2s, %1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtpd_s64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtps %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vcvtpd_u64_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("fcvtpu %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vcvtpq_s32_f32 (float32x4_t a) --{ -- int32x4_t result; -- __asm__ ("fcvtps %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vcvtpq_s64_f64 (float64x2_t a) --{ -- int64x2_t result; -- __asm__ ("fcvtps %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcvtpq_u32_f32 (float32x4_t a) --{ -- uint32x4_t result; -- __asm__ ("fcvtpu %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcvtpq_u64_f64 (float64x2_t a) --{ -- uint64x2_t result; -- __asm__ ("fcvtpu %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtps_s64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtps %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvtps_u64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtpu %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vcvtq_f32_s32 (int32x4_t a) --{ -- float32x4_t result; -- __asm__ ("scvtf %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vcvtq_f32_u32 (uint32x4_t a) --{ -- float32x4_t result; -- __asm__ ("ucvtf %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vcvtq_f64_s64 (int64x2_t a) --{ -- float64x2_t result; -- __asm__ ("scvtf %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vcvtq_f64_u64 (uint64x2_t a) --{ -- float64x2_t result; -- __asm__ ("ucvtf %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - #define vcvtq_n_f32_s32(a, b) \ - __extension__ \ - ({ \ -@@ -6751,72 +5599,6 @@ - result; \ - }) - --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vcvtq_s32_f32 (float32x4_t a) --{ -- int32x4_t result; -- __asm__ ("fcvtzs %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vcvtq_s64_f64 (float64x2_t a) --{ -- int64x2_t result; -- __asm__ ("fcvtzs %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vcvtq_u32_f32 (float32x4_t a) --{ -- uint32x4_t result; -- __asm__ ("fcvtzu %0.4s, %1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vcvtq_u64_f64 (float64x2_t a) --{ -- uint64x2_t result; -- __asm__ ("fcvtzu %0.2d, %1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32_t __attribute__ ((__always_inline__)) --vcvts_f64_s32 (int32_t a) --{ -- int32_t result; -- __asm__ ("scvtf %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) --vcvts_f64_u32 (uint32_t a) --{ -- uint32_t result; -- __asm__ ("ucvtf %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - #define vcvts_n_f32_s32(a, b) \ - __extension__ \ - ({ \ -@@ -6865,28 +5647,6 @@ - result; \ - }) - --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvts_s64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtzs %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vcvts_u64_f64 (float32_t a) --{ -- float32_t result; -- __asm__ ("fcvtzu %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) - vcvtx_f32_f64 (float64x2_t a) - { -@@ -8110,151 +6870,7 @@ - return result; - } - --#define vget_lane_f64(a, b) \ -- __extension__ \ -- ({ \ -- float64x1_t a_ = (a); \ -- float64_t result; \ -- __asm__ ("umov %x0, %1.d[%2]" \ -- : "=r"(result) \ -- : "w"(a_), "i"(b) \ -- : /* No clobbers */); \ -- result; \ -- }) -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vget_low_f32 (float32x4_t a) --{ -- float32x2_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) --vget_low_f64 (float64x2_t a) --{ -- float64x1_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vget_low_p8 (poly8x16_t a) --{ -- poly8x8_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) --vget_low_p16 (poly16x8_t a) --{ -- poly16x4_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vget_low_s8 (int8x16_t a) --{ -- int8x8_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vget_low_s16 (int16x8_t a) --{ -- int16x4_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vget_low_s32 (int32x4_t a) --{ -- int32x2_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) --vget_low_s64 (int64x2_t a) --{ -- int64x1_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vget_low_u8 (uint8x16_t a) --{ -- uint8x8_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vget_low_u16 (uint16x8_t a) --{ -- uint16x4_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vget_low_u32 (uint32x4_t a) --{ -- uint32x2_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vget_low_u64 (uint64x2_t a) --{ -- uint64x1_t result; -- __asm__ ("ins %0.d[0], %1.d[0]" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vhsub_s8 (int8x8_t a, int8x8_t b) - { - int8x8_t result; -@@ -8962,303 +7578,6 @@ - result; \ - }) - --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vmaxnm_f32 (float32x2_t a, float32x2_t b) --{ -- float32x2_t result; -- __asm__ ("fmaxnm %0.2s,%1.2s,%2.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vmaxnmq_f32 (float32x4_t a, float32x4_t b) --{ -- float32x4_t result; -- __asm__ ("fmaxnm %0.4s,%1.4s,%2.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vmaxnmq_f64 (float64x2_t a, float64x2_t b) --{ -- float64x2_t result; -- __asm__ ("fmaxnm %0.2d,%1.2d,%2.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vmaxnmvq_f32 (float32x4_t a) --{ -- float32_t result; -- __asm__ ("fmaxnmv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int8_t __attribute__ ((__always_inline__)) --vmaxv_s8 (int8x8_t a) --{ -- int8_t result; -- __asm__ ("smaxv %b0,%1.8b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16_t __attribute__ ((__always_inline__)) --vmaxv_s16 (int16x4_t a) --{ -- int16_t result; -- __asm__ ("smaxv %h0,%1.4h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) --vmaxv_u8 (uint8x8_t a) --{ -- uint8_t result; -- __asm__ ("umaxv %b0,%1.8b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) --vmaxv_u16 (uint16x4_t a) --{ -- uint16_t result; -- __asm__ ("umaxv %h0,%1.4h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vmaxvq_f32 (float32x4_t a) --{ -- float32_t result; -- __asm__ ("fmaxv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int8_t __attribute__ ((__always_inline__)) --vmaxvq_s8 (int8x16_t a) --{ -- int8_t result; -- __asm__ ("smaxv %b0,%1.16b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16_t __attribute__ ((__always_inline__)) --vmaxvq_s16 (int16x8_t a) --{ -- int16_t result; -- __asm__ ("smaxv %h0,%1.8h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32_t __attribute__ ((__always_inline__)) --vmaxvq_s32 (int32x4_t a) --{ -- int32_t result; -- __asm__ ("smaxv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) --vmaxvq_u8 (uint8x16_t a) --{ -- uint8_t result; -- __asm__ ("umaxv %b0,%1.16b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) --vmaxvq_u16 (uint16x8_t a) --{ -- uint16_t result; -- __asm__ ("umaxv %h0,%1.8h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) --vmaxvq_u32 (uint32x4_t a) --{ -- uint32_t result; -- __asm__ ("umaxv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vminnmvq_f32 (float32x4_t a) --{ -- float32_t result; -- __asm__ ("fminnmv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int8_t __attribute__ ((__always_inline__)) --vminv_s8 (int8x8_t a) --{ -- int8_t result; -- __asm__ ("sminv %b0,%1.8b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16_t __attribute__ ((__always_inline__)) --vminv_s16 (int16x4_t a) --{ -- int16_t result; -- __asm__ ("sminv %h0,%1.4h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) --vminv_u8 (uint8x8_t a) --{ -- uint8_t result; -- __asm__ ("uminv %b0,%1.8b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) --vminv_u16 (uint16x4_t a) --{ -- uint16_t result; -- __asm__ ("uminv %h0,%1.4h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vminvq_f32 (float32x4_t a) --{ -- float32_t result; -- __asm__ ("fminv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int8_t __attribute__ ((__always_inline__)) --vminvq_s8 (int8x16_t a) --{ -- int8_t result; -- __asm__ ("sminv %b0,%1.16b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int16_t __attribute__ ((__always_inline__)) --vminvq_s16 (int16x8_t a) --{ -- int16_t result; -- __asm__ ("sminv %h0,%1.8h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline int32_t __attribute__ ((__always_inline__)) --vminvq_s32 (int32x4_t a) --{ -- int32_t result; -- __asm__ ("sminv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) --vminvq_u8 (uint8x16_t a) --{ -- uint8_t result; -- __asm__ ("uminv %b0,%1.16b" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) --vminvq_u16 (uint16x8_t a) --{ -- uint16_t result; -- __asm__ ("uminv %h0,%1.8h" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) --vminvq_u32 (uint32x4_t a) --{ -- uint32_t result; -- __asm__ ("uminv %s0,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - #define vmla_lane_f32(a, b, c, d) \ - __extension__ \ - ({ \ -@@ -11382,7 +9701,7 @@ - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vmovn_high_s16 (int8x8_t a, int16x8_t b) - { -- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); -+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("xtn2 %0.16b,%1.8h" - : "+w"(result) - : "w"(b) -@@ -11393,7 +9712,7 @@ - __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) - vmovn_high_s32 (int16x4_t a, int32x4_t b) - { -- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); -+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("xtn2 %0.8h,%1.4s" - : "+w"(result) - : "w"(b) -@@ -11404,7 +9723,7 @@ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vmovn_high_s64 (int32x2_t a, int64x2_t b) - { -- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); -+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("xtn2 %0.4s,%1.2d" - : "+w"(result) - : "w"(b) -@@ -11415,7 +9734,7 @@ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vmovn_high_u16 (uint8x8_t a, uint16x8_t b) - { -- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); -+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("xtn2 %0.16b,%1.8h" - : "+w"(result) - : "w"(b) -@@ -11426,7 +9745,7 @@ - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) - vmovn_high_u32 (uint16x4_t a, uint32x4_t b) - { -- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); -+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("xtn2 %0.8h,%1.4s" - : "+w"(result) - : "w"(b) -@@ -11437,7 +9756,7 @@ - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vmovn_high_u64 (uint32x2_t a, uint64x2_t b) - { -- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); -+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("xtn2 %0.4s,%1.2d" - : "+w"(result) - : "w"(b) -@@ -13856,7 +12175,7 @@ - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vqmovn_high_s16 (int8x8_t a, int16x8_t b) - { -- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); -+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("sqxtn2 %0.16b, %1.8h" - : "+w"(result) - : "w"(b) -@@ -13867,7 +12186,7 @@ - __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) - vqmovn_high_s32 (int16x4_t a, int32x4_t b) - { -- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); -+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("sqxtn2 %0.8h, %1.4s" - : "+w"(result) - : "w"(b) -@@ -13878,7 +12197,7 @@ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vqmovn_high_s64 (int32x2_t a, int64x2_t b) - { -- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); -+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("sqxtn2 %0.4s, %1.2d" - : "+w"(result) - : "w"(b) -@@ -13889,7 +12208,7 @@ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vqmovn_high_u16 (uint8x8_t a, uint16x8_t b) - { -- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); -+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("uqxtn2 %0.16b, %1.8h" - : "+w"(result) - : "w"(b) -@@ -13900,7 +12219,7 @@ - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) - vqmovn_high_u32 (uint16x4_t a, uint32x4_t b) - { -- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); -+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("uqxtn2 %0.8h, %1.4s" - : "+w"(result) - : "w"(b) -@@ -13911,7 +12230,7 @@ - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vqmovn_high_u64 (uint32x2_t a, uint64x2_t b) - { -- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); -+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("uqxtn2 %0.4s, %1.2d" - : "+w"(result) - : "w"(b) -@@ -13922,7 +12241,7 @@ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vqmovun_high_s16 (uint8x8_t a, int16x8_t b) - { -- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); -+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("sqxtun2 %0.16b, %1.8h" - : "+w"(result) - : "w"(b) -@@ -13933,7 +12252,7 @@ - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) - vqmovun_high_s32 (uint16x4_t a, int32x4_t b) - { -- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); -+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("sqxtun2 %0.8h, %1.4s" - : "+w"(result) - : "w"(b) -@@ -13944,7 +12263,7 @@ - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vqmovun_high_s64 (uint32x2_t a, int64x2_t b) - { -- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); -+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("sqxtun2 %0.4s, %1.2d" - : "+w"(result) - : "w"(b) -@@ -14002,7 +12321,8 @@ - int16x8_t b_ = (b); \ - int8x8_t a_ = (a); \ - int8x16_t result = vcombine_s8 \ -- (a_, vcreate_s8 (UINT64_C (0x0))); \ -+ (a_, vcreate_s8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqrshrn2 %0.16b, %1.8h, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14016,7 +12336,8 @@ - int32x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x8_t result = vcombine_s16 \ -- (a_, vcreate_s16 (UINT64_C (0x0))); \ -+ (a_, vcreate_s16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqrshrn2 %0.8h, %1.4s, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14030,7 +12351,8 @@ - int64x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x4_t result = vcombine_s32 \ -- (a_, vcreate_s32 (UINT64_C (0x0))); \ -+ (a_, vcreate_s32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqrshrn2 %0.4s, %1.2d, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14044,7 +12366,8 @@ - uint16x8_t b_ = (b); \ - uint8x8_t a_ = (a); \ - uint8x16_t result = vcombine_u8 \ -- (a_, vcreate_u8 (UINT64_C (0x0))); \ -+ (a_, vcreate_u8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("uqrshrn2 %0.16b, %1.8h, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14058,7 +12381,8 @@ - uint32x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x8_t result = vcombine_u16 \ -- (a_, vcreate_u16 (UINT64_C (0x0))); \ -+ (a_, vcreate_u16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("uqrshrn2 %0.8h, %1.4s, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14072,7 +12396,8 @@ - uint64x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x4_t result = vcombine_u32 \ -- (a_, vcreate_u32 (UINT64_C (0x0))); \ -+ (a_, vcreate_u32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("uqrshrn2 %0.4s, %1.2d, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14086,7 +12411,8 @@ - int16x8_t b_ = (b); \ - uint8x8_t a_ = (a); \ - uint8x16_t result = vcombine_u8 \ -- (a_, vcreate_u8 (UINT64_C (0x0))); \ -+ (a_, vcreate_u8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqrshrun2 %0.16b, %1.8h, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14100,7 +12426,8 @@ - int32x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x8_t result = vcombine_u16 \ -- (a_, vcreate_u16 (UINT64_C (0x0))); \ -+ (a_, vcreate_u16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqrshrun2 %0.8h, %1.4s, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14114,7 +12441,8 @@ - int64x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x4_t result = vcombine_u32 \ -- (a_, vcreate_u32 (UINT64_C (0x0))); \ -+ (a_, vcreate_u32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqrshrun2 %0.4s, %1.2d, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14128,7 +12456,8 @@ - int16x8_t b_ = (b); \ - int8x8_t a_ = (a); \ - int8x16_t result = vcombine_s8 \ -- (a_, vcreate_s8 (UINT64_C (0x0))); \ -+ (a_, vcreate_s8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqshrn2 %0.16b, %1.8h, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14142,7 +12471,8 @@ - int32x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x8_t result = vcombine_s16 \ -- (a_, vcreate_s16 (UINT64_C (0x0))); \ -+ (a_, vcreate_s16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqshrn2 %0.8h, %1.4s, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14156,7 +12486,8 @@ - int64x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x4_t result = vcombine_s32 \ -- (a_, vcreate_s32 (UINT64_C (0x0))); \ -+ (a_, vcreate_s32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqshrn2 %0.4s, %1.2d, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14170,7 +12501,8 @@ - uint16x8_t b_ = (b); \ - uint8x8_t a_ = (a); \ - uint8x16_t result = vcombine_u8 \ -- (a_, vcreate_u8 (UINT64_C (0x0))); \ -+ (a_, vcreate_u8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("uqshrn2 %0.16b, %1.8h, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14184,7 +12516,8 @@ - uint32x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x8_t result = vcombine_u16 \ -- (a_, vcreate_u16 (UINT64_C (0x0))); \ -+ (a_, vcreate_u16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("uqshrn2 %0.8h, %1.4s, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14198,7 +12531,8 @@ - uint64x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x4_t result = vcombine_u32 \ -- (a_, vcreate_u32 (UINT64_C (0x0))); \ -+ (a_, vcreate_u32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("uqshrn2 %0.4s, %1.2d, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14212,7 +12546,8 @@ - int16x8_t b_ = (b); \ - uint8x8_t a_ = (a); \ - uint8x16_t result = vcombine_u8 \ -- (a_, vcreate_u8 (UINT64_C (0x0))); \ -+ (a_, vcreate_u8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqshrun2 %0.16b, %1.8h, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14226,7 +12561,8 @@ - int32x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x8_t result = vcombine_u16 \ -- (a_, vcreate_u16 (UINT64_C (0x0))); \ -+ (a_, vcreate_u16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqshrun2 %0.8h, %1.4s, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14240,7 +12576,8 @@ - int64x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x4_t result = vcombine_u32 \ -- (a_, vcreate_u32 (UINT64_C (0x0))); \ -+ (a_, vcreate_u32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("sqshrun2 %0.4s, %1.2d, #%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -14292,17 +12629,6 @@ - return result; - } - --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vrecpe_f32 (float32x2_t a) --{ -- float32x2_t result; -- __asm__ ("frecpe %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) - vrecpe_u32 (uint32x2_t a) - { -@@ -14314,39 +12640,6 @@ - return result; - } - --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vrecped_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("frecpe %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vrecpeq_f32 (float32x4_t a) --{ -- float32x4_t result; -- __asm__ ("frecpe %0.4s,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vrecpeq_f64 (float64x2_t a) --{ -- float64x2_t result; -- __asm__ ("frecpe %0.2d,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vrecpeq_u32 (uint32x4_t a) - { -@@ -14358,94 +12651,6 @@ - return result; - } - --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vrecpes_f32 (float32_t a) --{ -- float32_t result; -- __asm__ ("frecpe %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vrecps_f32 (float32x2_t a, float32x2_t b) --{ -- float32x2_t result; -- __asm__ ("frecps %0.2s,%1.2s,%2.2s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vrecpsd_f64 (float64_t a, float64_t b) --{ -- float64_t result; -- __asm__ ("frecps %d0,%d1,%d2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vrecpsq_f32 (float32x4_t a, float32x4_t b) --{ -- float32x4_t result; -- __asm__ ("frecps %0.4s,%1.4s,%2.4s" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vrecpsq_f64 (float64x2_t a, float64x2_t b) --{ -- float64x2_t result; -- __asm__ ("frecps %0.2d,%1.2d,%2.2d" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vrecpss_f32 (float32_t a, float32_t b) --{ -- float32_t result; -- __asm__ ("frecps %s0,%s1,%s2" -- : "=w"(result) -- : "w"(a), "w"(b) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vrecpxd_f64 (float64_t a) --{ -- float64_t result; -- __asm__ ("frecpe %d0,%d1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vrecpxs_f32 (float32_t a) --{ -- float32_t result; -- __asm__ ("frecpe %s0,%s1" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) - vrev16_p8 (poly8x8_t a) - { -@@ -14842,171 +13047,6 @@ - return result; - } - --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vrnd_f32 (float32x2_t a) --{ -- float32x2_t result; -- __asm__ ("frintz %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vrnda_f32 (float32x2_t a) --{ -- float32x2_t result; -- __asm__ ("frinta %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vrndm_f32 (float32x2_t a) --{ -- float32x2_t result; -- __asm__ ("frintm %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vrndn_f32 (float32x2_t a) --{ -- float32x2_t result; -- __asm__ ("frintn %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vrndp_f32 (float32x2_t a) --{ -- float32x2_t result; -- __asm__ ("frintp %0.2s,%1.2s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vrndq_f32 (float32x4_t a) --{ -- float32x4_t result; -- __asm__ ("frintz %0.4s,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vrndq_f64 (float64x2_t a) --{ -- float64x2_t result; -- __asm__ ("frintz %0.2d,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vrndqa_f32 (float32x4_t a) --{ -- float32x4_t result; -- __asm__ ("frinta %0.4s,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vrndqa_f64 (float64x2_t a) --{ -- float64x2_t result; -- __asm__ ("frinta %0.2d,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vrndqm_f32 (float32x4_t a) --{ -- float32x4_t result; -- __asm__ ("frintm %0.4s,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vrndqm_f64 (float64x2_t a) --{ -- float64x2_t result; -- __asm__ ("frintm %0.2d,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vrndqn_f32 (float32x4_t a) --{ -- float32x4_t result; -- __asm__ ("frintn %0.4s,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vrndqn_f64 (float64x2_t a) --{ -- float64x2_t result; -- __asm__ ("frintn %0.2d,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vrndqp_f32 (float32x4_t a) --{ -- float32x4_t result; -- __asm__ ("frintp %0.4s,%1.4s" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- --__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) --vrndqp_f64 (float64x2_t a) --{ -- float64x2_t result; -- __asm__ ("frintp %0.2d,%1.2d" -- : "=w"(result) -- : "w"(a) -- : /* No clobbers */); -- return result; --} -- - #define vrshrn_high_n_s16(a, b, c) \ - __extension__ \ - ({ \ -@@ -15013,7 +13053,8 @@ - int16x8_t b_ = (b); \ - int8x8_t a_ = (a); \ - int8x16_t result = vcombine_s8 \ -- (a_, vcreate_s8 (UINT64_C (0x0))); \ -+ (a_, vcreate_s8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("rshrn2 %0.16b,%1.8h,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15027,7 +13068,8 @@ - int32x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x8_t result = vcombine_s16 \ -- (a_, vcreate_s16 (UINT64_C (0x0))); \ -+ (a_, vcreate_s16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("rshrn2 %0.8h,%1.4s,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15041,7 +13083,8 @@ - int64x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x4_t result = vcombine_s32 \ -- (a_, vcreate_s32 (UINT64_C (0x0))); \ -+ (a_, vcreate_s32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("rshrn2 %0.4s,%1.2d,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15055,7 +13098,8 @@ - uint16x8_t b_ = (b); \ - uint8x8_t a_ = (a); \ - uint8x16_t result = vcombine_u8 \ -- (a_, vcreate_u8 (UINT64_C (0x0))); \ -+ (a_, vcreate_u8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("rshrn2 %0.16b,%1.8h,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15069,7 +13113,8 @@ - uint32x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x8_t result = vcombine_u16 \ -- (a_, vcreate_u16 (UINT64_C (0x0))); \ -+ (a_, vcreate_u16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("rshrn2 %0.8h,%1.4s,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15083,7 +13128,8 @@ - uint64x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x4_t result = vcombine_u32 \ -- (a_, vcreate_u32 (UINT64_C (0x0))); \ -+ (a_, vcreate_u32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("rshrn2 %0.4s,%1.2d,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15320,7 +13366,7 @@ - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vrsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c) - { -- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); -+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("rsubhn2 %0.16b, %1.8h, %2.8h" - : "+w"(result) - : "w"(b), "w"(c) -@@ -15331,7 +13377,7 @@ - __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) - vrsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c) - { -- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); -+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("rsubhn2 %0.8h, %1.4s, %2.4s" - : "+w"(result) - : "w"(b), "w"(c) -@@ -15342,7 +13388,7 @@ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vrsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c) - { -- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); -+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("rsubhn2 %0.4s, %1.2d, %2.2d" - : "+w"(result) - : "w"(b), "w"(c) -@@ -15353,7 +13399,7 @@ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vrsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c) - { -- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); -+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("rsubhn2 %0.16b, %1.8h, %2.8h" - : "+w"(result) - : "w"(b), "w"(c) -@@ -15364,7 +13410,7 @@ - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) - vrsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c) - { -- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); -+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("rsubhn2 %0.8h, %1.4s, %2.4s" - : "+w"(result) - : "w"(b), "w"(c) -@@ -15375,7 +13421,7 @@ - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vrsubhn_high_u64 (uint32x2_t a, uint64x2_t b, uint64x2_t c) - { -- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); -+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("rsubhn2 %0.4s, %1.2d, %2.2d" - : "+w"(result) - : "w"(b), "w"(c) -@@ -15767,7 +13813,8 @@ - int16x8_t b_ = (b); \ - int8x8_t a_ = (a); \ - int8x16_t result = vcombine_s8 \ -- (a_, vcreate_s8 (UINT64_C (0x0))); \ -+ (a_, vcreate_s8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("shrn2 %0.16b,%1.8h,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15781,7 +13828,8 @@ - int32x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x8_t result = vcombine_s16 \ -- (a_, vcreate_s16 (UINT64_C (0x0))); \ -+ (a_, vcreate_s16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("shrn2 %0.8h,%1.4s,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15795,7 +13843,8 @@ - int64x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x4_t result = vcombine_s32 \ -- (a_, vcreate_s32 (UINT64_C (0x0))); \ -+ (a_, vcreate_s32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("shrn2 %0.4s,%1.2d,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15809,7 +13858,8 @@ - uint16x8_t b_ = (b); \ - uint8x8_t a_ = (a); \ - uint8x16_t result = vcombine_u8 \ -- (a_, vcreate_u8 (UINT64_C (0x0))); \ -+ (a_, vcreate_u8 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("shrn2 %0.16b,%1.8h,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15823,7 +13873,8 @@ - uint32x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x8_t result = vcombine_u16 \ -- (a_, vcreate_u16 (UINT64_C (0x0))); \ -+ (a_, vcreate_u16 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("shrn2 %0.8h,%1.4s,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -15837,7 +13888,8 @@ - uint64x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x4_t result = vcombine_u32 \ -- (a_, vcreate_u32 (UINT64_C (0x0))); \ -+ (a_, vcreate_u32 \ -+ (__AARCH64_UINT64_C (0x0))); \ - __asm__ ("shrn2 %0.4s,%1.2d,#%2" \ - : "+w"(result) \ - : "w"(b_), "i"(c) \ -@@ -16289,7 +14341,7 @@ - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c) - { -- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); -+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("subhn2 %0.16b, %1.8h, %2.8h" - : "+w"(result) - : "w"(b), "w"(c) -@@ -16300,7 +14352,7 @@ - __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) - vsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c) - { -- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); -+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("subhn2 %0.8h, %1.4s, %2.4s" - : "+w"(result) - : "w"(b), "w"(c) -@@ -16311,7 +14363,7 @@ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c) - { -- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); -+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("subhn2 %0.4s, %1.2d, %2.2d" - : "+w"(result) - : "w"(b), "w"(c) -@@ -16322,7 +14374,7 @@ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c) - { -- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); -+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("subhn2 %0.16b, %1.8h, %2.8h" - : "+w"(result) - : "w"(b), "w"(c) -@@ -16333,7 +14385,7 @@ - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) - vsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c) - { -- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); -+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); - __asm__ ("subhn2 %0.8h, %1.4s, %2.4s" - : "+w"(result) - : "w"(b), "w"(c) -@@ -16344,7 +14396,7 @@ - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vsubhn_high_u64 (uint32x2_t a, uint64x2_t b, uint64x2_t c) - { -- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); -+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); - __asm__ ("subhn2 %0.4s, %1.2d, %2.2d" - : "+w"(result) - : "w"(b), "w"(c) -@@ -18309,86 +16361,6 @@ - return result; - } - --__extension__ static __inline int32_t __attribute__ ((__always_inline__)) --vaddv_s32 (int32x2_t a) --{ -- int32_t result; -- __asm__ ("addp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) --vaddv_u32 (uint32x2_t a) --{ -- uint32_t result; -- __asm__ ("addp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vmaxnmv_f32 (float32x2_t a) --{ -- float32_t result; -- __asm__ ("fmaxnmp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline float32_t __attribute__ ((__always_inline__)) --vminnmv_f32 (float32x2_t a) --{ -- float32_t result; -- __asm__ ("fminnmp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vmaxnmvq_f64 (float64x2_t a) --{ -- float64_t result; -- __asm__ ("fmaxnmp %0.2d, %1.2d, %1.2d" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline int32_t __attribute__ ((__always_inline__)) --vmaxv_s32 (int32x2_t a) --{ -- int32_t result; -- __asm__ ("smaxp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) --vmaxv_u32 (uint32x2_t a) --{ -- uint32_t result; -- __asm__ ("umaxp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline float64_t __attribute__ ((__always_inline__)) --vminnmvq_f64 (float64x2_t a) --{ -- float64_t result; -- __asm__ ("fminnmp %0.2d, %1.2d, %1.2d" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline int32_t __attribute__ ((__always_inline__)) --vminv_s32 (int32x2_t a) --{ -- int32_t result; -- __asm__ ("sminp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- --__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) --vminv_u32 (uint32x2_t a) --{ -- uint32_t result; -- __asm__ ("uminp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); -- return result; --} -- - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vpaddd_s64 (int64x2_t __a) - { -@@ -19022,7 +16994,7 @@ - vtbl1_s8 (int8x8_t tab, int8x8_t idx) - { - int8x8_t result; -- int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (UINT64_C (0x0))); -+ int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("tbl %0.8b, {%1.16b}, %2.8b" - : "=w"(result) - : "w"(temp), "w"(idx) -@@ -19034,7 +17006,7 @@ - vtbl1_u8 (uint8x8_t tab, uint8x8_t idx) - { - uint8x8_t result; -- uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (UINT64_C (0x0))); -+ uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("tbl %0.8b, {%1.16b}, %2.8b" - : "=w"(result) - : "w"(temp), "w"(idx) -@@ -19046,7 +17018,7 @@ - vtbl1_p8 (poly8x8_t tab, uint8x8_t idx) - { - poly8x8_t result; -- poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (UINT64_C (0x0))); -+ poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("tbl %0.8b, {%1.16b}, %2.8b" - : "=w"(result) - : "w"(temp), "w"(idx) -@@ -19096,7 +17068,7 @@ - int8x8_t result; - int8x16x2_t temp; - temp.val[0] = vcombine_s8 (tab.val[0], tab.val[1]); -- temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (UINT64_C (0x0))); -+ temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t" - "tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t" - : "=w"(result) -@@ -19111,7 +17083,7 @@ - uint8x8_t result; - uint8x16x2_t temp; - temp.val[0] = vcombine_u8 (tab.val[0], tab.val[1]); -- temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (UINT64_C (0x0))); -+ temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t" - "tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t" - : "=w"(result) -@@ -19126,7 +17098,7 @@ - poly8x8_t result; - poly8x16x2_t temp; - temp.val[0] = vcombine_p8 (tab.val[0], tab.val[1]); -- temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (UINT64_C (0x0))); -+ temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t" - "tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t" - : "=w"(result) -@@ -19185,7 +17157,7 @@ - { - int8x8_t result; - int8x8_t tmp1; -- int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (UINT64_C (0x0))); -+ int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("movi %0.8b, 8\n\t" - "cmhs %0.8b, %3.8b, %0.8b\n\t" - "tbl %1.8b, {%2.16b}, %3.8b\n\t" -@@ -19201,7 +17173,7 @@ - { - uint8x8_t result; - uint8x8_t tmp1; -- uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (UINT64_C (0x0))); -+ uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("movi %0.8b, 8\n\t" - "cmhs %0.8b, %3.8b, %0.8b\n\t" - "tbl %1.8b, {%2.16b}, %3.8b\n\t" -@@ -19217,7 +17189,7 @@ - { - poly8x8_t result; - poly8x8_t tmp1; -- poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (UINT64_C (0x0))); -+ poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("movi %0.8b, 8\n\t" - "cmhs %0.8b, %3.8b, %0.8b\n\t" - "tbl %1.8b, {%2.16b}, %3.8b\n\t" -@@ -19271,7 +17243,7 @@ - int8x8_t tmp1; - int8x16x2_t temp; - temp.val[0] = vcombine_s8 (tab.val[0], tab.val[1]); -- temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (UINT64_C (0x0))); -+ temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t" - "movi %0.8b, 24\n\t" - "cmhs %0.8b, %3.8b, %0.8b\n\t" -@@ -19290,7 +17262,7 @@ - uint8x8_t tmp1; - uint8x16x2_t temp; - temp.val[0] = vcombine_u8 (tab.val[0], tab.val[1]); -- temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (UINT64_C (0x0))); -+ temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t" - "movi %0.8b, 24\n\t" - "cmhs %0.8b, %3.8b, %0.8b\n\t" -@@ -19309,7 +17281,7 @@ - poly8x8_t tmp1; - poly8x16x2_t temp; - temp.val[0] = vcombine_p8 (tab.val[0], tab.val[1]); -- temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (UINT64_C (0x0))); -+ temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (__AARCH64_UINT64_C (0x0))); - __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t" - "movi %0.8b, 24\n\t" - "cmhs %0.8b, %3.8b, %0.8b\n\t" -@@ -19370,6 +17342,80 @@ - - /* Start of optimal implementations in approved order. */ - -+/* vabs */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vabs_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_absv2sf (__a); -+} -+ -+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) -+vabs_f64 (float64x1_t __a) -+{ -+ return __builtin_fabs (__a); -+} -+ -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vabs_s8 (int8x8_t __a) -+{ -+ return __builtin_aarch64_absv8qi (__a); -+} -+ -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vabs_s16 (int16x4_t __a) -+{ -+ return __builtin_aarch64_absv4hi (__a); -+} -+ -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vabs_s32 (int32x2_t __a) -+{ -+ return __builtin_aarch64_absv2si (__a); -+} -+ -+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -+vabs_s64 (int64x1_t __a) -+{ -+ return __builtin_llabs (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vabsq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_absv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vabsq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_absv2df (__a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vabsq_s8 (int8x16_t __a) -+{ -+ return __builtin_aarch64_absv16qi (__a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vabsq_s16 (int16x8_t __a) -+{ -+ return __builtin_aarch64_absv8hi (__a); -+} -+ -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vabsq_s32 (int32x4_t __a) -+{ -+ return __builtin_aarch64_absv4si (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vabsq_s64 (int64x2_t __a) -+{ -+ return __builtin_aarch64_absv2di (__a); -+} -+ - /* vadd */ - - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -@@ -19384,8 +17430,269 @@ - return __a + __b; - } - --/* vceq */ -+/* vaddv */ - -+__extension__ static __inline int8_t __attribute__ ((__always_inline__)) -+vaddv_s8 (int8x8_t __a) -+{ -+ return vget_lane_s8 (__builtin_aarch64_reduc_splus_v8qi (__a), 0); -+} -+ -+__extension__ static __inline int16_t __attribute__ ((__always_inline__)) -+vaddv_s16 (int16x4_t __a) -+{ -+ return vget_lane_s16 (__builtin_aarch64_reduc_splus_v4hi (__a), 0); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vaddv_s32 (int32x2_t __a) -+{ -+ return vget_lane_s32 (__builtin_aarch64_reduc_splus_v2si (__a), 0); -+} -+ -+__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -+vaddv_u8 (uint8x8_t __a) -+{ -+ return vget_lane_u8 ((uint8x8_t) -+ __builtin_aarch64_reduc_uplus_v8qi ((int8x8_t) __a), 0); -+} -+ -+__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -+vaddv_u16 (uint16x4_t __a) -+{ -+ return vget_lane_u16 ((uint16x4_t) -+ __builtin_aarch64_reduc_uplus_v4hi ((int16x4_t) __a), 0); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vaddv_u32 (uint32x2_t __a) -+{ -+ return vget_lane_u32 ((uint32x2_t) -+ __builtin_aarch64_reduc_uplus_v2si ((int32x2_t) __a), 0); -+} -+ -+__extension__ static __inline int8_t __attribute__ ((__always_inline__)) -+vaddvq_s8 (int8x16_t __a) -+{ -+ return vgetq_lane_s8 (__builtin_aarch64_reduc_splus_v16qi (__a), 0); -+} -+ -+__extension__ static __inline int16_t __attribute__ ((__always_inline__)) -+vaddvq_s16 (int16x8_t __a) -+{ -+ return vgetq_lane_s16 (__builtin_aarch64_reduc_splus_v8hi (__a), 0); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vaddvq_s32 (int32x4_t __a) -+{ -+ return vgetq_lane_s32 (__builtin_aarch64_reduc_splus_v4si (__a), 0); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vaddvq_s64 (int64x2_t __a) -+{ -+ return vgetq_lane_s64 (__builtin_aarch64_reduc_splus_v2di (__a), 0); -+} -+ -+__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -+vaddvq_u8 (uint8x16_t __a) -+{ -+ return vgetq_lane_u8 ((uint8x16_t) -+ __builtin_aarch64_reduc_uplus_v16qi ((int8x16_t) __a), 0); -+} -+ -+__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -+vaddvq_u16 (uint16x8_t __a) -+{ -+ return vgetq_lane_u16 ((uint16x8_t) -+ __builtin_aarch64_reduc_uplus_v8hi ((int16x8_t) __a), 0); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vaddvq_u32 (uint32x4_t __a) -+{ -+ return vgetq_lane_u32 ((uint32x4_t) -+ __builtin_aarch64_reduc_uplus_v4si ((int32x4_t) __a), 0); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vaddvq_u64 (uint64x2_t __a) -+{ -+ return vgetq_lane_u64 ((uint64x2_t) -+ __builtin_aarch64_reduc_uplus_v2di ((int64x2_t) __a), 0); -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vaddv_f32 (float32x2_t __a) -+{ -+ float32x2_t t = __builtin_aarch64_reduc_splus_v2sf (__a); -+ return vget_lane_f32 (t, 0); -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vaddvq_f32 (float32x4_t __a) -+{ -+ float32x4_t t = __builtin_aarch64_reduc_splus_v4sf (__a); -+ return vgetq_lane_f32 (t, 0); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vaddvq_f64 (float64x2_t __a) -+{ -+ float64x2_t t = __builtin_aarch64_reduc_splus_v2df (__a); -+ return vgetq_lane_f64 (t, 0); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+ -+/* vaes */ -+ -+static __inline uint8x16_t -+vaeseq_u8 (uint8x16_t data, uint8x16_t key) -+{ -+ return __builtin_aarch64_crypto_aesev16qi_uuu (data, key); -+} -+ -+static __inline uint8x16_t -+__attribute__ ((__always_inline__)) -+vaesdq_u8 (uint8x16_t data, uint8x16_t key) -+{ -+ return __builtin_aarch64_crypto_aesdv16qi_uuu (data, key); -+} -+ -+static __inline uint8x16_t -+vaesmcq_u8 (uint8x16_t data) -+{ -+ return __builtin_aarch64_crypto_aesmcv16qi_uu (data); -+} -+ -+static __inline uint8x16_t -+vaesimcq_u8 (uint8x16_t data) -+{ -+ return __builtin_aarch64_crypto_aesimcv16qi_uu (data); -+} -+ -+#endif -+ -+/* vcage */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcages_f32 (float32_t __a, float32_t __b) -+{ -+ return __builtin_fabsf (__a) >= __builtin_fabsf (__b) ? -1 : 0; -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcage_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return vabs_f32 (__a) >= vabs_f32 (__b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcageq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return vabsq_f32 (__a) >= vabsq_f32 (__b); -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcaged_f64 (float64_t __a, float64_t __b) -+{ -+ return __builtin_fabs (__a) >= __builtin_fabs (__b) ? -1 : 0; -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcageq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return vabsq_f64 (__a) >= vabsq_f64 (__b); -+} -+ -+/* vcagt */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcagts_f32 (float32_t __a, float32_t __b) -+{ -+ return __builtin_fabsf (__a) > __builtin_fabsf (__b) ? -1 : 0; -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcagt_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return vabs_f32 (__a) > vabs_f32 (__b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcagtq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return vabsq_f32 (__a) > vabsq_f32 (__b); -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcagtd_f64 (float64_t __a, float64_t __b) -+{ -+ return __builtin_fabs (__a) > __builtin_fabs (__b) ? -1 : 0; -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcagtq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return vabsq_f64 (__a) > vabsq_f64 (__b); -+} -+ -+/* vcale */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcale_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return vabs_f32 (__a) <= vabs_f32 (__b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcaleq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return vabsq_f32 (__a) <= vabsq_f32 (__b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcaleq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return vabsq_f64 (__a) <= vabsq_f64 (__b); -+} -+ -+/* vcalt */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcalt_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return vabs_f32 (__a) < vabs_f32 (__b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcaltq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return vabsq_f32 (__a) < vabsq_f32 (__b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcaltq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return vabsq_f64 (__a) < vabsq_f64 (__b); -+} -+ -+/* vceq - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vceq_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return (uint32x2_t) __builtin_aarch64_cmeqv2sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vceq_f64 (float64x1_t __a, float64x1_t __b) -+{ -+ return __a == __b ? -1ll : 0ll; -+} -+ - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) - vceq_p8 (poly8x8_t __a, poly8x8_t __b) - { -@@ -19414,7 +17721,7 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vceq_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, __b); -+ return __a == __b ? -1ll : 0ll; - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -@@ -19441,10 +17748,21 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vceq_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmeqdi ((int64x1_t) __a, -- (int64x1_t) __b); -+ return __a == __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vceqq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return (uint32x4_t) __builtin_aarch64_cmeqv4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vceqq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return (uint64x2_t) __builtin_aarch64_cmeqv2df (__a, __b); -+} -+ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vceqq_p8 (poly8x16_t __a, poly8x16_t __b) - { -@@ -19504,27 +17822,245 @@ - (int64x2_t) __b); - } - -+/* vceq - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vceqs_f32 (float32_t __a, float32_t __b) -+{ -+ return __a == __b ? -1 : 0; -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vceqd_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, __b); -+ return __a == __b ? -1ll : 0ll; - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vceqd_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, __b); -+ return __a == __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vceqd_f64 (float64_t __a, float64_t __b) -+{ -+ return __a == __b ? -1ll : 0ll; -+} -+ -+/* vceqz - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vceqz_f32 (float32x2_t __a) -+{ -+ float32x2_t __b = {0.0f, 0.0f}; -+ return (uint32x2_t) __builtin_aarch64_cmeqv2sf (__a, __b); -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vceqz_f64 (float64x1_t __a) -+{ -+ return __a == 0.0 ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vceqz_p8 (poly8x8_t __a) -+{ -+ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmeqv8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vceqz_s8 (int8x8_t __a) -+{ -+ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmeqv8qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vceqz_s16 (int16x4_t __a) -+{ -+ int16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmeqv4hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vceqz_s32 (int32x2_t __a) -+{ -+ int32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmeqv2si (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vceqz_s64 (int64x1_t __a) -+{ -+ return __a == 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vceqz_u8 (uint8x8_t __a) -+{ -+ uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmeqv8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vceqz_u16 (uint16x4_t __a) -+{ -+ uint16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmeqv4hi ((int16x4_t) __a, -+ (int16x4_t) __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vceqz_u32 (uint32x2_t __a) -+{ -+ uint32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmeqv2si ((int32x2_t) __a, -+ (int32x2_t) __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vceqz_u64 (uint64x1_t __a) -+{ -+ return __a == 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vceqzq_f32 (float32x4_t __a) -+{ -+ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; -+ return (uint32x4_t) __builtin_aarch64_cmeqv4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vceqzq_f64 (float64x2_t __a) -+{ -+ float64x2_t __b = {0.0, 0.0}; -+ return (uint64x2_t) __builtin_aarch64_cmeqv2df (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vceqzq_p8 (poly8x16_t __a) -+{ -+ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmeqv16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vceqzq_s8 (int8x16_t __a) -+{ -+ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmeqv16qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vceqzq_s16 (int16x8_t __a) -+{ -+ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmeqv8hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vceqzq_s32 (int32x4_t __a) -+{ -+ int32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmeqv4si (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vceqzq_s64 (int64x2_t __a) -+{ -+ int64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmeqv2di (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vceqzq_u8 (uint8x16_t __a) -+{ -+ uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmeqv16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vceqzq_u16 (uint16x8_t __a) -+{ -+ uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmeqv8hi ((int16x8_t) __a, -+ (int16x8_t) __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vceqzq_u32 (uint32x4_t __a) -+{ -+ uint32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmeqv4si ((int32x4_t) __a, -+ (int32x4_t) __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vceqzq_u64 (uint64x2_t __a) -+{ -+ uint64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmeqv2di ((int64x2_t) __a, -+ (int64x2_t) __b); -+} -+ -+/* vceqz - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vceqzs_f32 (float32_t __a) -+{ -+ return __a == 0.0f ? -1 : 0; -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vceqzd_s64 (int64x1_t __a) - { -- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, 0); -+ return __a == 0 ? -1ll : 0ll; - } - --/* vcge */ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vceqzd_u64 (int64x1_t __a) -+{ -+ return __a == 0 ? -1ll : 0ll; -+} - -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vceqzd_f64 (float64_t __a) -+{ -+ return __a == 0.0 ? -1ll : 0ll; -+} -+ -+/* vcge - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcge_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return (uint32x2_t) __builtin_aarch64_cmgev2sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcge_f64 (float64x1_t __a, float64x1_t __b) -+{ -+ return __a >= __b ? -1ll : 0ll; -+} -+ - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcge_p8 (poly8x8_t __a, poly8x8_t __b) -+{ -+ return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) - vcge_s8 (int8x8_t __a, int8x8_t __b) - { - return (uint8x8_t) __builtin_aarch64_cmgev8qi (__a, __b); -@@ -19545,7 +18081,7 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcge_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgedi (__a, __b); -+ return __a >= __b ? -1ll : 0ll; - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -@@ -19572,11 +18108,29 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcge_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgeudi ((int64x1_t) __a, -- (int64x1_t) __b); -+ return __a >= __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgeq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return (uint32x4_t) __builtin_aarch64_cmgev4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgeq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return (uint64x2_t) __builtin_aarch64_cmgev2df (__a, __b); -+} -+ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgeq_p8 (poly8x16_t __a, poly8x16_t __b) -+{ -+ return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vcgeq_s8 (int8x16_t __a, int8x16_t __b) - { - return (uint8x16_t) __builtin_aarch64_cmgev16qi (__a, __b); -@@ -19628,28 +18182,245 @@ - (int64x2_t) __b); - } - -+/* vcge - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcges_f32 (float32_t __a, float32_t __b) -+{ -+ return __a >= __b ? -1 : 0; -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcged_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgedi (__a, __b); -+ return __a >= __b ? -1ll : 0ll; - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcged_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgeudi ((int64x1_t) __a, -- (int64x1_t) __b); -+ return __a >= __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcged_f64 (float64_t __a, float64_t __b) -+{ -+ return __a >= __b ? -1ll : 0ll; -+} -+ -+/* vcgez - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcgez_f32 (float32x2_t __a) -+{ -+ float32x2_t __b = {0.0f, 0.0f}; -+ return (uint32x2_t) __builtin_aarch64_cmgev2sf (__a, __b); -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgez_f64 (float64x1_t __a) -+{ -+ return __a >= 0.0 ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcgez_p8 (poly8x8_t __a) -+{ -+ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcgez_s8 (int8x8_t __a) -+{ -+ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmgev8qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vcgez_s16 (int16x4_t __a) -+{ -+ int16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmgev4hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcgez_s32 (int32x2_t __a) -+{ -+ int32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmgev2si (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgez_s64 (int64x1_t __a) -+{ -+ return __a >= 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcgez_u8 (uint8x8_t __a) -+{ -+ uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmgeuv8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vcgez_u16 (uint16x4_t __a) -+{ -+ uint16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmgeuv4hi ((int16x4_t) __a, -+ (int16x4_t) __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcgez_u32 (uint32x2_t __a) -+{ -+ uint32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmgeuv2si ((int32x2_t) __a, -+ (int32x2_t) __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgez_u64 (uint64x1_t __a) -+{ -+ return __a >= 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgezq_f32 (float32x4_t __a) -+{ -+ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; -+ return (uint32x4_t) __builtin_aarch64_cmgev4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgezq_f64 (float64x2_t __a) -+{ -+ float64x2_t __b = {0.0, 0.0}; -+ return (uint64x2_t) __builtin_aarch64_cmgev2df (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgezq_p8 (poly8x16_t __a) -+{ -+ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgezq_s8 (int8x16_t __a) -+{ -+ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmgev16qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vcgezq_s16 (int16x8_t __a) -+{ -+ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmgev8hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgezq_s32 (int32x4_t __a) -+{ -+ int32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmgev4si (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgezq_s64 (int64x2_t __a) -+{ -+ int64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmgev2di (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgezq_u8 (uint8x16_t __a) -+{ -+ uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmgeuv16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vcgezq_u16 (uint16x8_t __a) -+{ -+ uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmgeuv8hi ((int16x8_t) __a, -+ (int16x8_t) __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgezq_u32 (uint32x4_t __a) -+{ -+ uint32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmgeuv4si ((int32x4_t) __a, -+ (int32x4_t) __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgezq_u64 (uint64x2_t __a) -+{ -+ uint64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmgeuv2di ((int64x2_t) __a, -+ (int64x2_t) __b); -+} -+ -+/* vcgez - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcgezs_f32 (float32_t __a) -+{ -+ return __a >= 0.0f ? -1 : 0; -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcgezd_s64 (int64x1_t __a) - { -- return (uint64x1_t) __builtin_aarch64_cmgedi (__a, 0); -+ return __a >= 0 ? -1ll : 0ll; - } - --/* vcgt */ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgezd_u64 (int64x1_t __a) -+{ -+ return __a >= 0 ? -1ll : 0ll; -+} - -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcgezd_f64 (float64_t __a) -+{ -+ return __a >= 0.0 ? -1ll : 0ll; -+} -+ -+/* vcgt - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcgt_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return (uint32x2_t) __builtin_aarch64_cmgtv2sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgt_f64 (float64x1_t __a, float64x1_t __b) -+{ -+ return __a > __b ? -1ll : 0ll; -+} -+ - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcgt_p8 (poly8x8_t __a, poly8x8_t __b) -+{ -+ return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) - vcgt_s8 (int8x8_t __a, int8x8_t __b) - { - return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__a, __b); -@@ -19670,7 +18441,7 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcgt_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgtdi (__a, __b); -+ return __a > __b ? -1ll : 0ll; - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -@@ -19697,11 +18468,29 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcgt_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgtudi ((int64x1_t) __a, -- (int64x1_t) __b); -+ return __a > __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgtq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return (uint32x4_t) __builtin_aarch64_cmgtv4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgtq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return (uint64x2_t) __builtin_aarch64_cmgtv2df (__a, __b); -+} -+ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgtq_p8 (poly8x16_t __a, poly8x16_t __b) -+{ -+ return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vcgtq_s8 (int8x16_t __a, int8x16_t __b) - { - return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__a, __b); -@@ -19753,28 +18542,245 @@ - (int64x2_t) __b); - } - -+/* vcgt - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcgts_f32 (float32_t __a, float32_t __b) -+{ -+ return __a > __b ? -1 : 0; -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcgtd_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgtdi (__a, __b); -+ return __a > __b ? -1ll : 0ll; - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcgtd_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgtudi ((int64x1_t) __a, -- (int64x1_t) __b); -+ return __a > __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcgtd_f64 (float64_t __a, float64_t __b) -+{ -+ return __a > __b ? -1ll : 0ll; -+} -+ -+/* vcgtz - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcgtz_f32 (float32x2_t __a) -+{ -+ float32x2_t __b = {0.0f, 0.0f}; -+ return (uint32x2_t) __builtin_aarch64_cmgtv2sf (__a, __b); -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgtz_f64 (float64x1_t __a) -+{ -+ return __a > 0.0 ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcgtz_p8 (poly8x8_t __a) -+{ -+ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcgtz_s8 (int8x8_t __a) -+{ -+ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vcgtz_s16 (int16x4_t __a) -+{ -+ int16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmgtv4hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcgtz_s32 (int32x2_t __a) -+{ -+ int32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmgtv2si (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgtz_s64 (int64x1_t __a) -+{ -+ return __a > 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcgtz_u8 (uint8x8_t __a) -+{ -+ uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmgtuv8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vcgtz_u16 (uint16x4_t __a) -+{ -+ uint16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmgtuv4hi ((int16x4_t) __a, -+ (int16x4_t) __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcgtz_u32 (uint32x2_t __a) -+{ -+ uint32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmgtuv2si ((int32x2_t) __a, -+ (int32x2_t) __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgtz_u64 (uint64x1_t __a) -+{ -+ return __a > 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgtzq_f32 (float32x4_t __a) -+{ -+ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; -+ return (uint32x4_t) __builtin_aarch64_cmgtv4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgtzq_f64 (float64x2_t __a) -+{ -+ float64x2_t __b = {0.0, 0.0}; -+ return (uint64x2_t) __builtin_aarch64_cmgtv2df (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgtzq_p8 (poly8x16_t __a) -+{ -+ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgtzq_s8 (int8x16_t __a) -+{ -+ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vcgtzq_s16 (int16x8_t __a) -+{ -+ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmgtv8hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgtzq_s32 (int32x4_t __a) -+{ -+ int32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmgtv4si (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgtzq_s64 (int64x2_t __a) -+{ -+ int64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmgtv2di (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcgtzq_u8 (uint8x16_t __a) -+{ -+ uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmgtuv16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vcgtzq_u16 (uint16x8_t __a) -+{ -+ uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmgtuv8hi ((int16x8_t) __a, -+ (int16x8_t) __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcgtzq_u32 (uint32x4_t __a) -+{ -+ uint32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmgtuv4si ((int32x4_t) __a, -+ (int32x4_t) __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcgtzq_u64 (uint64x2_t __a) -+{ -+ uint64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmgtuv2di ((int64x2_t) __a, -+ (int64x2_t) __b); -+} -+ -+/* vcgtz - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcgtzs_f32 (float32_t __a) -+{ -+ return __a > 0.0f ? -1 : 0; -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcgtzd_s64 (int64x1_t __a) - { -- return (uint64x1_t) __builtin_aarch64_cmgtdi (__a, 0); -+ return __a > 0 ? -1ll : 0ll; - } - --/* vcle */ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcgtzd_u64 (int64x1_t __a) -+{ -+ return __a > 0 ? -1ll : 0ll; -+} - -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcgtzd_f64 (float64_t __a) -+{ -+ return __a > 0.0 ? -1ll : 0ll; -+} -+ -+/* vcle - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcle_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return (uint32x2_t) __builtin_aarch64_cmgev2sf (__b, __a); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcle_f64 (float64x1_t __a, float64x1_t __b) -+{ -+ return __a <= __b ? -1ll : 0ll; -+} -+ - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcle_p8 (poly8x8_t __a, poly8x8_t __b) -+{ -+ return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __b, -+ (int8x8_t) __a); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) - vcle_s8 (int8x8_t __a, int8x8_t __b) - { - return (uint8x8_t) __builtin_aarch64_cmgev8qi (__b, __a); -@@ -19795,7 +18801,7 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcle_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgedi (__b, __a); -+ return __a <= __b ? -1ll : 0ll; - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -@@ -19822,11 +18828,29 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcle_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgeudi ((int64x1_t) __b, -- (int64x1_t) __a); -+ return __a <= __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcleq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return (uint32x4_t) __builtin_aarch64_cmgev4sf (__b, __a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcleq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return (uint64x2_t) __builtin_aarch64_cmgev2df (__b, __a); -+} -+ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcleq_p8 (poly8x16_t __a, poly8x16_t __b) -+{ -+ return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __b, -+ (int8x16_t) __a); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vcleq_s8 (int8x16_t __a, int8x16_t __b) - { - return (uint8x16_t) __builtin_aarch64_cmgev16qi (__b, __a); -@@ -19878,21 +18902,188 @@ - (int64x2_t) __a); - } - -+/* vcle - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcles_f32 (float32_t __a, float32_t __b) -+{ -+ return __a <= __b ? -1 : 0; -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcled_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgedi (__b, __a); -+ return __a <= __b ? -1ll : 0ll; - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcled_u64 (uint64x1_t __a, uint64x1_t __b) -+{ -+ return __a <= __b ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcled_f64 (float64_t __a, float64_t __b) -+{ -+ return __a <= __b ? -1ll : 0ll; -+} -+ -+/* vclez - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vclez_f32 (float32x2_t __a) -+{ -+ float32x2_t __b = {0.0f, 0.0f}; -+ return (uint32x2_t) __builtin_aarch64_cmlev2sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vclez_f64 (float64x1_t __a) -+{ -+ return __a <= 0.0 ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vclez_p8 (poly8x8_t __a) -+{ -+ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmlev8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vclez_s8 (int8x8_t __a) -+{ -+ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmlev8qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vclez_s16 (int16x4_t __a) -+{ -+ int16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmlev4hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vclez_s32 (int32x2_t __a) -+{ -+ int32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmlev2si (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vclez_s64 (int64x1_t __a) -+{ -+ return __a <= 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vclez_u64 (uint64x1_t __a) -+{ -+ return __a <= 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vclezq_f32 (float32x4_t __a) -+{ -+ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; -+ return (uint32x4_t) __builtin_aarch64_cmlev4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vclezq_f64 (float64x2_t __a) -+{ -+ float64x2_t __b = {0.0, 0.0}; -+ return (uint64x2_t) __builtin_aarch64_cmlev2df (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vclezq_p8 (poly8x16_t __a) -+{ -+ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmlev16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vclezq_s8 (int8x16_t __a) -+{ -+ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmlev16qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vclezq_s16 (int16x8_t __a) -+{ -+ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmlev8hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vclezq_s32 (int32x4_t __a) -+{ -+ int32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmlev4si (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vclezq_s64 (int64x2_t __a) -+{ -+ int64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmlev2di (__a, __b); -+} -+ -+/* vclez - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vclezs_f32 (float32_t __a) -+{ -+ return __a <= 0.0f ? -1 : 0; -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vclezd_s64 (int64x1_t __a) - { -- return (uint64x1_t) __builtin_aarch64_cmledi (__a, 0); -+ return __a <= 0 ? -1ll : 0ll; - } - --/* vclt */ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vclezd_u64 (int64x1_t __a) -+{ -+ return __a <= 0 ? -1ll : 0ll; -+} - -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vclezd_f64 (float64_t __a) -+{ -+ return __a <= 0.0 ? -1ll : 0ll; -+} -+ -+/* vclt - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vclt_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return (uint32x2_t) __builtin_aarch64_cmgtv2sf (__b, __a); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vclt_f64 (float64x1_t __a, float64x1_t __b) -+{ -+ return __a < __b ? -1ll : 0ll; -+} -+ - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vclt_p8 (poly8x8_t __a, poly8x8_t __b) -+{ -+ return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __b, -+ (int8x8_t) __a); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) - vclt_s8 (int8x8_t __a, int8x8_t __b) - { - return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__b, __a); -@@ -19913,7 +19104,7 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vclt_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgtdi (__b, __a); -+ return __a < __b ? -1ll : 0ll; - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -@@ -19940,11 +19131,29 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vclt_u64 (uint64x1_t __a, uint64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgtudi ((int64x1_t) __b, -- (int64x1_t) __a); -+ return __a < __b ? -1ll : 0ll; - } - -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcltq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return (uint32x4_t) __builtin_aarch64_cmgtv4sf (__b, __a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcltq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return (uint64x2_t) __builtin_aarch64_cmgtv2df (__b, __a); -+} -+ - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcltq_p8 (poly8x16_t __a, poly8x16_t __b) -+{ -+ return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __b, -+ (int8x16_t) __a); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vcltq_s8 (int8x16_t __a, int8x16_t __b) - { - return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__b, __a); -@@ -19996,66 +19205,639 @@ - (int64x2_t) __a); - } - -+/* vclt - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vclts_f32 (float32_t __a, float32_t __b) -+{ -+ return __a < __b ? -1 : 0; -+} -+ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcltd_s64 (int64x1_t __a, int64x1_t __b) - { -- return (uint64x1_t) __builtin_aarch64_cmgtdi (__b, __a); -+ return __a < __b ? -1ll : 0ll; - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcltd_u64 (uint64x1_t __a, uint64x1_t __b) -+{ -+ return __a < __b ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcltd_f64 (float64_t __a, float64_t __b) -+{ -+ return __a < __b ? -1ll : 0ll; -+} -+ -+/* vcltz - vector. */ -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcltz_f32 (float32x2_t __a) -+{ -+ float32x2_t __b = {0.0f, 0.0f}; -+ return (uint32x2_t) __builtin_aarch64_cmltv2sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcltz_f64 (float64x1_t __a) -+{ -+ return __a < 0.0 ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcltz_p8 (poly8x8_t __a) -+{ -+ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmltv8qi ((int8x8_t) __a, -+ (int8x8_t) __b); -+} -+ -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vcltz_s8 (int8x8_t __a) -+{ -+ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x8_t) __builtin_aarch64_cmltv8qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vcltz_s16 (int16x4_t __a) -+{ -+ int16x4_t __b = {0, 0, 0, 0}; -+ return (uint16x4_t) __builtin_aarch64_cmltv4hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcltz_s32 (int32x2_t __a) -+{ -+ int32x2_t __b = {0, 0}; -+ return (uint32x2_t) __builtin_aarch64_cmltv2si (__a, __b); -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcltz_s64 (int64x1_t __a) -+{ -+ return __a < 0ll ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcltzq_f32 (float32x4_t __a) -+{ -+ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; -+ return (uint32x4_t) __builtin_aarch64_cmltv4sf (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcltzq_f64 (float64x2_t __a) -+{ -+ float64x2_t __b = {0.0, 0.0}; -+ return (uint64x2_t) __builtin_aarch64_cmltv2df (__a, __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcltzq_p8 (poly8x16_t __a) -+{ -+ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmltv16qi ((int8x16_t) __a, -+ (int8x16_t) __b); -+} -+ -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vcltzq_s8 (int8x16_t __a) -+{ -+ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint8x16_t) __builtin_aarch64_cmltv16qi (__a, __b); -+} -+ -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vcltzq_s16 (int16x8_t __a) -+{ -+ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; -+ return (uint16x8_t) __builtin_aarch64_cmltv8hi (__a, __b); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcltzq_s32 (int32x4_t __a) -+{ -+ int32x4_t __b = {0, 0, 0, 0}; -+ return (uint32x4_t) __builtin_aarch64_cmltv4si (__a, __b); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcltzq_s64 (int64x2_t __a) -+{ -+ int64x2_t __b = {0, 0}; -+ return (uint64x2_t) __builtin_aarch64_cmltv2di (__a, __b); -+} -+ -+/* vcltz - scalar. */ -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcltzs_f32 (float32_t __a) -+{ -+ return __a < 0.0f ? -1 : 0; -+} -+ -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vcltzd_s64 (int64x1_t __a) - { -- return (uint64x1_t) __builtin_aarch64_cmltdi (__a, 0); -+ return __a < 0 ? -1ll : 0ll; - } - -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vcltzd_u64 (int64x1_t __a) -+{ -+ return __a < 0 ? -1ll : 0ll; -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcltzd_f64 (float64_t __a) -+{ -+ return __a < 0.0 ? -1ll : 0ll; -+} -+ -+/* vcvt (double -> float). */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vcvt_f32_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_float_truncate_lo_v2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vcvt_high_f32_f64 (float32x2_t __a, float64x2_t __b) -+{ -+ return __builtin_aarch64_float_truncate_hi_v4sf (__a, __b); -+} -+ -+/* vcvt (float -> double). */ -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vcvt_f64_f32 (float32x2_t __a) -+{ -+ -+ return __builtin_aarch64_float_extend_lo_v2df (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vcvt_high_f64_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_vec_unpacks_hi_v4sf (__a); -+} -+ -+/* vcvt (int -> float) */ -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vcvtd_f64_s64 (int64_t __a) -+{ -+ return (float64_t) __a; -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vcvtd_f64_u64 (uint64_t __a) -+{ -+ return (float64_t) __a; -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vcvts_f32_s32 (int32_t __a) -+{ -+ return (float32_t) __a; -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vcvts_f32_u32 (uint32_t __a) -+{ -+ return (float32_t) __a; -+} -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vcvt_f32_s32 (int32x2_t __a) -+{ -+ return __builtin_aarch64_floatv2siv2sf (__a); -+} -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vcvt_f32_u32 (uint32x2_t __a) -+{ -+ return __builtin_aarch64_floatunsv2siv2sf ((int32x2_t) __a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vcvtq_f32_s32 (int32x4_t __a) -+{ -+ return __builtin_aarch64_floatv4siv4sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vcvtq_f32_u32 (uint32x4_t __a) -+{ -+ return __builtin_aarch64_floatunsv4siv4sf ((int32x4_t) __a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vcvtq_f64_s64 (int64x2_t __a) -+{ -+ return __builtin_aarch64_floatv2div2df (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vcvtq_f64_u64 (uint64x2_t __a) -+{ -+ return __builtin_aarch64_floatunsv2div2df ((int64x2_t) __a); -+} -+ -+/* vcvt (float -> int) */ -+ -+__extension__ static __inline int64_t __attribute__ ((__always_inline__)) -+vcvtd_s64_f64 (float64_t __a) -+{ -+ return (int64_t) __a; -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcvtd_u64_f64 (float64_t __a) -+{ -+ return (uint64_t) __a; -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vcvts_s32_f32 (float32_t __a) -+{ -+ return (int32_t) __a; -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcvts_u32_f32 (float32_t __a) -+{ -+ return (uint32_t) __a; -+} -+ -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vcvt_s32_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_lbtruncv2sfv2si (__a); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcvt_u32_f32 (float32x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x2_t) __builtin_aarch64_lbtruncuv2sfv2si (__a); -+} -+ -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vcvtq_s32_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_lbtruncv4sfv4si (__a); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcvtq_u32_f32 (float32x4_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x4_t) __builtin_aarch64_lbtruncuv4sfv4si (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vcvtq_s64_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_lbtruncv2dfv2di (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcvtq_u64_f64 (float64x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint64x2_t) __builtin_aarch64_lbtruncuv2dfv2di (__a); -+} -+ -+/* vcvta */ -+ -+__extension__ static __inline int64_t __attribute__ ((__always_inline__)) -+vcvtad_s64_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_lrounddfdi (__a); -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcvtad_u64_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_lroundudfdi (__a); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vcvtas_s32_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_lroundsfsi (__a); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcvtas_u32_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_lroundusfsi (__a); -+} -+ -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vcvta_s32_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_lroundv2sfv2si (__a); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcvta_u32_f32 (float32x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x2_t) __builtin_aarch64_lrounduv2sfv2si (__a); -+} -+ -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vcvtaq_s32_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_lroundv4sfv4si (__a); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcvtaq_u32_f32 (float32x4_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x4_t) __builtin_aarch64_lrounduv4sfv4si (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vcvtaq_s64_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_lroundv2dfv2di (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcvtaq_u64_f64 (float64x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint64x2_t) __builtin_aarch64_lrounduv2dfv2di (__a); -+} -+ -+/* vcvtm */ -+ -+__extension__ static __inline int64_t __attribute__ ((__always_inline__)) -+vcvtmd_s64_f64 (float64_t __a) -+{ -+ return __builtin_lfloor (__a); -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcvtmd_u64_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_lfloorudfdi (__a); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vcvtms_s32_f32 (float32_t __a) -+{ -+ return __builtin_ifloorf (__a); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcvtms_u32_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_lfloorusfsi (__a); -+} -+ -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vcvtm_s32_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_lfloorv2sfv2si (__a); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcvtm_u32_f32 (float32x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x2_t) __builtin_aarch64_lflooruv2sfv2si (__a); -+} -+ -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vcvtmq_s32_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_lfloorv4sfv4si (__a); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcvtmq_u32_f32 (float32x4_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x4_t) __builtin_aarch64_lflooruv4sfv4si (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vcvtmq_s64_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_lfloorv2dfv2di (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcvtmq_u64_f64 (float64x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint64x2_t) __builtin_aarch64_lflooruv2dfv2di (__a); -+} -+ -+/* vcvtn */ -+ -+__extension__ static __inline int64_t __attribute__ ((__always_inline__)) -+vcvtnd_s64_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_lfrintndfdi (__a); -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcvtnd_u64_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_lfrintnudfdi (__a); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vcvtns_s32_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_lfrintnsfsi (__a); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcvtns_u32_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_lfrintnusfsi (__a); -+} -+ -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vcvtn_s32_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_lfrintnv2sfv2si (__a); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcvtn_u32_f32 (float32x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x2_t) __builtin_aarch64_lfrintnuv2sfv2si (__a); -+} -+ -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vcvtnq_s32_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_lfrintnv4sfv4si (__a); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcvtnq_u32_f32 (float32x4_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x4_t) __builtin_aarch64_lfrintnuv4sfv4si (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vcvtnq_s64_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_lfrintnv2dfv2di (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcvtnq_u64_f64 (float64x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint64x2_t) __builtin_aarch64_lfrintnuv2dfv2di (__a); -+} -+ -+/* vcvtp */ -+ -+__extension__ static __inline int64_t __attribute__ ((__always_inline__)) -+vcvtpd_s64_f64 (float64_t __a) -+{ -+ return __builtin_lceil (__a); -+} -+ -+__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -+vcvtpd_u64_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_lceiludfdi (__a); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vcvtps_s32_f32 (float32_t __a) -+{ -+ return __builtin_iceilf (__a); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vcvtps_u32_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_lceilusfsi (__a); -+} -+ -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vcvtp_s32_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_lceilv2sfv2si (__a); -+} -+ -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vcvtp_u32_f32 (float32x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x2_t) __builtin_aarch64_lceiluv2sfv2si (__a); -+} -+ -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vcvtpq_s32_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_lceilv4sfv4si (__a); -+} -+ -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vcvtpq_u32_f32 (float32x4_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint32x4_t) __builtin_aarch64_lceiluv4sfv4si (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vcvtpq_s64_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_lceilv2dfv2di (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vcvtpq_u64_f64 (float64x2_t __a) -+{ -+ /* TODO: This cast should go away when builtins have -+ their correct types. */ -+ return (uint64x2_t) __builtin_aarch64_lceiluv2dfv2di (__a); -+} -+ - /* vdup */ - - __extension__ static __inline int8x1_t __attribute__ ((__always_inline__)) - vdupb_lane_s8 (int8x16_t a, int const b) - { -- return __builtin_aarch64_dup_laneqi (a, b); -+ return __aarch64_vgetq_lane_s8 (a, b); - } - - __extension__ static __inline uint8x1_t __attribute__ ((__always_inline__)) - vdupb_lane_u8 (uint8x16_t a, int const b) - { -- return (uint8x1_t) __builtin_aarch64_dup_laneqi ((int8x16_t) a, b); -+ return __aarch64_vgetq_lane_u8 (a, b); - } - - __extension__ static __inline int16x1_t __attribute__ ((__always_inline__)) - vduph_lane_s16 (int16x8_t a, int const b) - { -- return __builtin_aarch64_dup_lanehi (a, b); -+ return __aarch64_vgetq_lane_s16 (a, b); - } - - __extension__ static __inline uint16x1_t __attribute__ ((__always_inline__)) - vduph_lane_u16 (uint16x8_t a, int const b) - { -- return (uint16x1_t) __builtin_aarch64_dup_lanehi ((int16x8_t) a, b); -+ return __aarch64_vgetq_lane_u16 (a, b); - } - - __extension__ static __inline int32x1_t __attribute__ ((__always_inline__)) - vdups_lane_s32 (int32x4_t a, int const b) - { -- return __builtin_aarch64_dup_lanesi (a, b); -+ return __aarch64_vgetq_lane_s32 (a, b); - } - - __extension__ static __inline uint32x1_t __attribute__ ((__always_inline__)) - vdups_lane_u32 (uint32x4_t a, int const b) - { -- return (uint32x1_t) __builtin_aarch64_dup_lanesi ((int32x4_t) a, b); -+ return __aarch64_vgetq_lane_u32 (a, b); - } - - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vdupd_lane_s64 (int64x2_t a, int const b) - { -- return __builtin_aarch64_dup_lanedi (a, b); -+ return __aarch64_vgetq_lane_s64 (a, b); - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vdupd_lane_u64 (uint64x2_t a, int const b) - { -- return (uint64x1_t) __builtin_aarch64_dup_lanedi ((int64x2_t) a, b); -+ return __aarch64_vgetq_lane_u64 (a, b); - } - - /* vld1 */ -@@ -21088,7 +20870,7 @@ - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) - vmax_f32 (float32x2_t __a, float32x2_t __b) - { -- return __builtin_aarch64_fmaxv2sf (__a, __b); -+ return __builtin_aarch64_smax_nanv2sf (__a, __b); - } - - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -@@ -21133,13 +20915,13 @@ - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) - vmaxq_f32 (float32x4_t __a, float32x4_t __b) - { -- return __builtin_aarch64_fmaxv4sf (__a, __b); -+ return __builtin_aarch64_smax_nanv4sf (__a, __b); - } - - __extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) - vmaxq_f64 (float64x2_t __a, float64x2_t __b) - { -- return __builtin_aarch64_fmaxv2df (__a, __b); -+ return __builtin_aarch64_smax_nanv2df (__a, __b); - } - - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -@@ -21181,12 +20963,150 @@ - (int32x4_t) __b); - } - --/* vmin */ -+/* vmaxnm */ - - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vmaxnm_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return __builtin_aarch64_smaxv2sf (__a, __b); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vmaxnmq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return __builtin_aarch64_smaxv4sf (__a, __b); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vmaxnmq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return __builtin_aarch64_smaxv2df (__a, __b); -+} -+ -+/* vmaxv */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vmaxv_f32 (float32x2_t __a) -+{ -+ return vget_lane_f32 (__builtin_aarch64_reduc_smax_nan_v2sf (__a), 0); -+} -+ -+__extension__ static __inline int8_t __attribute__ ((__always_inline__)) -+vmaxv_s8 (int8x8_t __a) -+{ -+ return vget_lane_s8 (__builtin_aarch64_reduc_smax_v8qi (__a), 0); -+} -+ -+__extension__ static __inline int16_t __attribute__ ((__always_inline__)) -+vmaxv_s16 (int16x4_t __a) -+{ -+ return vget_lane_s16 (__builtin_aarch64_reduc_smax_v4hi (__a), 0); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vmaxv_s32 (int32x2_t __a) -+{ -+ return vget_lane_s32 (__builtin_aarch64_reduc_smax_v2si (__a), 0); -+} -+ -+__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -+vmaxv_u8 (uint8x8_t __a) -+{ -+ return vget_lane_u8 ((uint8x8_t) -+ __builtin_aarch64_reduc_umax_v8qi ((int8x8_t) __a), 0); -+} -+ -+__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -+vmaxv_u16 (uint16x4_t __a) -+{ -+ return vget_lane_u16 ((uint16x4_t) -+ __builtin_aarch64_reduc_umax_v4hi ((int16x4_t) __a), 0); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vmaxv_u32 (uint32x2_t __a) -+{ -+ return vget_lane_u32 ((uint32x2_t) -+ __builtin_aarch64_reduc_umax_v2si ((int32x2_t) __a), 0); -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vmaxvq_f32 (float32x4_t __a) -+{ -+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_nan_v4sf (__a), 0); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vmaxvq_f64 (float64x2_t __a) -+{ -+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_nan_v2df (__a), 0); -+} -+ -+__extension__ static __inline int8_t __attribute__ ((__always_inline__)) -+vmaxvq_s8 (int8x16_t __a) -+{ -+ return vgetq_lane_s8 (__builtin_aarch64_reduc_smax_v16qi (__a), 0); -+} -+ -+__extension__ static __inline int16_t __attribute__ ((__always_inline__)) -+vmaxvq_s16 (int16x8_t __a) -+{ -+ return vgetq_lane_s16 (__builtin_aarch64_reduc_smax_v8hi (__a), 0); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vmaxvq_s32 (int32x4_t __a) -+{ -+ return vgetq_lane_s32 (__builtin_aarch64_reduc_smax_v4si (__a), 0); -+} -+ -+__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -+vmaxvq_u8 (uint8x16_t __a) -+{ -+ return vgetq_lane_u8 ((uint8x16_t) -+ __builtin_aarch64_reduc_umax_v16qi ((int8x16_t) __a), 0); -+} -+ -+__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -+vmaxvq_u16 (uint16x8_t __a) -+{ -+ return vgetq_lane_u16 ((uint16x8_t) -+ __builtin_aarch64_reduc_umax_v8hi ((int16x8_t) __a), 0); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vmaxvq_u32 (uint32x4_t __a) -+{ -+ return vgetq_lane_u32 ((uint32x4_t) -+ __builtin_aarch64_reduc_umax_v4si ((int32x4_t) __a), 0); -+} -+ -+/* vmaxnmv */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vmaxnmv_f32 (float32x2_t __a) -+{ -+ return vget_lane_f32 (__builtin_aarch64_reduc_smax_v2sf (__a), 0); -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vmaxnmvq_f32 (float32x4_t __a) -+{ -+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_v4sf (__a), 0); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vmaxnmvq_f64 (float64x2_t __a) -+{ -+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_v2df (__a), 0); -+} -+ -+/* vmin */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) - vmin_f32 (float32x2_t __a, float32x2_t __b) - { -- return __builtin_aarch64_fminv2sf (__a, __b); -+ return __builtin_aarch64_smin_nanv2sf (__a, __b); - } - - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -@@ -21231,13 +21151,13 @@ - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) - vminq_f32 (float32x4_t __a, float32x4_t __b) - { -- return __builtin_aarch64_fminv4sf (__a, __b); -+ return __builtin_aarch64_smin_nanv4sf (__a, __b); - } - - __extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) - vminq_f64 (float64x2_t __a, float64x2_t __b) - { -- return __builtin_aarch64_fminv2df (__a, __b); -+ return __builtin_aarch64_smin_nanv2df (__a, __b); - } - - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -@@ -21279,6 +21199,144 @@ - (int32x4_t) __b); - } - -+/* vminnm */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vminnm_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return __builtin_aarch64_sminv2sf (__a, __b); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vminnmq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return __builtin_aarch64_sminv4sf (__a, __b); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vminnmq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return __builtin_aarch64_sminv2df (__a, __b); -+} -+ -+/* vminv */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vminv_f32 (float32x2_t __a) -+{ -+ return vget_lane_f32 (__builtin_aarch64_reduc_smin_nan_v2sf (__a), 0); -+} -+ -+__extension__ static __inline int8_t __attribute__ ((__always_inline__)) -+vminv_s8 (int8x8_t __a) -+{ -+ return vget_lane_s8 (__builtin_aarch64_reduc_smin_v8qi (__a), 0); -+} -+ -+__extension__ static __inline int16_t __attribute__ ((__always_inline__)) -+vminv_s16 (int16x4_t __a) -+{ -+ return vget_lane_s16 (__builtin_aarch64_reduc_smin_v4hi (__a), 0); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vminv_s32 (int32x2_t __a) -+{ -+ return vget_lane_s32 (__builtin_aarch64_reduc_smin_v2si (__a), 0); -+} -+ -+__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -+vminv_u8 (uint8x8_t __a) -+{ -+ return vget_lane_u8 ((uint8x8_t) -+ __builtin_aarch64_reduc_umin_v8qi ((int8x8_t) __a), 0); -+} -+ -+__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -+vminv_u16 (uint16x4_t __a) -+{ -+ return vget_lane_u16 ((uint16x4_t) -+ __builtin_aarch64_reduc_umin_v4hi ((int16x4_t) __a), 0); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vminv_u32 (uint32x2_t __a) -+{ -+ return vget_lane_u32 ((uint32x2_t) -+ __builtin_aarch64_reduc_umin_v2si ((int32x2_t) __a), 0); -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vminvq_f32 (float32x4_t __a) -+{ -+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_nan_v4sf (__a), 0); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vminvq_f64 (float64x2_t __a) -+{ -+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_nan_v2df (__a), 0); -+} -+ -+__extension__ static __inline int8_t __attribute__ ((__always_inline__)) -+vminvq_s8 (int8x16_t __a) -+{ -+ return vgetq_lane_s8 (__builtin_aarch64_reduc_smin_v16qi (__a), 0); -+} -+ -+__extension__ static __inline int16_t __attribute__ ((__always_inline__)) -+vminvq_s16 (int16x8_t __a) -+{ -+ return vgetq_lane_s16 (__builtin_aarch64_reduc_smin_v8hi (__a), 0); -+} -+ -+__extension__ static __inline int32_t __attribute__ ((__always_inline__)) -+vminvq_s32 (int32x4_t __a) -+{ -+ return vgetq_lane_s32 (__builtin_aarch64_reduc_smin_v4si (__a), 0); -+} -+ -+__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -+vminvq_u8 (uint8x16_t __a) -+{ -+ return vgetq_lane_u8 ((uint8x16_t) -+ __builtin_aarch64_reduc_umin_v16qi ((int8x16_t) __a), 0); -+} -+ -+__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -+vminvq_u16 (uint16x8_t __a) -+{ -+ return vgetq_lane_u16 ((uint16x8_t) -+ __builtin_aarch64_reduc_umin_v8hi ((int16x8_t) __a), 0); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vminvq_u32 (uint32x4_t __a) -+{ -+ return vgetq_lane_u32 ((uint32x4_t) -+ __builtin_aarch64_reduc_umin_v4si ((int32x4_t) __a), 0); -+} -+ -+/* vminnmv */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vminnmv_f32 (float32x2_t __a) -+{ -+ return vget_lane_f32 (__builtin_aarch64_reduc_smin_v2sf (__a), 0); -+} -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vminnmvq_f32 (float32x4_t __a) -+{ -+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_v4sf (__a), 0); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vminnmvq_f64 (float64x2_t __a) -+{ -+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_v2df (__a), 0); -+} -+ - /* vmla */ - - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -@@ -21430,7 +21488,7 @@ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vqdmlal_lane_s16 (int32x4_t __a, int16x4_t __b, int16x4_t __c, int const __d) - { -- int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (INT64_C (0))); -+ int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (__AARCH64_INT64_C (0))); - return __builtin_aarch64_sqdmlal_lanev4hi (__a, __b, __tmp, __d); - } - -@@ -21481,7 +21539,7 @@ - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vqdmlal_lane_s32 (int64x2_t __a, int32x2_t __b, int32x2_t __c, int const __d) - { -- int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (INT64_C (0))); -+ int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (__AARCH64_INT64_C (0))); - return __builtin_aarch64_sqdmlal_lanev2si (__a, __b, __tmp, __d); - } - -@@ -21558,7 +21616,7 @@ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vqdmlsl_lane_s16 (int32x4_t __a, int16x4_t __b, int16x4_t __c, int const __d) - { -- int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (INT64_C (0))); -+ int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (__AARCH64_INT64_C (0))); - return __builtin_aarch64_sqdmlsl_lanev4hi (__a, __b, __tmp, __d); - } - -@@ -21609,7 +21667,7 @@ - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vqdmlsl_lane_s32 (int64x2_t __a, int32x2_t __b, int32x2_t __c, int const __d) - { -- int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (INT64_C (0))); -+ int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (__AARCH64_INT64_C (0))); - return __builtin_aarch64_sqdmlsl_lanev2si (__a, __b, __tmp, __d); - } - -@@ -21734,7 +21792,7 @@ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vqdmull_lane_s16 (int16x4_t __a, int16x4_t __b, int const __c) - { -- int16x8_t __tmp = vcombine_s16 (__b, vcreate_s16 (INT64_C (0))); -+ int16x8_t __tmp = vcombine_s16 (__b, vcreate_s16 (__AARCH64_INT64_C (0))); - return __builtin_aarch64_sqdmull_lanev4hi (__a, __tmp, __c); - } - -@@ -21783,7 +21841,7 @@ - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vqdmull_lane_s32 (int32x2_t __a, int32x2_t __b, int const __c) - { -- int32x4_t __tmp = vcombine_s32 (__b, vcreate_s32 (INT64_C (0))); -+ int32x4_t __tmp = vcombine_s32 (__b, vcreate_s32 (__AARCH64_INT64_C (0))); - return __builtin_aarch64_sqdmull_lanev2si (__a, __tmp, __c); - } - -@@ -22795,6 +22853,223 @@ - return (uint64x1_t) __builtin_aarch64_uqsubdi (__a, __b); - } - -+/* vrecpe */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vrecpes_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_frecpesf (__a); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vrecped_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_frecpedf (__a); -+} -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrecpe_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_frecpev2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrecpeq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_frecpev4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrecpeq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_frecpev2df (__a); -+} -+ -+/* vrecps */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vrecpss_f32 (float32_t __a, float32_t __b) -+{ -+ return __builtin_aarch64_frecpssf (__a, __b); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vrecpsd_f64 (float64_t __a, float64_t __b) -+{ -+ return __builtin_aarch64_frecpsdf (__a, __b); -+} -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrecps_f32 (float32x2_t __a, float32x2_t __b) -+{ -+ return __builtin_aarch64_frecpsv2sf (__a, __b); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrecpsq_f32 (float32x4_t __a, float32x4_t __b) -+{ -+ return __builtin_aarch64_frecpsv4sf (__a, __b); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrecpsq_f64 (float64x2_t __a, float64x2_t __b) -+{ -+ return __builtin_aarch64_frecpsv2df (__a, __b); -+} -+ -+/* vrecpx */ -+ -+__extension__ static __inline float32_t __attribute__ ((__always_inline__)) -+vrecpxs_f32 (float32_t __a) -+{ -+ return __builtin_aarch64_frecpxsf (__a); -+} -+ -+__extension__ static __inline float64_t __attribute__ ((__always_inline__)) -+vrecpxd_f64 (float64_t __a) -+{ -+ return __builtin_aarch64_frecpxdf (__a); -+} -+ -+/* vrnd */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrnd_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_btruncv2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrndq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_btruncv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrndq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_btruncv2df (__a); -+} -+ -+/* vrnda */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrnda_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_roundv2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrndaq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_roundv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrndaq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_roundv2df (__a); -+} -+ -+/* vrndi */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrndi_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_nearbyintv2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrndiq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_nearbyintv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrndiq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_nearbyintv2df (__a); -+} -+ -+/* vrndm */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrndm_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_floorv2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrndmq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_floorv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrndmq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_floorv2df (__a); -+} -+ -+/* vrndn */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrndn_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_frintnv2sf (__a); -+} -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrndnq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_frintnv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrndnq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_frintnv2df (__a); -+} -+ -+/* vrndp */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrndp_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_ceilv2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrndpq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_ceilv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrndpq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_ceilv2df (__a); -+} -+ -+/* vrndx */ -+ -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vrndx_f32 (float32x2_t __a) -+{ -+ return __builtin_aarch64_rintv2sf (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vrndxq_f32 (float32x4_t __a) -+{ -+ return __builtin_aarch64_rintv4sf (__a); -+} -+ -+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -+vrndxq_f64 (float64x2_t __a) -+{ -+ return __builtin_aarch64_rintv2df (__a); -+} -+ - /* vrshl */ - - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -@@ -23133,114 +23408,191 @@ - return (uint64x1_t) __builtin_aarch64_ursra_ndi (__a, __b, __c); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+ -+/* vsha1 */ -+ -+static __inline uint32x4_t -+vsha1cq_u32 (uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) -+{ -+ return __builtin_aarch64_crypto_sha1cv4si_uuuu (hash_abcd, hash_e, wk); -+} -+static __inline uint32x4_t -+vsha1mq_u32 (uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) -+{ -+ return __builtin_aarch64_crypto_sha1mv4si_uuuu (hash_abcd, hash_e, wk); -+} -+static __inline uint32x4_t -+vsha1pq_u32 (uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) -+{ -+ return __builtin_aarch64_crypto_sha1pv4si_uuuu (hash_abcd, hash_e, wk); -+} -+ -+static __inline uint32_t -+vsha1h_u32 (uint32_t hash_e) -+{ -+ return __builtin_aarch64_crypto_sha1hsi_uu (hash_e); -+} -+ -+static __inline uint32x4_t -+vsha1su0q_u32 (uint32x4_t w0_3, uint32x4_t w4_7, uint32x4_t w8_11) -+{ -+ return __builtin_aarch64_crypto_sha1su0v4si_uuuu (w0_3, w4_7, w8_11); -+} -+ -+static __inline uint32x4_t -+vsha1su1q_u32 (uint32x4_t tw0_3, uint32x4_t w12_15) -+{ -+ return __builtin_aarch64_crypto_sha1su1v4si_uuu (tw0_3, w12_15); -+} -+ -+static __inline uint32x4_t -+vsha256hq_u32 (uint32x4_t hash_abcd, uint32x4_t hash_efgh, uint32x4_t wk) -+{ -+ return __builtin_aarch64_crypto_sha256hv4si_uuuu (hash_abcd, hash_efgh, wk); -+} -+ -+static __inline uint32x4_t -+vsha256h2q_u32 (uint32x4_t hash_efgh, uint32x4_t hash_abcd, uint32x4_t wk) -+{ -+ return __builtin_aarch64_crypto_sha256h2v4si_uuuu (hash_efgh, hash_abcd, wk); -+} -+ -+static __inline uint32x4_t -+vsha256su0q_u32 (uint32x4_t w0_3, uint32x4_t w4_7) -+{ -+ return __builtin_aarch64_crypto_sha256su0v4si_uuu (w0_3, w4_7); -+} -+ -+static __inline uint32x4_t -+vsha256su1q_u32 (uint32x4_t tw0_3, uint32x4_t w8_11, uint32x4_t w12_15) -+{ -+ return __builtin_aarch64_crypto_sha256su1v4si_uuuu (tw0_3, w8_11, w12_15); -+} -+ -+static __inline poly128_t -+vmull_p64 (poly64_t a, poly64_t b) -+{ -+ return -+ __builtin_aarch64_crypto_pmulldi_ppp (a, b); -+} -+ -+static __inline poly128_t -+vmull_high_p64 (poly64x2_t a, poly64x2_t b) -+{ -+ return __builtin_aarch64_crypto_pmullv2di_ppp (a, b); -+} -+ -+#endif -+ - /* vshl */ - - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vshl_n_s8 (int8x8_t __a, const int __b) - { -- return (int8x8_t) __builtin_aarch64_sshl_nv8qi (__a, __b); -+ return (int8x8_t) __builtin_aarch64_ashlv8qi (__a, __b); - } - - __extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) - vshl_n_s16 (int16x4_t __a, const int __b) - { -- return (int16x4_t) __builtin_aarch64_sshl_nv4hi (__a, __b); -+ return (int16x4_t) __builtin_aarch64_ashlv4hi (__a, __b); - } - - __extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) - vshl_n_s32 (int32x2_t __a, const int __b) - { -- return (int32x2_t) __builtin_aarch64_sshl_nv2si (__a, __b); -+ return (int32x2_t) __builtin_aarch64_ashlv2si (__a, __b); - } - - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vshl_n_s64 (int64x1_t __a, const int __b) - { -- return (int64x1_t) __builtin_aarch64_sshl_ndi (__a, __b); -+ return (int64x1_t) __builtin_aarch64_ashldi (__a, __b); - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) - vshl_n_u8 (uint8x8_t __a, const int __b) - { -- return (uint8x8_t) __builtin_aarch64_ushl_nv8qi ((int8x8_t) __a, __b); -+ return (uint8x8_t) __builtin_aarch64_ashlv8qi ((int8x8_t) __a, __b); - } +-vcvtps_s64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtps %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvtps_u64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtpu %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vcvtq_f32_s32 (int32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("scvtf %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vcvtq_f32_u32 (uint32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("ucvtf %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vcvtq_f64_s64 (int64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("scvtf %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vcvtq_f64_u64 (uint64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("ucvtf %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + #define vcvtq_n_f32_s32(a, b) \ + __extension__ \ + ({ \ +@@ -6751,72 +5595,6 @@ + result; \ + }) - __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) - vshl_n_u16 (uint16x4_t __a, const int __b) - { -- return (uint16x4_t) __builtin_aarch64_ushl_nv4hi ((int16x4_t) __a, __b); -+ return (uint16x4_t) __builtin_aarch64_ashlv4hi ((int16x4_t) __a, __b); - } +-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +-vcvtq_s32_f32 (float32x4_t a) +-{ +- int32x4_t result; +- __asm__ ("fcvtzs %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) +-vcvtq_s64_f64 (float64x2_t a) +-{ +- int64x2_t result; +- __asm__ ("fcvtzs %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +-vcvtq_u32_f32 (float32x4_t a) +-{ +- uint32x4_t result; +- __asm__ ("fcvtzu %0.4s, %1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +-vcvtq_u64_f64 (float64x2_t a) +-{ +- uint64x2_t result; +- __asm__ ("fcvtzu %0.2d, %1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +-vcvts_f64_s32 (int32_t a) +-{ +- int32_t result; +- __asm__ ("scvtf %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +-vcvts_f64_u32 (uint32_t a) +-{ +- uint32_t result; +- __asm__ ("ucvtf %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + #define vcvts_n_f32_s32(a, b) \ + __extension__ \ + ({ \ +@@ -6865,28 +5643,6 @@ + result; \ + }) - __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) - vshl_n_u32 (uint32x2_t __a, const int __b) +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvts_s64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtzs %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vcvts_u64_f64 (float32_t a) +-{ +- float32_t result; +- __asm__ ("fcvtzu %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) + vcvtx_f32_f64 (float64x2_t a) { -- return (uint32x2_t) __builtin_aarch64_ushl_nv2si ((int32x2_t) __a, __b); -+ return (uint32x2_t) __builtin_aarch64_ashlv2si ((int32x2_t) __a, __b); +@@ -8110,151 +6866,7 @@ + return result; } - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vshl_n_u64 (uint64x1_t __a, const int __b) +-#define vget_lane_f64(a, b) \ +- __extension__ \ +- ({ \ +- float64x1_t a_ = (a); \ +- float64_t result; \ +- __asm__ ("umov %x0, %1.d[%2]" \ +- : "=r"(result) \ +- : "w"(a_), "i"(b) \ +- : /* No clobbers */); \ +- result; \ +- }) +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vget_low_f32 (float32x4_t a) +-{ +- float32x2_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) +-vget_low_f64 (float64x2_t a) +-{ +- float64x1_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) +-vget_low_p8 (poly8x16_t a) +-{ +- poly8x8_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) +-vget_low_p16 (poly16x8_t a) +-{ +- poly16x4_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) +-vget_low_s8 (int8x16_t a) +-{ +- int8x8_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +-vget_low_s16 (int16x8_t a) +-{ +- int16x4_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +-vget_low_s32 (int32x4_t a) +-{ +- int32x2_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) +-vget_low_s64 (int64x2_t a) +-{ +- int64x1_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) +-vget_low_u8 (uint8x16_t a) +-{ +- uint8x8_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +-vget_low_u16 (uint16x8_t a) +-{ +- uint16x4_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +-vget_low_u32 (uint32x4_t a) +-{ +- uint32x2_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) +-vget_low_u64 (uint64x2_t a) +-{ +- uint64x1_t result; +- __asm__ ("ins %0.d[0], %1.d[0]" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) + vhsub_s8 (int8x8_t a, int8x8_t b) { -- return (uint64x1_t) __builtin_aarch64_ushl_ndi ((int64x1_t) __a, __b); -+ return (uint64x1_t) __builtin_aarch64_ashldi ((int64x1_t) __a, __b); - } + int8x8_t result; +@@ -8962,303 +7574,6 @@ + result; \ + }) +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vmaxnm_f32 (float32x2_t a, float32x2_t b) +-{ +- float32x2_t result; +- __asm__ ("fmaxnm %0.2s,%1.2s,%2.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vmaxnmq_f32 (float32x4_t a, float32x4_t b) +-{ +- float32x4_t result; +- __asm__ ("fmaxnm %0.4s,%1.4s,%2.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vmaxnmq_f64 (float64x2_t a, float64x2_t b) +-{ +- float64x2_t result; +- __asm__ ("fmaxnm %0.2d,%1.2d,%2.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vmaxnmvq_f32 (float32x4_t a) +-{ +- float32_t result; +- __asm__ ("fmaxnmv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8_t __attribute__ ((__always_inline__)) +-vmaxv_s8 (int8x8_t a) +-{ +- int8_t result; +- __asm__ ("smaxv %b0,%1.8b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16_t __attribute__ ((__always_inline__)) +-vmaxv_s16 (int16x4_t a) +-{ +- int16_t result; +- __asm__ ("smaxv %h0,%1.4h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) +-vmaxv_u8 (uint8x8_t a) +-{ +- uint8_t result; +- __asm__ ("umaxv %b0,%1.8b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) +-vmaxv_u16 (uint16x4_t a) +-{ +- uint16_t result; +- __asm__ ("umaxv %h0,%1.4h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vmaxvq_f32 (float32x4_t a) +-{ +- float32_t result; +- __asm__ ("fmaxv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8_t __attribute__ ((__always_inline__)) +-vmaxvq_s8 (int8x16_t a) +-{ +- int8_t result; +- __asm__ ("smaxv %b0,%1.16b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16_t __attribute__ ((__always_inline__)) +-vmaxvq_s16 (int16x8_t a) +-{ +- int16_t result; +- __asm__ ("smaxv %h0,%1.8h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +-vmaxvq_s32 (int32x4_t a) +-{ +- int32_t result; +- __asm__ ("smaxv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) +-vmaxvq_u8 (uint8x16_t a) +-{ +- uint8_t result; +- __asm__ ("umaxv %b0,%1.16b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) +-vmaxvq_u16 (uint16x8_t a) +-{ +- uint16_t result; +- __asm__ ("umaxv %h0,%1.8h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +-vmaxvq_u32 (uint32x4_t a) +-{ +- uint32_t result; +- __asm__ ("umaxv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vminnmvq_f32 (float32x4_t a) +-{ +- float32_t result; +- __asm__ ("fminnmv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8_t __attribute__ ((__always_inline__)) +-vminv_s8 (int8x8_t a) +-{ +- int8_t result; +- __asm__ ("sminv %b0,%1.8b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16_t __attribute__ ((__always_inline__)) +-vminv_s16 (int16x4_t a) +-{ +- int16_t result; +- __asm__ ("sminv %h0,%1.4h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) +-vminv_u8 (uint8x8_t a) +-{ +- uint8_t result; +- __asm__ ("uminv %b0,%1.8b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) +-vminv_u16 (uint16x4_t a) +-{ +- uint16_t result; +- __asm__ ("uminv %h0,%1.4h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vminvq_f32 (float32x4_t a) +-{ +- float32_t result; +- __asm__ ("fminv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int8_t __attribute__ ((__always_inline__)) +-vminvq_s8 (int8x16_t a) +-{ +- int8_t result; +- __asm__ ("sminv %b0,%1.16b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int16_t __attribute__ ((__always_inline__)) +-vminvq_s16 (int16x8_t a) +-{ +- int16_t result; +- __asm__ ("sminv %h0,%1.8h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +-vminvq_s32 (int32x4_t a) +-{ +- int32_t result; +- __asm__ ("sminv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) +-vminvq_u8 (uint8x16_t a) +-{ +- uint8_t result; +- __asm__ ("uminv %b0,%1.16b" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) +-vminvq_u16 (uint16x8_t a) +-{ +- uint16_t result; +- __asm__ ("uminv %h0,%1.8h" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +-vminvq_u32 (uint32x4_t a) +-{ +- uint32_t result; +- __asm__ ("uminv %s0,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + #define vmla_lane_f32(a, b, c, d) \ + __extension__ \ + ({ \ +@@ -11382,7 +9697,7 @@ __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vshlq_n_s8 (int8x16_t __a, const int __b) + vmovn_high_s16 (int8x8_t a, int16x8_t b) { -- return (int8x16_t) __builtin_aarch64_sshl_nv16qi (__a, __b); -+ return (int8x16_t) __builtin_aarch64_ashlv16qi (__a, __b); - } - +- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); ++ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("xtn2 %0.16b,%1.8h" + : "+w"(result) + : "w"(b) +@@ -11393,7 +9708,7 @@ __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) - vshlq_n_s16 (int16x8_t __a, const int __b) + vmovn_high_s32 (int16x4_t a, int32x4_t b) { -- return (int16x8_t) __builtin_aarch64_sshl_nv8hi (__a, __b); -+ return (int16x8_t) __builtin_aarch64_ashlv8hi (__a, __b); - } - +- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); ++ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("xtn2 %0.8h,%1.4s" + : "+w"(result) + : "w"(b) +@@ -11404,7 +9719,7 @@ __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vshlq_n_s32 (int32x4_t __a, const int __b) - { -- return (int32x4_t) __builtin_aarch64_sshl_nv4si (__a, __b); -+ return (int32x4_t) __builtin_aarch64_ashlv4si (__a, __b); - } - - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vshlq_n_s64 (int64x2_t __a, const int __b) + vmovn_high_s64 (int32x2_t a, int64x2_t b) { -- return (int64x2_t) __builtin_aarch64_sshl_nv2di (__a, __b); -+ return (int64x2_t) __builtin_aarch64_ashlv2di (__a, __b); - } - +- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); ++ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("xtn2 %0.4s,%1.2d" + : "+w"(result) + : "w"(b) +@@ -11415,7 +9730,7 @@ __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vshlq_n_u8 (uint8x16_t __a, const int __b) + vmovn_high_u16 (uint8x8_t a, uint16x8_t b) { -- return (uint8x16_t) __builtin_aarch64_ushl_nv16qi ((int8x16_t) __a, __b); -+ return (uint8x16_t) __builtin_aarch64_ashlv16qi ((int8x16_t) __a, __b); - } - +- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); ++ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("xtn2 %0.16b,%1.8h" + : "+w"(result) + : "w"(b) +@@ -11426,7 +9741,7 @@ __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) - vshlq_n_u16 (uint16x8_t __a, const int __b) + vmovn_high_u32 (uint16x4_t a, uint32x4_t b) { -- return (uint16x8_t) __builtin_aarch64_ushl_nv8hi ((int16x8_t) __a, __b); -+ return (uint16x8_t) __builtin_aarch64_ashlv8hi ((int16x8_t) __a, __b); - } - +- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); ++ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("xtn2 %0.8h,%1.4s" + : "+w"(result) + : "w"(b) +@@ -11437,7 +9752,7 @@ __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vshlq_n_u32 (uint32x4_t __a, const int __b) - { -- return (uint32x4_t) __builtin_aarch64_ushl_nv4si ((int32x4_t) __a, __b); -+ return (uint32x4_t) __builtin_aarch64_ashlv4si ((int32x4_t) __a, __b); - } - - __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) - vshlq_n_u64 (uint64x2_t __a, const int __b) - { -- return (uint64x2_t) __builtin_aarch64_ushl_nv2di ((int64x2_t) __a, __b); -+ return (uint64x2_t) __builtin_aarch64_ashlv2di ((int64x2_t) __a, __b); - } - - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vshld_n_s64 (int64x1_t __a, const int __b) - { -- return (int64x1_t) __builtin_aarch64_sshl_ndi (__a, __b); -+ return (int64x1_t) __builtin_aarch64_ashldi (__a, __b); - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vshld_n_u64 (uint64x1_t __a, const int __b) - { -- return (uint64x1_t) __builtin_aarch64_ushl_ndi (__a, __b); -+ return (uint64x1_t) __builtin_aarch64_ashldi (__a, __b); - } - - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -@@ -23428,109 +23780,109 @@ - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vshr_n_s8 (int8x8_t __a, const int __b) - { -- return (int8x8_t) __builtin_aarch64_sshr_nv8qi (__a, __b); -+ return (int8x8_t) __builtin_aarch64_ashrv8qi (__a, __b); - } - - __extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) - vshr_n_s16 (int16x4_t __a, const int __b) - { -- return (int16x4_t) __builtin_aarch64_sshr_nv4hi (__a, __b); -+ return (int16x4_t) __builtin_aarch64_ashrv4hi (__a, __b); - } - - __extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) - vshr_n_s32 (int32x2_t __a, const int __b) - { -- return (int32x2_t) __builtin_aarch64_sshr_nv2si (__a, __b); -+ return (int32x2_t) __builtin_aarch64_ashrv2si (__a, __b); - } - - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vshr_n_s64 (int64x1_t __a, const int __b) - { -- return (int64x1_t) __builtin_aarch64_sshr_ndi (__a, __b); -+ return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b); - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) - vshr_n_u8 (uint8x8_t __a, const int __b) - { -- return (uint8x8_t) __builtin_aarch64_ushr_nv8qi ((int8x8_t) __a, __b); -+ return (uint8x8_t) __builtin_aarch64_lshrv8qi ((int8x8_t) __a, __b); - } - - __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) - vshr_n_u16 (uint16x4_t __a, const int __b) - { -- return (uint16x4_t) __builtin_aarch64_ushr_nv4hi ((int16x4_t) __a, __b); -+ return (uint16x4_t) __builtin_aarch64_lshrv4hi ((int16x4_t) __a, __b); - } - - __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) - vshr_n_u32 (uint32x2_t __a, const int __b) - { -- return (uint32x2_t) __builtin_aarch64_ushr_nv2si ((int32x2_t) __a, __b); -+ return (uint32x2_t) __builtin_aarch64_lshrv2si ((int32x2_t) __a, __b); - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vshr_n_u64 (uint64x1_t __a, const int __b) + vmovn_high_u64 (uint32x2_t a, uint64x2_t b) { -- return (uint64x1_t) __builtin_aarch64_ushr_ndi ((int64x1_t) __a, __b); -+ return (uint64x1_t) __builtin_aarch64_lshrdi ((int64x1_t) __a, __b); - } - +- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); ++ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("xtn2 %0.4s,%1.2d" + : "+w"(result) + : "w"(b) +@@ -13856,7 +12171,7 @@ __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vshrq_n_s8 (int8x16_t __a, const int __b) + vqmovn_high_s16 (int8x8_t a, int16x8_t b) { -- return (int8x16_t) __builtin_aarch64_sshr_nv16qi (__a, __b); -+ return (int8x16_t) __builtin_aarch64_ashrv16qi (__a, __b); - } - +- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); ++ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("sqxtn2 %0.16b, %1.8h" + : "+w"(result) + : "w"(b) +@@ -13867,7 +12182,7 @@ __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) - vshrq_n_s16 (int16x8_t __a, const int __b) + vqmovn_high_s32 (int16x4_t a, int32x4_t b) { -- return (int16x8_t) __builtin_aarch64_sshr_nv8hi (__a, __b); -+ return (int16x8_t) __builtin_aarch64_ashrv8hi (__a, __b); - } - +- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); ++ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("sqxtn2 %0.8h, %1.4s" + : "+w"(result) + : "w"(b) +@@ -13878,7 +12193,7 @@ __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vshrq_n_s32 (int32x4_t __a, const int __b) + vqmovn_high_s64 (int32x2_t a, int64x2_t b) { -- return (int32x4_t) __builtin_aarch64_sshr_nv4si (__a, __b); -+ return (int32x4_t) __builtin_aarch64_ashrv4si (__a, __b); - } - - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vshrq_n_s64 (int64x2_t __a, const int __b) +- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); ++ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("sqxtn2 %0.4s, %1.2d" + : "+w"(result) + : "w"(b) +@@ -13889,7 +12204,7 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vqmovn_high_u16 (uint8x8_t a, uint16x8_t b) { -- return (int64x2_t) __builtin_aarch64_sshr_nv2di (__a, __b); -+ return (int64x2_t) __builtin_aarch64_ashrv2di (__a, __b); - } - +- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); ++ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("uqxtn2 %0.16b, %1.8h" + : "+w"(result) + : "w"(b) +@@ -13900,7 +12215,7 @@ + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vqmovn_high_u32 (uint16x4_t a, uint32x4_t b) + { +- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); ++ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("uqxtn2 %0.8h, %1.4s" + : "+w"(result) + : "w"(b) +@@ -13911,7 +12226,7 @@ + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vqmovn_high_u64 (uint32x2_t a, uint64x2_t b) + { +- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); ++ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("uqxtn2 %0.4s, %1.2d" + : "+w"(result) + : "w"(b) +@@ -13922,7 +12237,7 @@ __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vshrq_n_u8 (uint8x16_t __a, const int __b) + vqmovun_high_s16 (uint8x8_t a, int16x8_t b) { -- return (uint8x16_t) __builtin_aarch64_ushr_nv16qi ((int8x16_t) __a, __b); -+ return (uint8x16_t) __builtin_aarch64_lshrv16qi ((int8x16_t) __a, __b); +- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); ++ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("sqxtun2 %0.16b, %1.8h" + : "+w"(result) + : "w"(b) +@@ -13933,7 +12248,7 @@ + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vqmovun_high_s32 (uint16x4_t a, int32x4_t b) + { +- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); ++ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("sqxtun2 %0.8h, %1.4s" + : "+w"(result) + : "w"(b) +@@ -13944,7 +12259,7 @@ + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vqmovun_high_s64 (uint32x2_t a, int64x2_t b) + { +- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); ++ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("sqxtun2 %0.4s, %1.2d" + : "+w"(result) + : "w"(b) +@@ -14002,7 +12317,8 @@ + int16x8_t b_ = (b); \ + int8x8_t a_ = (a); \ + int8x16_t result = vcombine_s8 \ +- (a_, vcreate_s8 (UINT64_C (0x0))); \ ++ (a_, vcreate_s8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqrshrn2 %0.16b, %1.8h, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14016,7 +12332,8 @@ + int32x4_t b_ = (b); \ + int16x4_t a_ = (a); \ + int16x8_t result = vcombine_s16 \ +- (a_, vcreate_s16 (UINT64_C (0x0))); \ ++ (a_, vcreate_s16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqrshrn2 %0.8h, %1.4s, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14030,7 +12347,8 @@ + int64x2_t b_ = (b); \ + int32x2_t a_ = (a); \ + int32x4_t result = vcombine_s32 \ +- (a_, vcreate_s32 (UINT64_C (0x0))); \ ++ (a_, vcreate_s32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqrshrn2 %0.4s, %1.2d, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14044,7 +12362,8 @@ + uint16x8_t b_ = (b); \ + uint8x8_t a_ = (a); \ + uint8x16_t result = vcombine_u8 \ +- (a_, vcreate_u8 (UINT64_C (0x0))); \ ++ (a_, vcreate_u8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("uqrshrn2 %0.16b, %1.8h, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14058,7 +12377,8 @@ + uint32x4_t b_ = (b); \ + uint16x4_t a_ = (a); \ + uint16x8_t result = vcombine_u16 \ +- (a_, vcreate_u16 (UINT64_C (0x0))); \ ++ (a_, vcreate_u16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("uqrshrn2 %0.8h, %1.4s, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14072,7 +12392,8 @@ + uint64x2_t b_ = (b); \ + uint32x2_t a_ = (a); \ + uint32x4_t result = vcombine_u32 \ +- (a_, vcreate_u32 (UINT64_C (0x0))); \ ++ (a_, vcreate_u32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("uqrshrn2 %0.4s, %1.2d, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14086,7 +12407,8 @@ + int16x8_t b_ = (b); \ + uint8x8_t a_ = (a); \ + uint8x16_t result = vcombine_u8 \ +- (a_, vcreate_u8 (UINT64_C (0x0))); \ ++ (a_, vcreate_u8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqrshrun2 %0.16b, %1.8h, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14100,7 +12422,8 @@ + int32x4_t b_ = (b); \ + uint16x4_t a_ = (a); \ + uint16x8_t result = vcombine_u16 \ +- (a_, vcreate_u16 (UINT64_C (0x0))); \ ++ (a_, vcreate_u16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqrshrun2 %0.8h, %1.4s, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14114,7 +12437,8 @@ + int64x2_t b_ = (b); \ + uint32x2_t a_ = (a); \ + uint32x4_t result = vcombine_u32 \ +- (a_, vcreate_u32 (UINT64_C (0x0))); \ ++ (a_, vcreate_u32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqrshrun2 %0.4s, %1.2d, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14128,7 +12452,8 @@ + int16x8_t b_ = (b); \ + int8x8_t a_ = (a); \ + int8x16_t result = vcombine_s8 \ +- (a_, vcreate_s8 (UINT64_C (0x0))); \ ++ (a_, vcreate_s8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqshrn2 %0.16b, %1.8h, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14142,7 +12467,8 @@ + int32x4_t b_ = (b); \ + int16x4_t a_ = (a); \ + int16x8_t result = vcombine_s16 \ +- (a_, vcreate_s16 (UINT64_C (0x0))); \ ++ (a_, vcreate_s16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqshrn2 %0.8h, %1.4s, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14156,7 +12482,8 @@ + int64x2_t b_ = (b); \ + int32x2_t a_ = (a); \ + int32x4_t result = vcombine_s32 \ +- (a_, vcreate_s32 (UINT64_C (0x0))); \ ++ (a_, vcreate_s32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqshrn2 %0.4s, %1.2d, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14170,7 +12497,8 @@ + uint16x8_t b_ = (b); \ + uint8x8_t a_ = (a); \ + uint8x16_t result = vcombine_u8 \ +- (a_, vcreate_u8 (UINT64_C (0x0))); \ ++ (a_, vcreate_u8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("uqshrn2 %0.16b, %1.8h, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14184,7 +12512,8 @@ + uint32x4_t b_ = (b); \ + uint16x4_t a_ = (a); \ + uint16x8_t result = vcombine_u16 \ +- (a_, vcreate_u16 (UINT64_C (0x0))); \ ++ (a_, vcreate_u16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("uqshrn2 %0.8h, %1.4s, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14198,7 +12527,8 @@ + uint64x2_t b_ = (b); \ + uint32x2_t a_ = (a); \ + uint32x4_t result = vcombine_u32 \ +- (a_, vcreate_u32 (UINT64_C (0x0))); \ ++ (a_, vcreate_u32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("uqshrn2 %0.4s, %1.2d, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14212,7 +12542,8 @@ + int16x8_t b_ = (b); \ + uint8x8_t a_ = (a); \ + uint8x16_t result = vcombine_u8 \ +- (a_, vcreate_u8 (UINT64_C (0x0))); \ ++ (a_, vcreate_u8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqshrun2 %0.16b, %1.8h, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14226,7 +12557,8 @@ + int32x4_t b_ = (b); \ + uint16x4_t a_ = (a); \ + uint16x8_t result = vcombine_u16 \ +- (a_, vcreate_u16 (UINT64_C (0x0))); \ ++ (a_, vcreate_u16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqshrun2 %0.8h, %1.4s, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14240,7 +12572,8 @@ + int64x2_t b_ = (b); \ + uint32x2_t a_ = (a); \ + uint32x4_t result = vcombine_u32 \ +- (a_, vcreate_u32 (UINT64_C (0x0))); \ ++ (a_, vcreate_u32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("sqshrun2 %0.4s, %1.2d, #%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -14292,17 +12625,6 @@ + return result; } - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) - vshrq_n_u16 (uint16x8_t __a, const int __b) +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vrecpe_f32 (float32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("frecpe %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) + vrecpe_u32 (uint32x2_t a) { -- return (uint16x8_t) __builtin_aarch64_ushr_nv8hi ((int16x8_t) __a, __b); -+ return (uint16x8_t) __builtin_aarch64_lshrv8hi ((int16x8_t) __a, __b); +@@ -14314,39 +12636,6 @@ + return result; } +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vrecped_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("frecpe %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vrecpeq_f32 (float32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("frecpe %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vrecpeq_f64 (float64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("frecpe %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) - vshrq_n_u32 (uint32x4_t __a, const int __b) - { -- return (uint32x4_t) __builtin_aarch64_ushr_nv4si ((int32x4_t) __a, __b); -+ return (uint32x4_t) __builtin_aarch64_lshrv4si ((int32x4_t) __a, __b); - } - - __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) - vshrq_n_u64 (uint64x2_t __a, const int __b) - { -- return (uint64x2_t) __builtin_aarch64_ushr_nv2di ((int64x2_t) __a, __b); -+ return (uint64x2_t) __builtin_aarch64_lshrv2di ((int64x2_t) __a, __b); - } - - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vshrd_n_s64 (int64x1_t __a, const int __b) + vrecpeq_u32 (uint32x4_t a) { -- return (int64x1_t) __builtin_aarch64_sshr_ndi (__a, __b); -+ return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b); +@@ -14358,94 +12647,6 @@ + return result; } - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vshrd_n_u64 (uint64x1_t __a, const int __b) +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vrecpes_f32 (float32_t a) +-{ +- float32_t result; +- __asm__ ("frecpe %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vrecps_f32 (float32x2_t a, float32x2_t b) +-{ +- float32x2_t result; +- __asm__ ("frecps %0.2s,%1.2s,%2.2s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vrecpsd_f64 (float64_t a, float64_t b) +-{ +- float64_t result; +- __asm__ ("frecps %d0,%d1,%d2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vrecpsq_f32 (float32x4_t a, float32x4_t b) +-{ +- float32x4_t result; +- __asm__ ("frecps %0.4s,%1.4s,%2.4s" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vrecpsq_f64 (float64x2_t a, float64x2_t b) +-{ +- float64x2_t result; +- __asm__ ("frecps %0.2d,%1.2d,%2.2d" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vrecpss_f32 (float32_t a, float32_t b) +-{ +- float32_t result; +- __asm__ ("frecps %s0,%s1,%s2" +- : "=w"(result) +- : "w"(a), "w"(b) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vrecpxd_f64 (float64_t a) +-{ +- float64_t result; +- __asm__ ("frecpe %d0,%d1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vrecpxs_f32 (float32_t a) +-{ +- float32_t result; +- __asm__ ("frecpe %s0,%s1" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) + vrev16_p8 (poly8x8_t a) { -- return (uint64x1_t) __builtin_aarch64_ushr_ndi (__a, __b); -+ return (uint64x1_t) __builtin_aarch64_lshrdi (__a, __b); +@@ -14842,178 +13043,14 @@ + return result; } - /* vsli */ -@@ -24153,8 +24505,8 @@ - { - __builtin_aarch64_simd_oi __o; - int64x2x2_t temp; -- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0))); -- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0))); -+ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[1], 1); - __builtin_aarch64_st2di ((__builtin_aarch64_simd_di *) __a, __o); -@@ -24165,8 +24517,8 @@ - { - __builtin_aarch64_simd_oi __o; - uint64x2x2_t temp; -- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0))); -- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0))); -+ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[1], 1); - __builtin_aarch64_st2di ((__builtin_aarch64_simd_di *) __a, __o); -@@ -24177,8 +24529,8 @@ - { - __builtin_aarch64_simd_oi __o; - float64x2x2_t temp; -- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0))); -- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0))); -+ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv2df (__o, (float64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv2df (__o, (float64x2_t) temp.val[1], 1); - __builtin_aarch64_st2df ((__builtin_aarch64_simd_df *) __a, __o); -@@ -24189,8 +24541,8 @@ - { - __builtin_aarch64_simd_oi __o; - int8x16x2_t temp; -- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0))); -- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0))); -+ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1); - __builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o); -@@ -24201,8 +24553,8 @@ - { - __builtin_aarch64_simd_oi __o; - poly8x16x2_t temp; -- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0))); -- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0))); -+ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1); - __builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o); -@@ -24213,8 +24565,8 @@ - { - __builtin_aarch64_simd_oi __o; - int16x8x2_t temp; -- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0))); -- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0))); -+ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1); - __builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o); -@@ -24225,8 +24577,8 @@ - { - __builtin_aarch64_simd_oi __o; - poly16x8x2_t temp; -- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0))); -- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0))); -+ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1); - __builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o); -@@ -24237,8 +24589,8 @@ - { - __builtin_aarch64_simd_oi __o; - int32x4x2_t temp; -- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0))); -- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0))); -+ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[1], 1); - __builtin_aarch64_st2v2si ((__builtin_aarch64_simd_si *) __a, __o); -@@ -24249,8 +24601,8 @@ - { - __builtin_aarch64_simd_oi __o; - uint8x16x2_t temp; -- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0))); -- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0))); -+ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1); - __builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o); -@@ -24261,8 +24613,8 @@ - { - __builtin_aarch64_simd_oi __o; - uint16x8x2_t temp; -- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0))); -- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0))); -+ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1); - __builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o); -@@ -24273,8 +24625,8 @@ - { - __builtin_aarch64_simd_oi __o; - uint32x4x2_t temp; -- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0))); -- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0))); -+ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[1], 1); - __builtin_aarch64_st2v2si ((__builtin_aarch64_simd_si *) __a, __o); -@@ -24285,8 +24637,8 @@ - { - __builtin_aarch64_simd_oi __o; - float32x4x2_t temp; -- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0))); -- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0))); -+ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregoiv4sf (__o, (float32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregoiv4sf (__o, (float32x4_t) temp.val[1], 1); - __builtin_aarch64_st2v2sf ((__builtin_aarch64_simd_sf *) __a, __o); -@@ -24405,9 +24757,9 @@ - { - __builtin_aarch64_simd_ci __o; - int64x2x3_t temp; -- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0))); -- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0))); -- temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (INT64_C (0))); -+ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[2], 2); -@@ -24419,9 +24771,9 @@ - { - __builtin_aarch64_simd_ci __o; - uint64x2x3_t temp; -- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0))); -- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0))); -- temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (UINT64_C (0))); -+ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[2], 2); -@@ -24433,9 +24785,9 @@ - { - __builtin_aarch64_simd_ci __o; - float64x2x3_t temp; -- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0))); -- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0))); -- temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (UINT64_C (0))); -+ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[2], 2); -@@ -24447,9 +24799,9 @@ - { - __builtin_aarch64_simd_ci __o; - int8x16x3_t temp; -- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0))); -- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0))); -- temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (INT64_C (0))); -+ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2); -@@ -24461,9 +24813,9 @@ - { - __builtin_aarch64_simd_ci __o; - poly8x16x3_t temp; -- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0))); -- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0))); -- temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (UINT64_C (0))); -+ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2); -@@ -24475,9 +24827,9 @@ - { - __builtin_aarch64_simd_ci __o; - int16x8x3_t temp; -- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0))); -- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0))); -- temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (INT64_C (0))); -+ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2); -@@ -24489,9 +24841,9 @@ - { - __builtin_aarch64_simd_ci __o; - poly16x8x3_t temp; -- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0))); -- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0))); -- temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (UINT64_C (0))); -+ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2); -@@ -24503,9 +24855,9 @@ - { - __builtin_aarch64_simd_ci __o; - int32x4x3_t temp; -- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0))); -- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0))); -- temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (INT64_C (0))); -+ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[2], 2); -@@ -24517,9 +24869,9 @@ - { - __builtin_aarch64_simd_ci __o; - uint8x16x3_t temp; -- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0))); -- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0))); -- temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (UINT64_C (0))); -+ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2); -@@ -24531,9 +24883,9 @@ +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vrnd_f32 (float32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("frintz %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vrnda_f32 (float32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("frinta %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vrndm_f32 (float32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("frintm %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vrndn_f32 (float32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("frintn %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +-vrndp_f32 (float32x2_t a) +-{ +- float32x2_t result; +- __asm__ ("frintp %0.2s,%1.2s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vrndq_f32 (float32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("frintz %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vrndq_f64 (float64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("frintz %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vrndqa_f32 (float32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("frinta %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vrndqa_f64 (float64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("frinta %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vrndqm_f32 (float32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("frintm %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vrndqm_f64 (float64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("frintm %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vrndqn_f32 (float32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("frintn %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vrndqn_f64 (float64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("frintn %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +-vrndqp_f32 (float32x4_t a) +-{ +- float32x4_t result; +- __asm__ ("frintp %0.4s,%1.4s" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- +-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +-vrndqp_f64 (float64x2_t a) +-{ +- float64x2_t result; +- __asm__ ("frintp %0.2d,%1.2d" +- : "=w"(result) +- : "w"(a) +- : /* No clobbers */); +- return result; +-} +- + #define vrshrn_high_n_s16(a, b, c) \ + __extension__ \ + ({ \ + int16x8_t b_ = (b); \ + int8x8_t a_ = (a); \ + int8x16_t result = vcombine_s8 \ +- (a_, vcreate_s8 (UINT64_C (0x0))); \ ++ (a_, vcreate_s8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("rshrn2 %0.16b,%1.8h,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15027,7 +13064,8 @@ + int32x4_t b_ = (b); \ + int16x4_t a_ = (a); \ + int16x8_t result = vcombine_s16 \ +- (a_, vcreate_s16 (UINT64_C (0x0))); \ ++ (a_, vcreate_s16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("rshrn2 %0.8h,%1.4s,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15041,7 +13079,8 @@ + int64x2_t b_ = (b); \ + int32x2_t a_ = (a); \ + int32x4_t result = vcombine_s32 \ +- (a_, vcreate_s32 (UINT64_C (0x0))); \ ++ (a_, vcreate_s32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("rshrn2 %0.4s,%1.2d,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15055,7 +13094,8 @@ + uint16x8_t b_ = (b); \ + uint8x8_t a_ = (a); \ + uint8x16_t result = vcombine_u8 \ +- (a_, vcreate_u8 (UINT64_C (0x0))); \ ++ (a_, vcreate_u8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("rshrn2 %0.16b,%1.8h,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15069,7 +13109,8 @@ + uint32x4_t b_ = (b); \ + uint16x4_t a_ = (a); \ + uint16x8_t result = vcombine_u16 \ +- (a_, vcreate_u16 (UINT64_C (0x0))); \ ++ (a_, vcreate_u16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("rshrn2 %0.8h,%1.4s,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15083,7 +13124,8 @@ + uint64x2_t b_ = (b); \ + uint32x2_t a_ = (a); \ + uint32x4_t result = vcombine_u32 \ +- (a_, vcreate_u32 (UINT64_C (0x0))); \ ++ (a_, vcreate_u32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("rshrn2 %0.4s,%1.2d,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15320,7 +13362,7 @@ + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) + vrsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c) { - __builtin_aarch64_simd_ci __o; - uint16x8x3_t temp; -- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0))); -- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0))); -- temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (UINT64_C (0))); -+ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2); -@@ -24545,9 +24897,9 @@ +- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); ++ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("rsubhn2 %0.16b, %1.8h, %2.8h" + : "+w"(result) + : "w"(b), "w"(c) +@@ -15331,7 +13373,7 @@ + __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) + vrsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c) { - __builtin_aarch64_simd_ci __o; - uint32x4x3_t temp; -- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0))); -- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0))); -- temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (UINT64_C (0))); -+ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[2], 2); -@@ -24559,9 +24911,9 @@ +- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); ++ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("rsubhn2 %0.8h, %1.4s, %2.4s" + : "+w"(result) + : "w"(b), "w"(c) +@@ -15342,7 +13384,7 @@ + __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) + vrsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c) { - __builtin_aarch64_simd_ci __o; - float32x4x3_t temp; -- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0))); -- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0))); -- temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (UINT64_C (0))); -+ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[2], 2); -@@ -24693,10 +25045,10 @@ +- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); ++ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("rsubhn2 %0.4s, %1.2d, %2.2d" + : "+w"(result) + : "w"(b), "w"(c) +@@ -15353,7 +13395,7 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vrsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c) { - __builtin_aarch64_simd_xi __o; - int64x2x4_t temp; -- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0))); -- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0))); -- temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (INT64_C (0))); -- temp.val[3] = vcombine_s64 (val.val[3], vcreate_s64 (INT64_C (0))); -+ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (__AARCH64_INT64_C (0))); -+ temp.val[3] = vcombine_s64 (val.val[3], vcreate_s64 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[2], 2); -@@ -24709,10 +25061,10 @@ +- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); ++ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("rsubhn2 %0.16b, %1.8h, %2.8h" + : "+w"(result) + : "w"(b), "w"(c) +@@ -15364,7 +13406,7 @@ + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vrsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c) { - __builtin_aarch64_simd_xi __o; - uint64x2x4_t temp; -- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0))); -- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0))); -- temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (UINT64_C (0))); -- temp.val[3] = vcombine_u64 (val.val[3], vcreate_u64 (UINT64_C (0))); -+ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_u64 (val.val[3], vcreate_u64 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[2], 2); -@@ -24725,10 +25077,10 @@ +- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); ++ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("rsubhn2 %0.8h, %1.4s, %2.4s" + : "+w"(result) + : "w"(b), "w"(c) +@@ -15375,7 +13417,7 @@ + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vrsubhn_high_u64 (uint32x2_t a, uint64x2_t b, uint64x2_t c) { - __builtin_aarch64_simd_xi __o; - float64x2x4_t temp; -- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0))); -- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0))); -- temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (UINT64_C (0))); -- temp.val[3] = vcombine_f64 (val.val[3], vcreate_f64 (UINT64_C (0))); -+ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_f64 (val.val[3], vcreate_f64 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[2], 2); -@@ -24741,10 +25093,10 @@ +- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); ++ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("rsubhn2 %0.4s, %1.2d, %2.2d" + : "+w"(result) + : "w"(b), "w"(c) +@@ -15767,7 +13809,8 @@ + int16x8_t b_ = (b); \ + int8x8_t a_ = (a); \ + int8x16_t result = vcombine_s8 \ +- (a_, vcreate_s8 (UINT64_C (0x0))); \ ++ (a_, vcreate_s8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("shrn2 %0.16b,%1.8h,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15781,7 +13824,8 @@ + int32x4_t b_ = (b); \ + int16x4_t a_ = (a); \ + int16x8_t result = vcombine_s16 \ +- (a_, vcreate_s16 (UINT64_C (0x0))); \ ++ (a_, vcreate_s16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("shrn2 %0.8h,%1.4s,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15795,7 +13839,8 @@ + int64x2_t b_ = (b); \ + int32x2_t a_ = (a); \ + int32x4_t result = vcombine_s32 \ +- (a_, vcreate_s32 (UINT64_C (0x0))); \ ++ (a_, vcreate_s32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("shrn2 %0.4s,%1.2d,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15809,7 +13854,8 @@ + uint16x8_t b_ = (b); \ + uint8x8_t a_ = (a); \ + uint8x16_t result = vcombine_u8 \ +- (a_, vcreate_u8 (UINT64_C (0x0))); \ ++ (a_, vcreate_u8 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("shrn2 %0.16b,%1.8h,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15823,7 +13869,8 @@ + uint32x4_t b_ = (b); \ + uint16x4_t a_ = (a); \ + uint16x8_t result = vcombine_u16 \ +- (a_, vcreate_u16 (UINT64_C (0x0))); \ ++ (a_, vcreate_u16 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("shrn2 %0.8h,%1.4s,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -15837,7 +13884,8 @@ + uint64x2_t b_ = (b); \ + uint32x2_t a_ = (a); \ + uint32x4_t result = vcombine_u32 \ +- (a_, vcreate_u32 (UINT64_C (0x0))); \ ++ (a_, vcreate_u32 \ ++ (__AARCH64_UINT64_C (0x0))); \ + __asm__ ("shrn2 %0.4s,%1.2d,#%2" \ + : "+w"(result) \ + : "w"(b_), "i"(c) \ +@@ -16289,7 +14337,7 @@ + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) + vsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c) { - __builtin_aarch64_simd_xi __o; - int8x16x4_t temp; -- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0))); -- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0))); -- temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (INT64_C (0))); -- temp.val[3] = vcombine_s8 (val.val[3], vcreate_s8 (INT64_C (0))); -+ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (__AARCH64_INT64_C (0))); -+ temp.val[3] = vcombine_s8 (val.val[3], vcreate_s8 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2); -@@ -24757,10 +25109,10 @@ +- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0))); ++ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("subhn2 %0.16b, %1.8h, %2.8h" + : "+w"(result) + : "w"(b), "w"(c) +@@ -16300,7 +14348,7 @@ + __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) + vsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c) { - __builtin_aarch64_simd_xi __o; - poly8x16x4_t temp; -- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0))); -- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0))); -- temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (UINT64_C (0))); -- temp.val[3] = vcombine_p8 (val.val[3], vcreate_p8 (UINT64_C (0))); -+ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_p8 (val.val[3], vcreate_p8 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2); -@@ -24773,10 +25125,10 @@ +- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0))); ++ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("subhn2 %0.8h, %1.4s, %2.4s" + : "+w"(result) + : "w"(b), "w"(c) +@@ -16311,7 +14359,7 @@ + __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) + vsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c) { - __builtin_aarch64_simd_xi __o; - int16x8x4_t temp; -- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0))); -- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0))); -- temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (INT64_C (0))); -- temp.val[3] = vcombine_s16 (val.val[3], vcreate_s16 (INT64_C (0))); -+ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (__AARCH64_INT64_C (0))); -+ temp.val[3] = vcombine_s16 (val.val[3], vcreate_s16 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2); -@@ -24789,10 +25141,10 @@ +- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0))); ++ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("subhn2 %0.4s, %1.2d, %2.2d" + : "+w"(result) + : "w"(b), "w"(c) +@@ -16322,7 +14370,7 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c) { - __builtin_aarch64_simd_xi __o; - poly16x8x4_t temp; -- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0))); -- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0))); -- temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (UINT64_C (0))); -- temp.val[3] = vcombine_p16 (val.val[3], vcreate_p16 (UINT64_C (0))); -+ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_p16 (val.val[3], vcreate_p16 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2); -@@ -24805,10 +25157,10 @@ +- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0))); ++ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("subhn2 %0.16b, %1.8h, %2.8h" + : "+w"(result) + : "w"(b), "w"(c) +@@ -16333,7 +14381,7 @@ + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c) { - __builtin_aarch64_simd_xi __o; - int32x4x4_t temp; -- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0))); -- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0))); -- temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (INT64_C (0))); -- temp.val[3] = vcombine_s32 (val.val[3], vcreate_s32 (INT64_C (0))); -+ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0))); -+ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0))); -+ temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (__AARCH64_INT64_C (0))); -+ temp.val[3] = vcombine_s32 (val.val[3], vcreate_s32 (__AARCH64_INT64_C (0))); - __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[2], 2); -@@ -24821,10 +25173,10 @@ +- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0))); ++ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0))); + __asm__ ("subhn2 %0.8h, %1.4s, %2.4s" + : "+w"(result) + : "w"(b), "w"(c) +@@ -16344,7 +14392,7 @@ + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vsubhn_high_u64 (uint32x2_t a, uint64x2_t b, uint64x2_t c) { - __builtin_aarch64_simd_xi __o; - uint8x16x4_t temp; -- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0))); -- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0))); -- temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (UINT64_C (0))); -- temp.val[3] = vcombine_u8 (val.val[3], vcreate_u8 (UINT64_C (0))); -+ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_u8 (val.val[3], vcreate_u8 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2); -@@ -24837,10 +25189,10 @@ +- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0))); ++ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0))); + __asm__ ("subhn2 %0.4s, %1.2d, %2.2d" + : "+w"(result) + : "w"(b), "w"(c) +@@ -18309,86 +16357,6 @@ + return result; + } + +-__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +-vaddv_s32 (int32x2_t a) +-{ +- int32_t result; +- __asm__ ("addp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +-vaddv_u32 (uint32x2_t a) +-{ +- uint32_t result; +- __asm__ ("addp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vmaxnmv_f32 (float32x2_t a) +-{ +- float32_t result; +- __asm__ ("fmaxnmp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +-vminnmv_f32 (float32x2_t a) +-{ +- float32_t result; +- __asm__ ("fminnmp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vmaxnmvq_f64 (float64x2_t a) +-{ +- float64_t result; +- __asm__ ("fmaxnmp %0.2d, %1.2d, %1.2d" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +-vmaxv_s32 (int32x2_t a) +-{ +- int32_t result; +- __asm__ ("smaxp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +-vmaxv_u32 (uint32x2_t a) +-{ +- uint32_t result; +- __asm__ ("umaxp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +-vminnmvq_f64 (float64x2_t a) +-{ +- float64_t result; +- __asm__ ("fminnmp %0.2d, %1.2d, %1.2d" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +-vminv_s32 (int32x2_t a) +-{ +- int32_t result; +- __asm__ ("sminp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- +-__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +-vminv_u32 (uint32x2_t a) +-{ +- uint32_t result; +- __asm__ ("uminp %0.2s, %1.2s, %1.2s" : "=w"(result) : "w"(a) : ); +- return result; +-} +- + __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) + vpaddd_s64 (int64x2_t __a) { - __builtin_aarch64_simd_xi __o; - uint16x8x4_t temp; -- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0))); -- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0))); -- temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (UINT64_C (0))); -- temp.val[3] = vcombine_u16 (val.val[3], vcreate_u16 (UINT64_C (0))); -+ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_u16 (val.val[3], vcreate_u16 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2); -@@ -24853,10 +25205,10 @@ +@@ -19022,7 +16990,7 @@ + vtbl1_s8 (int8x8_t tab, int8x8_t idx) { - __builtin_aarch64_simd_xi __o; - uint32x4x4_t temp; -- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0))); -- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0))); -- temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (UINT64_C (0))); -- temp.val[3] = vcombine_u32 (val.val[3], vcreate_u32 (UINT64_C (0))); -+ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_u32 (val.val[3], vcreate_u32 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[2], 2); -@@ -24869,10 +25221,10 @@ + int8x8_t result; +- int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (UINT64_C (0x0))); ++ int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("tbl %0.8b, {%1.16b}, %2.8b" + : "=w"(result) + : "w"(temp), "w"(idx) +@@ -19034,7 +17002,7 @@ + vtbl1_u8 (uint8x8_t tab, uint8x8_t idx) { - __builtin_aarch64_simd_xi __o; - float32x4x4_t temp; -- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0))); -- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0))); -- temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (UINT64_C (0))); -- temp.val[3] = vcombine_f32 (val.val[3], vcreate_f32 (UINT64_C (0))); -+ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0))); -+ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0))); -+ temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (__AARCH64_UINT64_C (0))); -+ temp.val[3] = vcombine_f32 (val.val[3], vcreate_f32 (__AARCH64_UINT64_C (0))); - __o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[0], 0); - __o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[1], 1); - __o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[2], 2); -@@ -25159,7 +25511,7 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vtst_s64 (int64x1_t __a, int64x1_t __b) + uint8x8_t result; +- uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (UINT64_C (0x0))); ++ uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("tbl %0.8b, {%1.16b}, %2.8b" + : "=w"(result) + : "w"(temp), "w"(idx) +@@ -19046,7 +17014,7 @@ + vtbl1_p8 (poly8x8_t tab, uint8x8_t idx) { -- return (uint64x1_t) __builtin_aarch64_cmtstdi (__a, __b); -+ return (__a & __b) ? -1ll : 0ll; - } - - __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -@@ -25186,8 +25538,7 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vtst_u64 (uint64x1_t __a, uint64x1_t __b) + poly8x8_t result; +- poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (UINT64_C (0x0))); ++ poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("tbl %0.8b, {%1.16b}, %2.8b" + : "=w"(result) + : "w"(temp), "w"(idx) +@@ -19096,7 +17064,7 @@ + int8x8_t result; + int8x16x2_t temp; + temp.val[0] = vcombine_s8 (tab.val[0], tab.val[1]); +- temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (UINT64_C (0x0))); ++ temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t" + "tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t" + : "=w"(result) +@@ -19111,7 +17079,7 @@ + uint8x8_t result; + uint8x16x2_t temp; + temp.val[0] = vcombine_u8 (tab.val[0], tab.val[1]); +- temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (UINT64_C (0x0))); ++ temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t" + "tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t" + : "=w"(result) +@@ -19126,7 +17094,7 @@ + poly8x8_t result; + poly8x16x2_t temp; + temp.val[0] = vcombine_p8 (tab.val[0], tab.val[1]); +- temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (UINT64_C (0x0))); ++ temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t" + "tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t" + : "=w"(result) +@@ -19185,7 +17153,7 @@ { -- return (uint64x1_t) __builtin_aarch64_cmtstdi ((int64x1_t) __a, -- (int64x1_t) __b); -+ return (__a & __b) ? -1ll : 0ll; - } - - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -@@ -25245,14 +25596,13 @@ - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vtstd_s64 (int64x1_t __a, int64x1_t __b) + int8x8_t result; + int8x8_t tmp1; +- int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (UINT64_C (0x0))); ++ int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("movi %0.8b, 8\n\t" + "cmhs %0.8b, %3.8b, %0.8b\n\t" + "tbl %1.8b, {%2.16b}, %3.8b\n\t" +@@ -19201,7 +17169,7 @@ { -- return (uint64x1_t) __builtin_aarch64_cmtstdi (__a, __b); -+ return (__a & __b) ? -1ll : 0ll; - } - - __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) - vtstd_u64 (uint64x1_t __a, uint64x1_t __b) + uint8x8_t result; + uint8x8_t tmp1; +- uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (UINT64_C (0x0))); ++ uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("movi %0.8b, 8\n\t" + "cmhs %0.8b, %3.8b, %0.8b\n\t" + "tbl %1.8b, {%2.16b}, %3.8b\n\t" +@@ -19217,7 +17185,7 @@ { -- return (uint64x1_t) __builtin_aarch64_cmtstdi ((int64x1_t) __a, -- (int64x1_t) __b); -+ return (__a & __b) ? -1ll : 0ll; - } - - /* vuqadd */ -@@ -25371,4 +25721,31 @@ - - /* End of optimal implementations in approved order. */ - -+#undef __aarch64_vget_lane_any -+#undef __aarch64_vget_lane_f32 -+#undef __aarch64_vget_lane_f64 -+#undef __aarch64_vget_lane_p8 -+#undef __aarch64_vget_lane_p16 -+#undef __aarch64_vget_lane_s8 -+#undef __aarch64_vget_lane_s16 -+#undef __aarch64_vget_lane_s32 -+#undef __aarch64_vget_lane_s64 -+#undef __aarch64_vget_lane_u8 -+#undef __aarch64_vget_lane_u16 -+#undef __aarch64_vget_lane_u32 -+#undef __aarch64_vget_lane_u64 -+ -+#undef __aarch64_vgetq_lane_f32 -+#undef __aarch64_vgetq_lane_f64 -+#undef __aarch64_vgetq_lane_p8 -+#undef __aarch64_vgetq_lane_p16 -+#undef __aarch64_vgetq_lane_s8 -+#undef __aarch64_vgetq_lane_s16 -+#undef __aarch64_vgetq_lane_s32 -+#undef __aarch64_vgetq_lane_s64 -+#undef __aarch64_vgetq_lane_u8 -+#undef __aarch64_vgetq_lane_u16 -+#undef __aarch64_vgetq_lane_u32 -+#undef __aarch64_vgetq_lane_u64 -+ - #endif ---- a/src/gcc/config/aarch64/aarch64.md -+++ b/src/gcc/config/aarch64/aarch64.md -@@ -68,14 +68,19 @@ - (define_c_enum "unspec" [ - UNSPEC_CASESI - UNSPEC_CLS -+ UNSPEC_FRECPE -+ UNSPEC_FRECPS -+ UNSPEC_FRECPX - UNSPEC_FRINTA - UNSPEC_FRINTI - UNSPEC_FRINTM -+ UNSPEC_FRINTN - UNSPEC_FRINTP - UNSPEC_FRINTX - UNSPEC_FRINTZ - UNSPEC_GOTSMALLPIC - UNSPEC_GOTSMALLTLS -+ UNSPEC_GOTTINYPIC - UNSPEC_LD2 - UNSPEC_LD3 - UNSPEC_LD4 -@@ -230,6 +235,9 @@ - fmovf2i,\ - fmovi2f,\ - fmul,\ -+ frecpe,\ -+ frecps,\ -+ frecpx,\ - frint,\ - fsqrt,\ - load_acq,\ -@@ -763,19 +771,41 @@ - ) - - (define_insn "*mov_aarch64" -- [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,r,m, r,*w") -- (match_operand:SHORT 1 "general_operand" " r,M,m,rZ,*w,r"))] -+ [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w") -+ (match_operand:SHORT 1 "general_operand" " r,M,D,m, m,rZ,*w,*w, r,*w"))] - "(register_operand (operands[0], mode) - || aarch64_reg_or_zero (operands[1], mode))" -- "@ -- mov\\t%w0, %w1 -- mov\\t%w0, %1 -- ldr\\t%w0, %1 -- str\\t%w1, %0 -- umov\\t%w0, %1.[0] -- dup\\t%0., %w1" -- [(set_attr "v8type" "move,alu,load1,store1,*,*") -- (set_attr "simd_type" "*,*,*,*,simd_movgp,simd_dupgp") -+{ -+ switch (which_alternative) -+ { -+ case 0: -+ return "mov\t%w0, %w1"; -+ case 1: -+ return "mov\t%w0, %1"; -+ case 2: -+ return aarch64_output_scalar_simd_mov_immediate (operands[1], -+ mode); -+ case 3: -+ return "ldr\t%w0, %1"; -+ case 4: -+ return "ldr\t%0, %1"; -+ case 5: -+ return "str\t%w1, %0"; -+ case 6: -+ return "str\t%1, %0"; -+ case 7: -+ return "umov\t%w0, %1.[0]"; -+ case 8: -+ return "dup\t%0., %w1"; -+ case 9: -+ return "dup\t%0, %1.[0]"; -+ default: -+ gcc_unreachable (); -+ } -+} -+ [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*") -+ (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup") -+ (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes") - (set_attr "mode" "") - (set_attr "simd_mode" "")] - ) -@@ -797,8 +827,8 @@ - ) - - (define_insn "*movsi_aarch64" -- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w") -- (match_operand:SI 1 "aarch64_mov_operand" " r,M,m,rZ,rZ,*w,*w"))] -+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,*w,m, m,*w, r,*w") -+ (match_operand:SI 1 "aarch64_mov_operand" " r,M,m, m,rZ,*w,rZ,*w,*w"))] - "(register_operand (operands[0], SImode) - || aarch64_reg_or_zero (operands[1], SImode))" - "@ -@@ -805,18 +835,20 @@ - mov\\t%w0, %w1 - mov\\t%w0, %1 - ldr\\t%w0, %1 -+ ldr\\t%s0, %1 - str\\t%w1, %0 -+ str\\t%s1, %0 - fmov\\t%s0, %w1 - fmov\\t%w0, %s1 - fmov\\t%s0, %s1" -- [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov") -+ [(set_attr "v8type" "move,alu,load1,load1,store1,store1,fmov,fmov,fmov") - (set_attr "mode" "SI") -- (set_attr "fp" "*,*,*,*,yes,yes,yes")] -+ (set_attr "fp" "*,*,*,yes,*,yes,yes,yes,yes")] - ) - - (define_insn "*movdi_aarch64" -- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r, r, *w, r,*w,w") -- (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))] -+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w") -+ (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))] - "(register_operand (operands[0], DImode) - || aarch64_reg_or_zero (operands[1], DImode))" - "@ -@@ -825,7 +857,9 @@ - mov\\t%x0, %1 - mov\\t%x0, %1 - ldr\\t%x0, %1 -+ ldr\\t%d0, %1 - str\\t%x1, %0 -+ str\\t%d1, %0 - adr\\t%x0, %a1 - adrp\\t%x0, %A1 - fmov\\t%d0, %x1 -@@ -832,10 +866,10 @@ - fmov\\t%x0, %d1 - fmov\\t%d0, %d1 - movi\\t%d0, %1" -- [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov") -+ [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov") - (set_attr "mode" "DI") -- (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,*") -- (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,yes")] -+ (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*") -+ (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")] - ) - - (define_insn "insv_imm" -@@ -843,9 +877,8 @@ - (const_int 16) - (match_operand:GPI 1 "const_int_operand" "n")) - (match_operand:GPI 2 "const_int_operand" "n"))] -- "INTVAL (operands[1]) < GET_MODE_BITSIZE (mode) -- && INTVAL (operands[1]) % 16 == 0 -- && UINTVAL (operands[2]) <= 0xffff" -+ "UINTVAL (operands[1]) < GET_MODE_BITSIZE (mode) -+ && UINTVAL (operands[1]) % 16 == 0" - "movk\\t%0, %X2, lsl %1" - [(set_attr "v8type" "movk") - (set_attr "mode" "")] -@@ -982,9 +1015,9 @@ - || register_operand (operands[1], TFmode))" - "@ - orr\\t%0.16b, %1.16b, %1.16b -- mov\\t%0, %1\;mov\\t%H0, %H1 -- fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1 -- fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1] -+ # -+ # -+ # - movi\\t%0.2d, #0 - fmov\\t%s0, wzr - ldr\\t%q0, %1 -@@ -998,6 +1031,17 @@ - (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")] - ) - -+(define_split -+ [(set (match_operand:TF 0 "register_operand" "") -+ (match_operand:TF 1 "aarch64_reg_or_imm" ""))] -+ "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])" -+ [(const_int 0)] -+ { -+ aarch64_split_128bit_move (operands[0], operands[1]); -+ DONE; -+ } -+) -+ - ;; Operands 1 and 3 are tied together by the final condition; so we allow - ;; fairly lax checking on the second memory operation. - (define_insn "load_pair" -@@ -1150,13 +1194,14 @@ - ) - - (define_insn "*zero_extend2_aarch64" -- [(set (match_operand:GPI 0 "register_operand" "=r,r") -- (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))] -+ [(set (match_operand:GPI 0 "register_operand" "=r,r,*w") -+ (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))] - "" - "@ - uxt\t%0, %w1 -- ldr\t%w0, %1" -- [(set_attr "v8type" "extend,load1") -+ ldr\t%w0, %1 -+ ldr\t%0, %1" -+ [(set_attr "v8type" "extend,load1,load1") - (set_attr "mode" "")] - ) + poly8x8_t result; + poly8x8_t tmp1; +- poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (UINT64_C (0x0))); ++ poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("movi %0.8b, 8\n\t" + "cmhs %0.8b, %3.8b, %0.8b\n\t" + "tbl %1.8b, {%2.16b}, %3.8b\n\t" +@@ -19271,7 +17239,7 @@ + int8x8_t tmp1; + int8x16x2_t temp; + temp.val[0] = vcombine_s8 (tab.val[0], tab.val[1]); +- temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (UINT64_C (0x0))); ++ temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t" + "movi %0.8b, 24\n\t" + "cmhs %0.8b, %3.8b, %0.8b\n\t" +@@ -19290,7 +17258,7 @@ + uint8x8_t tmp1; + uint8x16x2_t temp; + temp.val[0] = vcombine_u8 (tab.val[0], tab.val[1]); +- temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (UINT64_C (0x0))); ++ temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t" + "movi %0.8b, 24\n\t" + "cmhs %0.8b, %3.8b, %0.8b\n\t" +@@ -19309,7 +17277,7 @@ + poly8x8_t tmp1; + poly8x16x2_t temp; + temp.val[0] = vcombine_p8 (tab.val[0], tab.val[1]); +- temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (UINT64_C (0x0))); ++ temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (__AARCH64_UINT64_C (0x0))); + __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t" + "movi %0.8b, 24\n\t" + "cmhs %0.8b, %3.8b, %0.8b\n\t" +@@ -19370,6 +17338,80 @@ -@@ -1287,6 +1332,112 @@ - (set_attr "mode" "SI")] - ) + /* Start of optimal implementations in approved order. */ -+(define_insn "*adds_mul_imm_" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (plus:GPI (mult:GPI -+ (match_operand:GPI 1 "register_operand" "r") -+ (match_operand:QI 2 "aarch64_pwr_2_" "n")) -+ (match_operand:GPI 3 "register_operand" "rk")) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (plus:GPI (mult:GPI (match_dup 1) (match_dup 2)) -+ (match_dup 3)))] -+ "" -+ "adds\\t%0, %3, %1, lsl %p2" -+ [(set_attr "v8type" "alus_shift") -+ (set_attr "mode" "")] -+) -+ -+(define_insn "*subs_mul_imm_" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (minus:GPI (match_operand:GPI 1 "register_operand" "rk") -+ (mult:GPI -+ (match_operand:GPI 2 "register_operand" "r") -+ (match_operand:QI 3 "aarch64_pwr_2_" "n"))) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (minus:GPI (match_dup 1) -+ (mult:GPI (match_dup 2) (match_dup 3))))] -+ "" -+ "subs\\t%0, %1, %2, lsl %p3" -+ [(set_attr "v8type" "alus_shift") -+ (set_attr "mode" "")] -+) -+ -+(define_insn "*adds__" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (plus:GPI -+ (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r")) -+ (match_operand:GPI 2 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))] -+ "" -+ "adds\\t%0, %2, %1, xt" -+ [(set_attr "v8type" "alus_ext") -+ (set_attr "mode" "")] -+) -+ -+(define_insn "*subs__" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (minus:GPI (match_operand:GPI 1 "register_operand" "r") -+ (ANY_EXTEND:GPI -+ (match_operand:ALLX 2 "register_operand" "r"))) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))] -+ "" -+ "subs\\t%0, %1, %2, xt" -+ [(set_attr "v8type" "alus_ext") -+ (set_attr "mode" "")] -+) -+ -+(define_insn "*adds__multp2" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (plus:GPI (ANY_EXTRACT:GPI -+ (mult:GPI (match_operand:GPI 1 "register_operand" "r") -+ (match_operand 2 "aarch64_pwr_imm3" "Up3")) -+ (match_operand 3 "const_int_operand" "n") -+ (const_int 0)) -+ (match_operand:GPI 4 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2)) -+ (match_dup 3) -+ (const_int 0)) -+ (match_dup 4)))] -+ "aarch64_is_extend_from_extract (mode, operands[2], operands[3])" -+ "adds\\t%0, %4, %1, xt%e3 %p2" -+ [(set_attr "v8type" "alus_ext") -+ (set_attr "mode" "")] -+) -+ -+(define_insn "*subs__multp2" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (minus:GPI (match_operand:GPI 4 "register_operand" "r") -+ (ANY_EXTRACT:GPI -+ (mult:GPI (match_operand:GPI 1 "register_operand" "r") -+ (match_operand 2 "aarch64_pwr_imm3" "Up3")) -+ (match_operand 3 "const_int_operand" "n") -+ (const_int 0))) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI -+ (mult:GPI (match_dup 1) (match_dup 2)) -+ (match_dup 3) -+ (const_int 0))))] -+ "aarch64_is_extend_from_extract (mode, operands[2], operands[3])" -+ "subs\\t%0, %4, %1, xt%e3 %p2" -+ [(set_attr "v8type" "alus_ext") -+ (set_attr "mode" "")] -+) ++/* vabs */ + - (define_insn "*add3nr_compare0" - [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ -@@ -1302,12 +1453,12 @@ - ) - - (define_insn "*compare_neg" -- [(set (reg:CC CC_REGNUM) -- (compare:CC -- (match_operand:GPI 0 "register_operand" "r") -- (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))] -+ [(set (reg:CC_SWP CC_REGNUM) -+ (compare:CC_SWP -+ (neg:GPI (match_operand:GPI 0 "register_operand" "r")) -+ (match_operand:GPI 1 "register_operand" "r")))] - "" -- "cmn\\t%0, %1" -+ "cmn\\t%1, %0" - [(set_attr "v8type" "alus") - (set_attr "mode" "")] - ) -@@ -1791,6 +1942,34 @@ - (set_attr "mode" "SI")] - ) - -+(define_insn "*sub3_carryin" -+ [(set -+ (match_operand:GPI 0 "register_operand" "=r") -+ (minus:GPI (minus:GPI -+ (match_operand:GPI 1 "register_operand" "r") -+ (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))) -+ (match_operand:GPI 2 "register_operand" "r")))] -+ "" -+ "sbc\\t%0, %1, %2" -+ [(set_attr "v8type" "adc") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vabs_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_absv2sf (__a); ++} + -+;; zero_extend version of the above -+(define_insn "*subsi3_carryin_uxtw" -+ [(set -+ (match_operand:DI 0 "register_operand" "=r") -+ (zero_extend:DI -+ (minus:SI (minus:SI -+ (match_operand:SI 1 "register_operand" "r") -+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))) -+ (match_operand:SI 2 "register_operand" "r"))))] -+ "" -+ "sbc\\t%w0, %w1, %w2" -+ [(set_attr "v8type" "adc") -+ (set_attr "mode" "SI")] -+) ++__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) ++vabs_f64 (float64x1_t __a) ++{ ++ return __builtin_fabs (__a); ++} + - (define_insn "*sub_uxt_multp2" - [(set (match_operand:GPI 0 "register_operand" "=rk") - (minus:GPI (match_operand:GPI 4 "register_operand" "r") -@@ -1825,6 +2004,38 @@ - (set_attr "mode" "SI")] - ) - -+(define_insn_and_split "absdi2" -+ [(set (match_operand:DI 0 "register_operand" "=r,w") -+ (abs:DI (match_operand:DI 1 "register_operand" "r,w"))) -+ (clobber (match_scratch:DI 2 "=&r,X"))] -+ "" -+ "@ -+ # -+ abs\\t%d0, %d1" -+ "reload_completed -+ && GP_REGNUM_P (REGNO (operands[0])) -+ && GP_REGNUM_P (REGNO (operands[1]))" -+ [(const_int 0)] -+ { -+ emit_insn (gen_rtx_SET (VOIDmode, operands[2], -+ gen_rtx_XOR (DImode, -+ gen_rtx_ASHIFTRT (DImode, -+ operands[1], -+ GEN_INT (63)), -+ operands[1]))); -+ emit_insn (gen_rtx_SET (VOIDmode, -+ operands[0], -+ gen_rtx_MINUS (DImode, -+ operands[2], -+ gen_rtx_ASHIFTRT (DImode, -+ operands[1], -+ GEN_INT (63))))); -+ DONE; -+ } -+ [(set_attr "v8type" "alu") -+ (set_attr "mode" "DI")] -+) ++__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) ++vabs_s8 (int8x8_t __a) ++{ ++ return __builtin_aarch64_absv8qi (__a); ++} + - (define_insn "neg2" - [(set (match_operand:GPI 0 "register_operand" "=r") - (neg:GPI (match_operand:GPI 1 "register_operand" "r")))] -@@ -1844,6 +2055,27 @@ - (set_attr "mode" "SI")] - ) - -+(define_insn "*ngc" -+ [(set (match_operand:GPI 0 "register_operand" "=r") -+ (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))) -+ (match_operand:GPI 1 "register_operand" "r")))] -+ "" -+ "ngc\\t%0, %1" -+ [(set_attr "v8type" "adc") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) ++vabs_s16 (int16x4_t __a) ++{ ++ return __builtin_aarch64_absv4hi (__a); ++} + -+(define_insn "*ngcsi_uxtw" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (zero_extend:DI -+ (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))) -+ (match_operand:SI 1 "register_operand" "r"))))] -+ "" -+ "ngc\\t%w0, %w1" -+ [(set_attr "v8type" "adc") -+ (set_attr "mode" "SI")] -+) ++__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) ++vabs_s32 (int32x2_t __a) ++{ ++ return __builtin_aarch64_absv2si (__a); ++} + - (define_insn "*neg2_compare0" - [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r")) -@@ -1869,6 +2101,21 @@ - (set_attr "mode" "SI")] - ) - -+(define_insn "*neg_3_compare0" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (neg:GPI (ASHIFT:GPI -+ (match_operand:GPI 1 "register_operand" "r") -+ (match_operand:QI 2 "aarch64_shift_imm_" "n"))) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))] -+ "" -+ "negs\\t%0, %1, %2" -+ [(set_attr "v8type" "alus_shift") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) ++vabs_s64 (int64x1_t __a) ++{ ++ return __builtin_llabs (__a); ++} + - (define_insn "*neg__2" - [(set (match_operand:GPI 0 "register_operand" "=r") - (neg:GPI (ASHIFT:GPI -@@ -2158,6 +2405,18 @@ - (set_attr "mode" "")] - ) - -+(define_insn "*cmp_swp__shft_" -+ [(set (reg:CC_SWP CC_REGNUM) -+ (compare:CC_SWP (ashift:GPI -+ (ANY_EXTEND:GPI -+ (match_operand:ALLX 0 "register_operand" "r")) -+ (match_operand 1 "aarch64_imm3" "Ui3")) -+ (match_operand:GPI 2 "register_operand" "r")))] -+ "" -+ "cmp\\t%2, %0, xt %1" -+ [(set_attr "v8type" "alus_ext") -+ (set_attr "mode" "")] -+) - - ;; ------------------------------------------------------------------- - ;; Store-flag and conditional select insns -@@ -2434,6 +2693,69 @@ - [(set_attr "v8type" "logic,logic_imm") - (set_attr "mode" "SI")]) - -+(define_insn "*and3_compare0" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:GPI (match_operand:GPI 1 "register_operand" "%r,r") -+ (match_operand:GPI 2 "aarch64_logical_operand" "r,")) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r,r") -+ (and:GPI (match_dup 1) (match_dup 2)))] -+ "" -+ "ands\\t%0, %1, %2" -+ [(set_attr "v8type" "logics,logics_imm") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vabsq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_absv4sf (__a); ++} + -+;; zero_extend version of above -+(define_insn "*andsi3_compare0_uxtw" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:SI (match_operand:SI 1 "register_operand" "%r,r") -+ (match_operand:SI 2 "aarch64_logical_operand" "r,K")) -+ (const_int 0))) -+ (set (match_operand:DI 0 "register_operand" "=r,r") -+ (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] -+ "" -+ "ands\\t%w0, %w1, %w2" -+ [(set_attr "v8type" "logics,logics_imm") -+ (set_attr "mode" "SI")] -+) ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vabsq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_absv2df (__a); ++} + -+(define_insn "*and_3_compare0" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:GPI (SHIFT:GPI -+ (match_operand:GPI 1 "register_operand" "r") -+ (match_operand:QI 2 "aarch64_shift_imm_" "n")) -+ (match_operand:GPI 3 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))] -+ "" -+ "ands\\t%0, %3, %1, %2" -+ [(set_attr "v8type" "logics_shift") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) ++vabsq_s8 (int8x16_t __a) ++{ ++ return __builtin_aarch64_absv16qi (__a); ++} + -+;; zero_extend version of above -+(define_insn "*and_si3_compare0_uxtw" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:SI (SHIFT:SI -+ (match_operand:SI 1 "register_operand" "r") -+ (match_operand:QI 2 "aarch64_shift_imm_si" "n")) -+ (match_operand:SI 3 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:DI 0 "register_operand" "=r") -+ (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2)) -+ (match_dup 3))))] -+ "" -+ "ands\\t%w0, %w3, %w1, %2" -+ [(set_attr "v8type" "logics_shift") -+ (set_attr "mode" "SI")] -+) ++__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) ++vabsq_s16 (int16x8_t __a) ++{ ++ return __builtin_aarch64_absv8hi (__a); ++} + - (define_insn "*_3" - [(set (match_operand:GPI 0 "register_operand" "=r") - (LOGICAL:GPI (SHIFT:GPI -@@ -2485,6 +2807,35 @@ - [(set_attr "v8type" "logic") - (set_attr "mode" "")]) - -+(define_insn "*and_one_cmpl3_compare0" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:GPI (not:GPI -+ (match_operand:GPI 1 "register_operand" "r")) -+ (match_operand:GPI 2 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))] -+ "" -+ "bics\\t%0, %2, %1" -+ [(set_attr "v8type" "logics") -+ (set_attr "mode" "")]) ++__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) ++vabsq_s32 (int32x4_t __a) ++{ ++ return __builtin_aarch64_absv4si (__a); ++} + -+;; zero_extend version of above -+(define_insn "*and_one_cmplsi3_compare0_uxtw" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:SI (not:SI -+ (match_operand:SI 1 "register_operand" "r")) -+ (match_operand:SI 2 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:DI 0 "register_operand" "=r") -+ (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))] -+ "" -+ "bics\\t%w0, %w2, %w1" -+ [(set_attr "v8type" "logics") -+ (set_attr "mode" "SI")]) ++__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) ++vabsq_s64 (int64x2_t __a) ++{ ++ return __builtin_aarch64_absv2di (__a); ++} + - (define_insn "*_one_cmpl_3" - [(set (match_operand:GPI 0 "register_operand" "=r") - (LOGICAL:GPI (not:GPI -@@ -2497,6 +2848,43 @@ - [(set_attr "v8type" "logic_shift") - (set_attr "mode" "")]) + /* vadd */ -+(define_insn "*and_one_cmpl_3_compare0" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:GPI (not:GPI -+ (SHIFT:GPI -+ (match_operand:GPI 1 "register_operand" "r") -+ (match_operand:QI 2 "aarch64_shift_imm_" "n"))) -+ (match_operand:GPI 3 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:GPI 0 "register_operand" "=r") -+ (and:GPI (not:GPI -+ (SHIFT:GPI -+ (match_dup 1) (match_dup 2))) (match_dup 3)))] -+ "" -+ "bics\\t%0, %3, %1, %2" -+ [(set_attr "v8type" "logics_shift") -+ (set_attr "mode" "")]) + __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) +@@ -19384,8 +17426,238 @@ + return __a + __b; + } + +-/* vceq */ ++/* vaddv */ + ++__extension__ static __inline int8_t __attribute__ ((__always_inline__)) ++vaddv_s8 (int8x8_t __a) ++{ ++ return vget_lane_s8 (__builtin_aarch64_reduc_splus_v8qi (__a), 0); ++} + -+;; zero_extend version of above -+(define_insn "*and_one_cmpl_si3_compare0_uxtw" -+ [(set (reg:CC_NZ CC_REGNUM) -+ (compare:CC_NZ -+ (and:SI (not:SI -+ (SHIFT:SI -+ (match_operand:SI 1 "register_operand" "r") -+ (match_operand:QI 2 "aarch64_shift_imm_si" "n"))) -+ (match_operand:SI 3 "register_operand" "r")) -+ (const_int 0))) -+ (set (match_operand:DI 0 "register_operand" "=r") -+ (zero_extend:DI (and:SI -+ (not:SI -+ (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))] -+ "" -+ "bics\\t%w0, %w3, %w1, %2" -+ [(set_attr "v8type" "logics_shift") -+ (set_attr "mode" "SI")]) ++__extension__ static __inline int16_t __attribute__ ((__always_inline__)) ++vaddv_s16 (int16x4_t __a) ++{ ++ return vget_lane_s16 (__builtin_aarch64_reduc_splus_v4hi (__a), 0); ++} + - (define_insn "clz2" - [(set (match_operand:GPI 0 "register_operand" "=r") - (clz:GPI (match_operand:GPI 1 "register_operand" "r")))] -@@ -2704,6 +3092,62 @@ - (set_attr "mode" "")] - ) - -+(define_insn "*extr5_insn" -+ [(set (match_operand:GPI 0 "register_operand" "=r") -+ (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") -+ (match_operand 3 "const_int_operand" "n")) -+ (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r") -+ (match_operand 4 "const_int_operand" "n"))))] -+ "UINTVAL (operands[3]) < GET_MODE_BITSIZE (mode) && -+ (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (mode))" -+ "extr\\t%0, %1, %2, %4" -+ [(set_attr "v8type" "shift") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vaddv_s32 (int32x2_t __a) ++{ ++ return vget_lane_s32 (__builtin_aarch64_reduc_splus_v2si (__a), 0); ++} + -+;; zero_extend version of the above -+(define_insn "*extrsi5_insn_uxtw" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (zero_extend:DI -+ (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand 3 "const_int_operand" "n")) -+ (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") -+ (match_operand 4 "const_int_operand" "n")))))] -+ "UINTVAL (operands[3]) < 32 && -+ (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)" -+ "extr\\t%w0, %w1, %w2, %4" -+ [(set_attr "v8type" "shift") -+ (set_attr "mode" "SI")] -+) ++__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) ++vaddv_u8 (uint8x8_t __a) ++{ ++ return vget_lane_u8 ((uint8x8_t) ++ __builtin_aarch64_reduc_uplus_v8qi ((int8x8_t) __a), 0); ++} + -+(define_insn "*ror3_insn" -+ [(set (match_operand:GPI 0 "register_operand" "=r") -+ (rotate:GPI (match_operand:GPI 1 "register_operand" "r") -+ (match_operand 2 "const_int_operand" "n")))] -+ "UINTVAL (operands[2]) < GET_MODE_BITSIZE (mode)" ++__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) ++vaddv_u16 (uint16x4_t __a) +{ -+ operands[3] = GEN_INT ( - UINTVAL (operands[2])); -+ return "ror\\t%0, %1, %3"; ++ return vget_lane_u16 ((uint16x4_t) ++ __builtin_aarch64_reduc_uplus_v4hi ((int16x4_t) __a), 0); +} -+ [(set_attr "v8type" "shift") -+ (set_attr "mode" "")] -+) + -+;; zero_extend version of the above -+(define_insn "*rorsi3_insn_uxtw" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (zero_extend:DI -+ (rotate:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand 2 "const_int_operand" "n"))))] -+ "UINTVAL (operands[2]) < 32" ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vaddv_u32 (uint32x2_t __a) +{ -+ operands[3] = GEN_INT (32 - UINTVAL (operands[2])); -+ return "ror\\t%w0, %w1, %3"; ++ return vget_lane_u32 ((uint32x2_t) ++ __builtin_aarch64_reduc_uplus_v2si ((int32x2_t) __a), 0); +} -+ [(set_attr "v8type" "shift") -+ (set_attr "mode" "SI")] -+) + - (define_insn "*_ashl" - [(set (match_operand:GPI 0 "register_operand" "=r") - (ANY_EXTEND:GPI -@@ -2770,6 +3214,65 @@ - (set_attr "mode" "")] - ) - -+;; Bitfield Insert (insv) -+(define_expand "insv" -+ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand") -+ (match_operand 1 "const_int_operand") -+ (match_operand 2 "const_int_operand")) -+ (match_operand:GPI 3 "general_operand"))] -+ "" ++__extension__ static __inline int8_t __attribute__ ((__always_inline__)) ++vaddvq_s8 (int8x16_t __a) +{ -+ unsigned HOST_WIDE_INT width = UINTVAL (operands[1]); -+ unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]); -+ rtx value = operands[3]; ++ return vgetq_lane_s8 (__builtin_aarch64_reduc_splus_v16qi (__a), 0); ++} + -+ if (width == 0 || (pos + width) > GET_MODE_BITSIZE (mode)) -+ FAIL; ++__extension__ static __inline int16_t __attribute__ ((__always_inline__)) ++vaddvq_s16 (int16x8_t __a) ++{ ++ return vgetq_lane_s16 (__builtin_aarch64_reduc_splus_v8hi (__a), 0); ++} + -+ if (CONST_INT_P (value)) -+ { -+ unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1; ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vaddvq_s32 (int32x4_t __a) ++{ ++ return vgetq_lane_s32 (__builtin_aarch64_reduc_splus_v4si (__a), 0); ++} + -+ /* Prefer AND/OR for inserting all zeros or all ones. */ -+ if ((UINTVAL (value) & mask) == 0 -+ || (UINTVAL (value) & mask) == mask) -+ FAIL; ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vaddvq_s64 (int64x2_t __a) ++{ ++ return vgetq_lane_s64 (__builtin_aarch64_reduc_splus_v2di (__a), 0); ++} + -+ /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */ -+ if (width == 16 && (pos % 16) == 0) -+ DONE; -+ } -+ operands[3] = force_reg (mode, value); -+}) ++__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) ++vaddvq_u8 (uint8x16_t __a) ++{ ++ return vgetq_lane_u8 ((uint8x16_t) ++ __builtin_aarch64_reduc_uplus_v16qi ((int8x16_t) __a), 0); ++} + -+(define_insn "*insv_reg" -+ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") -+ (match_operand 1 "const_int_operand" "n") -+ (match_operand 2 "const_int_operand" "n")) -+ (match_operand:GPI 3 "register_operand" "r"))] -+ "!(UINTVAL (operands[1]) == 0 -+ || (UINTVAL (operands[2]) + UINTVAL (operands[1]) -+ > GET_MODE_BITSIZE (mode)))" -+ "bfi\\t%0, %3, %2, %1" -+ [(set_attr "v8type" "bfm") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) ++vaddvq_u16 (uint16x8_t __a) ++{ ++ return vgetq_lane_u16 ((uint16x8_t) ++ __builtin_aarch64_reduc_uplus_v8hi ((int16x8_t) __a), 0); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vaddvq_u32 (uint32x4_t __a) ++{ ++ return vgetq_lane_u32 ((uint32x4_t) ++ __builtin_aarch64_reduc_uplus_v4si ((int32x4_t) __a), 0); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vaddvq_u64 (uint64x2_t __a) ++{ ++ return vgetq_lane_u64 ((uint64x2_t) ++ __builtin_aarch64_reduc_uplus_v2di ((int64x2_t) __a), 0); ++} ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vaddv_f32 (float32x2_t __a) ++{ ++ float32x2_t t = __builtin_aarch64_reduc_splus_v2sf (__a); ++ return vget_lane_f32 (t, 0); ++} ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vaddvq_f32 (float32x4_t __a) ++{ ++ float32x4_t t = __builtin_aarch64_reduc_splus_v4sf (__a); ++ return vgetq_lane_f32 (t, 0); ++} + -+(define_insn "*extr_insv_lower_reg" -+ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") -+ (match_operand 1 "const_int_operand" "n") -+ (const_int 0)) -+ (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r") -+ (match_dup 1) -+ (match_operand 3 "const_int_operand" "n")))] -+ "!(UINTVAL (operands[1]) == 0 -+ || (UINTVAL (operands[3]) + UINTVAL (operands[1]) -+ > GET_MODE_BITSIZE (mode)))" -+ "bfxil\\t%0, %2, %3, %1" -+ [(set_attr "v8type" "bfm") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vaddvq_f64 (float64x2_t __a) ++{ ++ float64x2_t t = __builtin_aarch64_reduc_splus_v2df (__a); ++ return vgetq_lane_f64 (t, 0); ++} + - (define_insn "*_shft_" - [(set (match_operand:GPI 0 "register_operand" "=r") - (ashift:GPI (ANY_EXTEND:GPI -@@ -3090,6 +3593,27 @@ - (set_attr "mode" "")] - ) - -+(define_insn "aarch64_frecp" -+ [(set (match_operand:GPF 0 "register_operand" "=w") -+ (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] -+ FRECP))] -+ "TARGET_FLOAT" -+ "frecp\\t%0, %1" -+ [(set_attr "v8type" "frecp") -+ (set_attr "mode" "")] -+) ++/* vcage */ + -+(define_insn "aarch64_frecps" -+ [(set (match_operand:GPF 0 "register_operand" "=w") -+ (unspec:GPF [(match_operand:GPF 1 "register_operand" "w") -+ (match_operand:GPF 2 "register_operand" "w")] -+ UNSPEC_FRECPS))] -+ "TARGET_FLOAT" -+ "frecps\\t%0, %1, %2" -+ [(set_attr "v8type" "frecps") -+ (set_attr "mode" "")] -+) ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcages_f32 (float32_t __a, float32_t __b) ++{ ++ return __builtin_fabsf (__a) >= __builtin_fabsf (__b) ? -1 : 0; ++} + - ;; ------------------------------------------------------------------- - ;; Reload support - ;; ------------------------------------------------------------------- -@@ -3146,9 +3670,9 @@ - ;; after or during reload as we don't want these patterns to start - ;; kicking in during the combiner. - --(define_insn "aarch64_movdi_tilow" -+(define_insn "aarch64_movdi_low" - [(set (match_operand:DI 0 "register_operand" "=r") -- (truncate:DI (match_operand:TI 1 "register_operand" "w")))] -+ (truncate:DI (match_operand:TX 1 "register_operand" "w")))] - "reload_completed || reload_in_progress" - "fmov\\t%x0, %d1" - [(set_attr "v8type" "fmovf2i") -@@ -3156,10 +3680,10 @@ - (set_attr "length" "4") - ]) - --(define_insn "aarch64_movdi_tihigh" -+(define_insn "aarch64_movdi_high" - [(set (match_operand:DI 0 "register_operand" "=r") - (truncate:DI -- (lshiftrt:TI (match_operand:TI 1 "register_operand" "w") -+ (lshiftrt:TX (match_operand:TX 1 "register_operand" "w") - (const_int 64))))] - "reload_completed || reload_in_progress" - "fmov\\t%x0, %1.d[1]" -@@ -3168,24 +3692,22 @@ - (set_attr "length" "4") - ]) - --(define_insn "aarch64_movtihigh_di" -- [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w") -+(define_insn "aarch64_movhigh_di" -+ [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w") - (const_int 64) (const_int 64)) -- (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))] -+ (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] - "reload_completed || reload_in_progress" - "fmov\\t%0.d[1], %x1" -- - [(set_attr "v8type" "fmovi2f") - (set_attr "mode" "DI") - (set_attr "length" "4") - ]) - --(define_insn "aarch64_movtilow_di" -- [(set (match_operand:TI 0 "register_operand" "=w") -- (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))] -+(define_insn "aarch64_movlow_di" -+ [(set (match_operand:TX 0 "register_operand" "=w") -+ (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] - "reload_completed || reload_in_progress" - "fmov\\t%d0, %x1" -- - [(set_attr "v8type" "fmovi2f") - (set_attr "mode" "DI") - (set_attr "length" "4") -@@ -3197,7 +3719,6 @@ - (truncate:DI (match_operand:TI 1 "register_operand" "w"))))] - "reload_completed || reload_in_progress" - "fmov\\t%d0, %d1" -- - [(set_attr "v8type" "fmovi2f") - (set_attr "mode" "DI") - (set_attr "length" "4") -@@ -3231,6 +3752,16 @@ - (set_attr "mode" "DI")] - ) - -+(define_insn "ldr_got_tiny" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] -+ UNSPEC_GOTTINYPIC))] -+ "" -+ "ldr\\t%0, %L1" -+ [(set_attr "v8type" "load1") -+ (set_attr "mode" "DI")] -+) ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcage_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return vabs_f32 (__a) >= vabs_f32 (__b); ++} + - (define_insn "aarch64_load_tp_hard" - [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(const_int 0)] UNSPEC_TLS))] ---- a/src/gcc/config/aarch64/aarch64-option-extensions.def -+++ b/src/gcc/config/aarch64/aarch64-option-extensions.def -@@ -35,3 +35,4 @@ - AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, AARCH64_FL_FPSIMD | AARCH64_FL_CRYPTO) - AARCH64_OPT_EXTENSION("simd", AARCH64_FL_FPSIMD, AARCH64_FL_SIMD | AARCH64_FL_CRYPTO) - AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO | AARCH64_FL_FPSIMD, AARCH64_FL_CRYPTO) -+AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, AARCH64_FL_CRC) ---- a/src/gcc/config/aarch64/aarch64-builtins.c -+++ b/src/gcc/config/aarch64/aarch64-builtins.c -@@ -30,6 +30,7 @@ - #include "langhooks.h" - #include "diagnostic-core.h" - #include "optabs.h" -+#include "gimple.h" - - enum aarch64_simd_builtin_type_mode - { -@@ -50,6 +51,7 @@ - T_OI, - T_XI, - T_SI, -+ T_SF, - T_HI, - T_QI, - T_MAX -@@ -72,172 +74,251 @@ - #define oi_UP T_OI - #define xi_UP T_XI - #define si_UP T_SI -+#define sf_UP T_SF - #define hi_UP T_HI - #define qi_UP T_QI - - #define UP(X) X##_UP - --typedef enum -+#define SIMD_MAX_BUILTIN_ARGS 5 ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcageq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return vabsq_f32 (__a) >= vabsq_f32 (__b); ++} + -+enum aarch64_type_qualifiers - { -- AARCH64_SIMD_BINOP, -- AARCH64_SIMD_TERNOP, -- AARCH64_SIMD_QUADOP, -- AARCH64_SIMD_UNOP, -- AARCH64_SIMD_GETLANE, -- AARCH64_SIMD_SETLANE, -- AARCH64_SIMD_CREATE, -- AARCH64_SIMD_DUP, -- AARCH64_SIMD_DUPLANE, -- AARCH64_SIMD_COMBINE, -- AARCH64_SIMD_SPLIT, -- AARCH64_SIMD_LANEMUL, -- AARCH64_SIMD_LANEMULL, -- AARCH64_SIMD_LANEMULH, -- AARCH64_SIMD_LANEMAC, -- AARCH64_SIMD_SCALARMUL, -- AARCH64_SIMD_SCALARMULL, -- AARCH64_SIMD_SCALARMULH, -- AARCH64_SIMD_SCALARMAC, -- AARCH64_SIMD_CONVERT, -- AARCH64_SIMD_FIXCONV, -- AARCH64_SIMD_SELECT, -- AARCH64_SIMD_RESULTPAIR, -- AARCH64_SIMD_REINTERP, -- AARCH64_SIMD_VTBL, -- AARCH64_SIMD_VTBX, -- AARCH64_SIMD_LOAD1, -- AARCH64_SIMD_LOAD1LANE, -- AARCH64_SIMD_STORE1, -- AARCH64_SIMD_STORE1LANE, -- AARCH64_SIMD_LOADSTRUCT, -- AARCH64_SIMD_LOADSTRUCTLANE, -- AARCH64_SIMD_STORESTRUCT, -- AARCH64_SIMD_STORESTRUCTLANE, -- AARCH64_SIMD_LOGICBINOP, -- AARCH64_SIMD_SHIFTINSERT, -- AARCH64_SIMD_SHIFTIMM, -- AARCH64_SIMD_SHIFTACC --} aarch64_simd_itype; -+ /* T foo. */ -+ qualifier_none = 0x0, -+ /* unsigned T foo. */ -+ qualifier_unsigned = 0x1, /* 1 << 0 */ -+ /* const T foo. */ -+ qualifier_const = 0x2, /* 1 << 1 */ -+ /* T *foo. */ -+ qualifier_pointer = 0x4, /* 1 << 2 */ -+ /* const T *foo. */ -+ qualifier_const_pointer = 0x6, /* qualifier_const | qualifier_pointer */ -+ /* Used when expanding arguments if an operand could -+ be an immediate. */ -+ qualifier_immediate = 0x8, /* 1 << 3 */ -+ qualifier_maybe_immediate = 0x10, /* 1 << 4 */ -+ /* void foo (...). */ -+ qualifier_void = 0x20, /* 1 << 5 */ -+ /* Some patterns may have internal operands, this qualifier is an -+ instruction to the initialisation code to skip this operand. */ -+ qualifier_internal = 0x40, /* 1 << 6 */ -+ /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum -+ rather than using the type of the operand. */ -+ qualifier_map_mode = 0x80, /* 1 << 7 */ -+ /* qualifier_pointer | qualifier_map_mode */ -+ qualifier_pointer_map_mode = 0x84, -+ /* qualifier_const_pointer | qualifier_map_mode */ -+ qualifier_const_pointer_map_mode = 0x86, -+ /* Polynomial types. */ -+ qualifier_poly = 0x100 -+}; - - typedef struct - { - const char *name; -- const aarch64_simd_itype itype; - enum aarch64_simd_builtin_type_mode mode; - const enum insn_code code; - unsigned int fcode; -+ enum aarch64_type_qualifiers *qualifiers; - } aarch64_simd_builtin_datum; - --#define CF(N, X) CODE_FOR_aarch64_##N##X -+static enum aarch64_type_qualifiers -+aarch64_types_unop_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_none }; -+#define TYPES_UNOP (aarch64_types_unop_qualifiers) -+static enum aarch64_type_qualifiers -+aarch64_types_unopu_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_unsigned, qualifier_unsigned }; -+#define TYPES_UNOPU (aarch64_types_unopu_qualifiers) -+#define TYPES_CREATE (aarch64_types_unop_qualifiers) -+#define TYPES_REINTERP (aarch64_types_unop_qualifiers) -+static enum aarch64_type_qualifiers -+aarch64_types_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_none, qualifier_maybe_immediate }; -+#define TYPES_BINOP (aarch64_types_binop_qualifiers) -+static enum aarch64_type_qualifiers -+aarch64_types_binopu_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned }; -+#define TYPES_BINOPU (aarch64_types_binopu_qualifiers) -+static enum aarch64_type_qualifiers -+aarch64_types_binopp_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_poly, qualifier_poly, qualifier_poly }; -+#define TYPES_BINOPP (aarch64_types_binopp_qualifiers) - --#define VAR1(T, N, A) \ -- {#N, AARCH64_SIMD_##T, UP (A), CF (N, A), 0}, --#define VAR2(T, N, A, B) \ -- VAR1 (T, N, A) \ -- VAR1 (T, N, B) --#define VAR3(T, N, A, B, C) \ -- VAR2 (T, N, A, B) \ -- VAR1 (T, N, C) --#define VAR4(T, N, A, B, C, D) \ -- VAR3 (T, N, A, B, C) \ -- VAR1 (T, N, D) --#define VAR5(T, N, A, B, C, D, E) \ -- VAR4 (T, N, A, B, C, D) \ -- VAR1 (T, N, E) --#define VAR6(T, N, A, B, C, D, E, F) \ -- VAR5 (T, N, A, B, C, D, E) \ -- VAR1 (T, N, F) --#define VAR7(T, N, A, B, C, D, E, F, G) \ -- VAR6 (T, N, A, B, C, D, E, F) \ -- VAR1 (T, N, G) --#define VAR8(T, N, A, B, C, D, E, F, G, H) \ -- VAR7 (T, N, A, B, C, D, E, F, G) \ -- VAR1 (T, N, H) --#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \ -- VAR8 (T, N, A, B, C, D, E, F, G, H) \ -- VAR1 (T, N, I) --#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \ -- VAR9 (T, N, A, B, C, D, E, F, G, H, I) \ -- VAR1 (T, N, J) --#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \ -- VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \ -- VAR1 (T, N, K) --#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \ -- VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \ -- VAR1 (T, N, L) -+static enum aarch64_type_qualifiers -+aarch64_types_ternop_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_none, qualifier_none, qualifier_none }; -+#define TYPES_TERNOP (aarch64_types_ternop_qualifiers) -+static enum aarch64_type_qualifiers -+aarch64_types_ternopu_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_unsigned, qualifier_unsigned, -+ qualifier_unsigned, qualifier_unsigned }; -+#define TYPES_TERNOPU (aarch64_types_ternopu_qualifiers) - -+static enum aarch64_type_qualifiers -+aarch64_types_quadop_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_none, qualifier_none, -+ qualifier_none, qualifier_none }; -+#define TYPES_QUADOP (aarch64_types_quadop_qualifiers) -+ -+static enum aarch64_type_qualifiers -+aarch64_types_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_none, qualifier_immediate }; -+#define TYPES_GETLANE (aarch64_types_getlane_qualifiers) -+#define TYPES_SHIFTIMM (aarch64_types_getlane_qualifiers) -+static enum aarch64_type_qualifiers -+aarch64_types_setlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate }; -+#define TYPES_SETLANE (aarch64_types_setlane_qualifiers) -+#define TYPES_SHIFTINSERT (aarch64_types_setlane_qualifiers) -+#define TYPES_SHIFTACC (aarch64_types_setlane_qualifiers) -+ -+static enum aarch64_type_qualifiers -+aarch64_types_combine_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_none, qualifier_none }; -+#define TYPES_COMBINE (aarch64_types_combine_qualifiers) -+ -+static enum aarch64_type_qualifiers -+aarch64_types_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_none, qualifier_const_pointer_map_mode }; -+#define TYPES_LOAD1 (aarch64_types_load1_qualifiers) -+#define TYPES_LOADSTRUCT (aarch64_types_load1_qualifiers) -+ -+/* The first argument (return type) of a store should be void type, -+ which we represent with qualifier_void. Their first operand will be -+ a DImode pointer to the location to store to, so we must use -+ qualifier_map_mode | qualifier_pointer to build a pointer to the -+ element type of the vector. */ -+static enum aarch64_type_qualifiers -+aarch64_types_store1_qualifiers[SIMD_MAX_BUILTIN_ARGS] -+ = { qualifier_void, qualifier_pointer_map_mode, qualifier_none }; -+#define TYPES_STORE1 (aarch64_types_store1_qualifiers) -+#define TYPES_STORESTRUCT (aarch64_types_store1_qualifiers) ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcaged_f64 (float64_t __a, float64_t __b) ++{ ++ return __builtin_fabs (__a) >= __builtin_fabs (__b) ? -1 : 0; ++} + -+#define CF0(N, X) CODE_FOR_aarch64_##N##X -+#define CF1(N, X) CODE_FOR_##N##X##1 -+#define CF2(N, X) CODE_FOR_##N##X##2 -+#define CF3(N, X) CODE_FOR_##N##X##3 -+#define CF4(N, X) CODE_FOR_##N##X##4 -+#define CF10(N, X) CODE_FOR_##N##X ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcageq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return vabsq_f64 (__a) >= vabsq_f64 (__b); ++} + -+#define VAR1(T, N, MAP, A) \ -+ {#N, UP (A), CF##MAP (N, A), 0, TYPES_##T}, -+#define VAR2(T, N, MAP, A, B) \ -+ VAR1 (T, N, MAP, A) \ -+ VAR1 (T, N, MAP, B) -+#define VAR3(T, N, MAP, A, B, C) \ -+ VAR2 (T, N, MAP, A, B) \ -+ VAR1 (T, N, MAP, C) -+#define VAR4(T, N, MAP, A, B, C, D) \ -+ VAR3 (T, N, MAP, A, B, C) \ -+ VAR1 (T, N, MAP, D) -+#define VAR5(T, N, MAP, A, B, C, D, E) \ -+ VAR4 (T, N, MAP, A, B, C, D) \ -+ VAR1 (T, N, MAP, E) -+#define VAR6(T, N, MAP, A, B, C, D, E, F) \ -+ VAR5 (T, N, MAP, A, B, C, D, E) \ -+ VAR1 (T, N, MAP, F) -+#define VAR7(T, N, MAP, A, B, C, D, E, F, G) \ -+ VAR6 (T, N, MAP, A, B, C, D, E, F) \ -+ VAR1 (T, N, MAP, G) -+#define VAR8(T, N, MAP, A, B, C, D, E, F, G, H) \ -+ VAR7 (T, N, MAP, A, B, C, D, E, F, G) \ -+ VAR1 (T, N, MAP, H) -+#define VAR9(T, N, MAP, A, B, C, D, E, F, G, H, I) \ -+ VAR8 (T, N, MAP, A, B, C, D, E, F, G, H) \ -+ VAR1 (T, N, MAP, I) -+#define VAR10(T, N, MAP, A, B, C, D, E, F, G, H, I, J) \ -+ VAR9 (T, N, MAP, A, B, C, D, E, F, G, H, I) \ -+ VAR1 (T, N, MAP, J) -+#define VAR11(T, N, MAP, A, B, C, D, E, F, G, H, I, J, K) \ -+ VAR10 (T, N, MAP, A, B, C, D, E, F, G, H, I, J) \ -+ VAR1 (T, N, MAP, K) -+#define VAR12(T, N, MAP, A, B, C, D, E, F, G, H, I, J, K, L) \ -+ VAR11 (T, N, MAP, A, B, C, D, E, F, G, H, I, J, K) \ -+ VAR1 (T, N, MAP, L) ++/* vcagt */ + - /* BUILTIN_ macros should expand to cover the same range of - modes as is given for each define_mode_iterator in - config/aarch64/iterators.md. */ - --#define BUILTIN_DX(T, N) \ -- VAR2 (T, N, di, df) --#define BUILTIN_SDQ_I(T, N) \ -- VAR4 (T, N, qi, hi, si, di) --#define BUILTIN_SD_HSI(T, N) \ -- VAR2 (T, N, hi, si) --#define BUILTIN_V2F(T, N) \ -- VAR2 (T, N, v2sf, v2df) --#define BUILTIN_VALL(T, N) \ -- VAR10 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, v2sf, v4sf, v2df) --#define BUILTIN_VB(T, N) \ -- VAR2 (T, N, v8qi, v16qi) --#define BUILTIN_VD(T, N) \ -- VAR4 (T, N, v8qi, v4hi, v2si, v2sf) --#define BUILTIN_VDC(T, N) \ -- VAR6 (T, N, v8qi, v4hi, v2si, v2sf, di, df) --#define BUILTIN_VDIC(T, N) \ -- VAR3 (T, N, v8qi, v4hi, v2si) --#define BUILTIN_VDN(T, N) \ -- VAR3 (T, N, v4hi, v2si, di) --#define BUILTIN_VDQ(T, N) \ -- VAR7 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) --#define BUILTIN_VDQF(T, N) \ -- VAR3 (T, N, v2sf, v4sf, v2df) --#define BUILTIN_VDQHS(T, N) \ -- VAR4 (T, N, v4hi, v8hi, v2si, v4si) --#define BUILTIN_VDQIF(T, N) \ -- VAR9 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2sf, v4sf, v2df) --#define BUILTIN_VDQM(T, N) \ -- VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si) --#define BUILTIN_VDQV(T, N) \ -- VAR5 (T, N, v8qi, v16qi, v4hi, v8hi, v4si) --#define BUILTIN_VDQ_BHSI(T, N) \ -- VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si) --#define BUILTIN_VDQ_I(T, N) \ -- VAR7 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) --#define BUILTIN_VDW(T, N) \ -- VAR3 (T, N, v8qi, v4hi, v2si) --#define BUILTIN_VD_BHSI(T, N) \ -- VAR3 (T, N, v8qi, v4hi, v2si) --#define BUILTIN_VD_HSI(T, N) \ -- VAR2 (T, N, v4hi, v2si) --#define BUILTIN_VD_RE(T, N) \ -- VAR6 (T, N, v8qi, v4hi, v2si, v2sf, di, df) --#define BUILTIN_VQ(T, N) \ -- VAR6 (T, N, v16qi, v8hi, v4si, v2di, v4sf, v2df) --#define BUILTIN_VQN(T, N) \ -- VAR3 (T, N, v8hi, v4si, v2di) --#define BUILTIN_VQW(T, N) \ -- VAR3 (T, N, v16qi, v8hi, v4si) --#define BUILTIN_VQ_HSI(T, N) \ -- VAR2 (T, N, v8hi, v4si) --#define BUILTIN_VQ_S(T, N) \ -- VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si) --#define BUILTIN_VSDQ_HSI(T, N) \ -- VAR6 (T, N, v4hi, v8hi, v2si, v4si, hi, si) --#define BUILTIN_VSDQ_I(T, N) \ -- VAR11 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si, di) --#define BUILTIN_VSDQ_I_BHSI(T, N) \ -- VAR10 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si) --#define BUILTIN_VSDQ_I_DI(T, N) \ -- VAR8 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, di) --#define BUILTIN_VSD_HSI(T, N) \ -- VAR4 (T, N, v4hi, v2si, hi, si) --#define BUILTIN_VSQN_HSDI(T, N) \ -- VAR6 (T, N, v8hi, v4si, v2di, hi, si, di) --#define BUILTIN_VSTRUCT(T, N) \ -- VAR3 (T, N, oi, ci, xi) -+#define BUILTIN_DX(T, N, MAP) \ -+ VAR2 (T, N, MAP, di, df) -+#define BUILTIN_GPF(T, N, MAP) \ -+ VAR2 (T, N, MAP, sf, df) -+#define BUILTIN_SDQ_I(T, N, MAP) \ -+ VAR4 (T, N, MAP, qi, hi, si, di) -+#define BUILTIN_SD_HSI(T, N, MAP) \ -+ VAR2 (T, N, MAP, hi, si) -+#define BUILTIN_V2F(T, N, MAP) \ -+ VAR2 (T, N, MAP, v2sf, v2df) -+#define BUILTIN_VALL(T, N, MAP) \ -+ VAR10 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, \ -+ v4si, v2di, v2sf, v4sf, v2df) -+#define BUILTIN_VALLDI(T, N, MAP) \ -+ VAR11 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, \ -+ v4si, v2di, v2sf, v4sf, v2df, di) -+#define BUILTIN_VB(T, N, MAP) \ -+ VAR2 (T, N, MAP, v8qi, v16qi) -+#define BUILTIN_VD(T, N, MAP) \ -+ VAR4 (T, N, MAP, v8qi, v4hi, v2si, v2sf) -+#define BUILTIN_VDC(T, N, MAP) \ -+ VAR6 (T, N, MAP, v8qi, v4hi, v2si, v2sf, di, df) -+#define BUILTIN_VDIC(T, N, MAP) \ -+ VAR3 (T, N, MAP, v8qi, v4hi, v2si) -+#define BUILTIN_VDN(T, N, MAP) \ -+ VAR3 (T, N, MAP, v4hi, v2si, di) -+#define BUILTIN_VDQ(T, N, MAP) \ -+ VAR7 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) -+#define BUILTIN_VDQF(T, N, MAP) \ -+ VAR3 (T, N, MAP, v2sf, v4sf, v2df) -+#define BUILTIN_VDQH(T, N, MAP) \ -+ VAR2 (T, N, MAP, v4hi, v8hi) -+#define BUILTIN_VDQHS(T, N, MAP) \ -+ VAR4 (T, N, MAP, v4hi, v8hi, v2si, v4si) -+#define BUILTIN_VDQIF(T, N, MAP) \ -+ VAR9 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2sf, v4sf, v2df) -+#define BUILTIN_VDQM(T, N, MAP) \ -+ VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si) -+#define BUILTIN_VDQV(T, N, MAP) \ -+ VAR5 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v4si) -+#define BUILTIN_VDQ_BHSI(T, N, MAP) \ -+ VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si) -+#define BUILTIN_VDQ_I(T, N, MAP) \ -+ VAR7 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) -+#define BUILTIN_VDW(T, N, MAP) \ -+ VAR3 (T, N, MAP, v8qi, v4hi, v2si) -+#define BUILTIN_VD_BHSI(T, N, MAP) \ -+ VAR3 (T, N, MAP, v8qi, v4hi, v2si) -+#define BUILTIN_VD_HSI(T, N, MAP) \ -+ VAR2 (T, N, MAP, v4hi, v2si) -+#define BUILTIN_VD_RE(T, N, MAP) \ -+ VAR6 (T, N, MAP, v8qi, v4hi, v2si, v2sf, di, df) -+#define BUILTIN_VQ(T, N, MAP) \ -+ VAR6 (T, N, MAP, v16qi, v8hi, v4si, v2di, v4sf, v2df) -+#define BUILTIN_VQN(T, N, MAP) \ -+ VAR3 (T, N, MAP, v8hi, v4si, v2di) -+#define BUILTIN_VQW(T, N, MAP) \ -+ VAR3 (T, N, MAP, v16qi, v8hi, v4si) -+#define BUILTIN_VQ_HSI(T, N, MAP) \ -+ VAR2 (T, N, MAP, v8hi, v4si) -+#define BUILTIN_VQ_S(T, N, MAP) \ -+ VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si) -+#define BUILTIN_VSDQ_HSI(T, N, MAP) \ -+ VAR6 (T, N, MAP, v4hi, v8hi, v2si, v4si, hi, si) -+#define BUILTIN_VSDQ_I(T, N, MAP) \ -+ VAR11 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si, di) -+#define BUILTIN_VSDQ_I_BHSI(T, N, MAP) \ -+ VAR10 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si) -+#define BUILTIN_VSDQ_I_DI(T, N, MAP) \ -+ VAR8 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, di) -+#define BUILTIN_VSD_HSI(T, N, MAP) \ -+ VAR4 (T, N, MAP, v4hi, v2si, hi, si) -+#define BUILTIN_VSQN_HSDI(T, N, MAP) \ -+ VAR6 (T, N, MAP, v8hi, v4si, v2di, hi, si, di) -+#define BUILTIN_VSTRUCT(T, N, MAP) \ -+ VAR3 (T, N, MAP, oi, ci, xi) - - static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = { - #include "aarch64-simd-builtins.def" -@@ -244,8 +325,8 @@ - }; - - #undef VAR1 --#define VAR1(T, N, A) \ -- AARCH64_SIMD_BUILTIN_##N##A, -+#define VAR1(T, N, MAP, A) \ -+ AARCH64_SIMD_BUILTIN_##T##_##N##A, - - enum aarch64_builtins - { -@@ -257,171 +338,218 @@ - AARCH64_BUILTIN_MAX - }; - --#undef BUILTIN_DX --#undef BUILTIN_SDQ_I --#undef BUILTIN_SD_HSI --#undef BUILTIN_V2F --#undef BUILTIN_VALL --#undef BUILTIN_VB --#undef BUILTIN_VD --#undef BUILTIN_VDC --#undef BUILTIN_VDIC --#undef BUILTIN_VDN --#undef BUILTIN_VDQ --#undef BUILTIN_VDQF --#undef BUILTIN_VDQHS --#undef BUILTIN_VDQIF --#undef BUILTIN_VDQM --#undef BUILTIN_VDQV --#undef BUILTIN_VDQ_BHSI --#undef BUILTIN_VDQ_I --#undef BUILTIN_VDW --#undef BUILTIN_VD_BHSI --#undef BUILTIN_VD_HSI --#undef BUILTIN_VD_RE --#undef BUILTIN_VQ --#undef BUILTIN_VQN --#undef BUILTIN_VQW --#undef BUILTIN_VQ_HSI --#undef BUILTIN_VQ_S --#undef BUILTIN_VSDQ_HSI --#undef BUILTIN_VSDQ_I --#undef BUILTIN_VSDQ_I_BHSI --#undef BUILTIN_VSDQ_I_DI --#undef BUILTIN_VSD_HSI --#undef BUILTIN_VSQN_HSDI --#undef BUILTIN_VSTRUCT --#undef CF --#undef VAR1 --#undef VAR2 --#undef VAR3 --#undef VAR4 --#undef VAR5 --#undef VAR6 --#undef VAR7 --#undef VAR8 --#undef VAR9 --#undef VAR10 --#undef VAR11 -- - static GTY(()) tree aarch64_builtin_decls[AARCH64_BUILTIN_MAX]; - - #define NUM_DREG_TYPES 6 - #define NUM_QREG_TYPES 6 - --static void --aarch64_init_simd_builtins (void) -+/* Return a tree for a signed or unsigned argument of either -+ the mode specified by MODE, or the inner mode of MODE. */ -+tree -+aarch64_build_scalar_type (enum machine_mode mode, -+ bool unsigned_p, -+ bool poly_p) - { -- unsigned int i, fcode = AARCH64_SIMD_BUILTIN_BASE + 1; -+#undef INT_TYPES -+#define INT_TYPES \ -+ AARCH64_TYPE_BUILDER (QI) \ -+ AARCH64_TYPE_BUILDER (HI) \ -+ AARCH64_TYPE_BUILDER (SI) \ -+ AARCH64_TYPE_BUILDER (DI) \ -+ AARCH64_TYPE_BUILDER (EI) \ -+ AARCH64_TYPE_BUILDER (OI) \ -+ AARCH64_TYPE_BUILDER (CI) \ -+ AARCH64_TYPE_BUILDER (XI) \ -+ AARCH64_TYPE_BUILDER (TI) \ - -- /* Scalar type nodes. */ -- tree aarch64_simd_intQI_type_node; -- tree aarch64_simd_intHI_type_node; -- tree aarch64_simd_polyQI_type_node; -- tree aarch64_simd_polyHI_type_node; -- tree aarch64_simd_intSI_type_node; -- tree aarch64_simd_intDI_type_node; -- tree aarch64_simd_float_type_node; -- tree aarch64_simd_double_type_node; -+/* Statically declare all the possible types we might need. */ -+#undef AARCH64_TYPE_BUILDER -+#define AARCH64_TYPE_BUILDER(X) \ -+ static tree X##_aarch64_type_node_p = NULL; \ -+ static tree X##_aarch64_type_node_s = NULL; \ -+ static tree X##_aarch64_type_node_u = NULL; - -- /* Pointer to scalar type nodes. */ -- tree intQI_pointer_node; -- tree intHI_pointer_node; -- tree intSI_pointer_node; -- tree intDI_pointer_node; -- tree float_pointer_node; -- tree double_pointer_node; -+ INT_TYPES - -- /* Const scalar type nodes. */ -- tree const_intQI_node; -- tree const_intHI_node; -- tree const_intSI_node; -- tree const_intDI_node; -- tree const_float_node; -- tree const_double_node; -+ static tree float_aarch64_type_node = NULL; -+ static tree double_aarch64_type_node = NULL; - -- /* Pointer to const scalar type nodes. */ -- tree const_intQI_pointer_node; -- tree const_intHI_pointer_node; -- tree const_intSI_pointer_node; -- tree const_intDI_pointer_node; -- tree const_float_pointer_node; -- tree const_double_pointer_node; -+ gcc_assert (!VECTOR_MODE_P (mode)); - -- /* Vector type nodes. */ -- tree V8QI_type_node; -- tree V4HI_type_node; -- tree V2SI_type_node; -- tree V2SF_type_node; -- tree V16QI_type_node; -- tree V8HI_type_node; -- tree V4SI_type_node; -- tree V4SF_type_node; -- tree V2DI_type_node; -- tree V2DF_type_node; -+/* If we've already initialised this type, don't initialise it again, -+ otherwise ask for a new type of the correct size. */ -+#undef AARCH64_TYPE_BUILDER -+#define AARCH64_TYPE_BUILDER(X) \ -+ case X##mode: \ -+ if (unsigned_p) \ -+ return (X##_aarch64_type_node_u \ -+ ? X##_aarch64_type_node_u \ -+ : X##_aarch64_type_node_u \ -+ = make_unsigned_type (GET_MODE_PRECISION (mode))); \ -+ else if (poly_p) \ -+ return (X##_aarch64_type_node_p \ -+ ? X##_aarch64_type_node_p \ -+ : X##_aarch64_type_node_p \ -+ = make_unsigned_type (GET_MODE_PRECISION (mode))); \ -+ else \ -+ return (X##_aarch64_type_node_s \ -+ ? X##_aarch64_type_node_s \ -+ : X##_aarch64_type_node_s \ -+ = make_signed_type (GET_MODE_PRECISION (mode))); \ -+ break; - -- /* Scalar unsigned type nodes. */ -- tree intUQI_type_node; -- tree intUHI_type_node; -- tree intUSI_type_node; -- tree intUDI_type_node; -+ switch (mode) -+ { -+ INT_TYPES -+ case SFmode: -+ if (!float_aarch64_type_node) -+ { -+ float_aarch64_type_node = make_node (REAL_TYPE); -+ TYPE_PRECISION (float_aarch64_type_node) = FLOAT_TYPE_SIZE; -+ layout_type (float_aarch64_type_node); -+ } -+ return float_aarch64_type_node; -+ break; -+ case DFmode: -+ if (!double_aarch64_type_node) -+ { -+ double_aarch64_type_node = make_node (REAL_TYPE); -+ TYPE_PRECISION (double_aarch64_type_node) = DOUBLE_TYPE_SIZE; -+ layout_type (double_aarch64_type_node); -+ } -+ return double_aarch64_type_node; -+ break; -+ default: -+ gcc_unreachable (); -+ } ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcagts_f32 (float32_t __a, float32_t __b) ++{ ++ return __builtin_fabsf (__a) > __builtin_fabsf (__b) ? -1 : 0; ++} ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcagt_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return vabs_f32 (__a) > vabs_f32 (__b); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcagtq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return vabsq_f32 (__a) > vabsq_f32 (__b); +} - -- /* Opaque integer types for structures of vectors. */ -- tree intEI_type_node; -- tree intOI_type_node; -- tree intCI_type_node; -- tree intXI_type_node; -+tree -+aarch64_build_vector_type (enum machine_mode mode, -+ bool unsigned_p, -+ bool poly_p) -+{ -+ tree eltype; - -- /* Pointer to vector type nodes. */ -- tree V8QI_pointer_node; -- tree V4HI_pointer_node; -- tree V2SI_pointer_node; -- tree V2SF_pointer_node; -- tree V16QI_pointer_node; -- tree V8HI_pointer_node; -- tree V4SI_pointer_node; -- tree V4SF_pointer_node; -- tree V2DI_pointer_node; -- tree V2DF_pointer_node; -+#define VECTOR_TYPES \ -+ AARCH64_TYPE_BUILDER (V16QI) \ -+ AARCH64_TYPE_BUILDER (V8HI) \ -+ AARCH64_TYPE_BUILDER (V4SI) \ -+ AARCH64_TYPE_BUILDER (V2DI) \ -+ AARCH64_TYPE_BUILDER (V8QI) \ -+ AARCH64_TYPE_BUILDER (V4HI) \ -+ AARCH64_TYPE_BUILDER (V2SI) \ -+ \ -+ AARCH64_TYPE_BUILDER (V4SF) \ -+ AARCH64_TYPE_BUILDER (V2DF) \ -+ AARCH64_TYPE_BUILDER (V2SF) \ -+/* Declare our "cache" of values. */ -+#undef AARCH64_TYPE_BUILDER -+#define AARCH64_TYPE_BUILDER(X) \ -+ static tree X##_aarch64_type_node_s = NULL; \ -+ static tree X##_aarch64_type_node_u = NULL; \ -+ static tree X##_aarch64_type_node_p = NULL; - -- /* Operations which return results as pairs. */ -- tree void_ftype_pv8qi_v8qi_v8qi; -- tree void_ftype_pv4hi_v4hi_v4hi; -- tree void_ftype_pv2si_v2si_v2si; -- tree void_ftype_pv2sf_v2sf_v2sf; -- tree void_ftype_pdi_di_di; -- tree void_ftype_pv16qi_v16qi_v16qi; -- tree void_ftype_pv8hi_v8hi_v8hi; -- tree void_ftype_pv4si_v4si_v4si; -- tree void_ftype_pv4sf_v4sf_v4sf; -- tree void_ftype_pv2di_v2di_v2di; -- tree void_ftype_pv2df_v2df_v2df; -+ VECTOR_TYPES - -- tree reinterp_ftype_dreg[NUM_DREG_TYPES][NUM_DREG_TYPES]; -- tree reinterp_ftype_qreg[NUM_QREG_TYPES][NUM_QREG_TYPES]; -- tree dreg_types[NUM_DREG_TYPES], qreg_types[NUM_QREG_TYPES]; -+ gcc_assert (VECTOR_MODE_P (mode)); - -- /* Create distinguished type nodes for AARCH64_SIMD vector element types, -- and pointers to values of such types, so we can detect them later. */ -- aarch64_simd_intQI_type_node = -- make_signed_type (GET_MODE_PRECISION (QImode)); -- aarch64_simd_intHI_type_node = -- make_signed_type (GET_MODE_PRECISION (HImode)); -- aarch64_simd_polyQI_type_node = -- make_signed_type (GET_MODE_PRECISION (QImode)); -- aarch64_simd_polyHI_type_node = -- make_signed_type (GET_MODE_PRECISION (HImode)); -- aarch64_simd_intSI_type_node = -- make_signed_type (GET_MODE_PRECISION (SImode)); -- aarch64_simd_intDI_type_node = -- make_signed_type (GET_MODE_PRECISION (DImode)); -- aarch64_simd_float_type_node = make_node (REAL_TYPE); -- aarch64_simd_double_type_node = make_node (REAL_TYPE); -- TYPE_PRECISION (aarch64_simd_float_type_node) = FLOAT_TYPE_SIZE; -- TYPE_PRECISION (aarch64_simd_double_type_node) = DOUBLE_TYPE_SIZE; -- layout_type (aarch64_simd_float_type_node); -- layout_type (aarch64_simd_double_type_node); -+#undef AARCH64_TYPE_BUILDER -+#define AARCH64_TYPE_BUILDER(X) \ -+ case X##mode: \ -+ if (unsigned_p) \ -+ return X##_aarch64_type_node_u \ -+ ? X##_aarch64_type_node_u \ -+ : X##_aarch64_type_node_u \ -+ = build_vector_type_for_mode (aarch64_build_scalar_type \ -+ (GET_MODE_INNER (mode), \ -+ unsigned_p, poly_p), mode); \ -+ else if (poly_p) \ -+ return X##_aarch64_type_node_p \ -+ ? X##_aarch64_type_node_p \ -+ : X##_aarch64_type_node_p \ -+ = build_vector_type_for_mode (aarch64_build_scalar_type \ -+ (GET_MODE_INNER (mode), \ -+ unsigned_p, poly_p), mode); \ -+ else \ -+ return X##_aarch64_type_node_s \ -+ ? X##_aarch64_type_node_s \ -+ : X##_aarch64_type_node_s \ -+ = build_vector_type_for_mode (aarch64_build_scalar_type \ -+ (GET_MODE_INNER (mode), \ -+ unsigned_p, poly_p), mode); \ -+ break; - -+ switch (mode) -+ { -+ default: -+ eltype = aarch64_build_scalar_type (GET_MODE_INNER (mode), -+ unsigned_p, poly_p); -+ return build_vector_type_for_mode (eltype, mode); -+ break; -+ VECTOR_TYPES -+ } ++ ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcagtd_f64 (float64_t __a, float64_t __b) ++{ ++ return __builtin_fabs (__a) > __builtin_fabs (__b) ? -1 : 0; +} + -+tree -+aarch64_build_type (enum machine_mode mode, bool unsigned_p, bool poly_p) ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcagtq_f64 (float64x2_t __a, float64x2_t __b) +{ -+ if (VECTOR_MODE_P (mode)) -+ return aarch64_build_vector_type (mode, unsigned_p, poly_p); -+ else -+ return aarch64_build_scalar_type (mode, unsigned_p, poly_p); ++ return vabsq_f64 (__a) > vabsq_f64 (__b); +} + -+tree -+aarch64_build_signed_type (enum machine_mode mode) ++/* vcale */ ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcale_f32 (float32x2_t __a, float32x2_t __b) +{ -+ return aarch64_build_type (mode, false, false); ++ return vabs_f32 (__a) <= vabs_f32 (__b); +} + -+tree -+aarch64_build_unsigned_type (enum machine_mode mode) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcaleq_f32 (float32x4_t __a, float32x4_t __b) +{ -+ return aarch64_build_type (mode, true, false); ++ return vabsq_f32 (__a) <= vabsq_f32 (__b); +} + -+tree -+aarch64_build_poly_type (enum machine_mode mode) ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcaleq_f64 (float64x2_t __a, float64x2_t __b) +{ -+ return aarch64_build_type (mode, false, true); ++ return vabsq_f64 (__a) <= vabsq_f64 (__b); +} + -+static void -+aarch64_init_simd_builtins (void) ++/* vcalt */ ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcalt_f32 (float32x2_t __a, float32x2_t __b) +{ -+ unsigned int i, fcode = AARCH64_SIMD_BUILTIN_BASE + 1; ++ return vabs_f32 (__a) < vabs_f32 (__b); ++} + -+ /* Signed scalar type nodes. */ -+ tree aarch64_simd_intQI_type_node = aarch64_build_signed_type (QImode); -+ tree aarch64_simd_intHI_type_node = aarch64_build_signed_type (HImode); -+ tree aarch64_simd_intSI_type_node = aarch64_build_signed_type (SImode); -+ tree aarch64_simd_intDI_type_node = aarch64_build_signed_type (DImode); -+ tree aarch64_simd_intTI_type_node = aarch64_build_signed_type (TImode); -+ tree aarch64_simd_intEI_type_node = aarch64_build_signed_type (EImode); -+ tree aarch64_simd_intOI_type_node = aarch64_build_signed_type (OImode); -+ tree aarch64_simd_intCI_type_node = aarch64_build_signed_type (CImode); -+ tree aarch64_simd_intXI_type_node = aarch64_build_signed_type (XImode); -+ -+ /* Unsigned scalar type nodes. */ -+ tree aarch64_simd_intUQI_type_node = aarch64_build_unsigned_type (QImode); -+ tree aarch64_simd_intUHI_type_node = aarch64_build_unsigned_type (HImode); -+ tree aarch64_simd_intUSI_type_node = aarch64_build_unsigned_type (SImode); -+ tree aarch64_simd_intUDI_type_node = aarch64_build_unsigned_type (DImode); -+ -+ /* Poly scalar type nodes. */ -+ tree aarch64_simd_polyQI_type_node = aarch64_build_poly_type (QImode); -+ tree aarch64_simd_polyHI_type_node = aarch64_build_poly_type (HImode); -+ tree aarch64_simd_polyDI_type_node = aarch64_build_poly_type (DImode); -+ tree aarch64_simd_polyTI_type_node = aarch64_build_poly_type (TImode); -+ -+ /* Float type nodes. */ -+ tree aarch64_simd_float_type_node = aarch64_build_signed_type (SFmode); -+ tree aarch64_simd_double_type_node = aarch64_build_signed_type (DFmode); ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcaltq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return vabsq_f32 (__a) < vabsq_f32 (__b); ++} + - /* Define typedefs which exactly correspond to the modes we are basing vector - types on. If you change these names you'll need to change - the table used by aarch64_mangle_type too. */ -@@ -441,518 +569,139 @@ - "__builtin_aarch64_simd_poly8"); - (*lang_hooks.types.register_builtin_type) (aarch64_simd_polyHI_type_node, - "__builtin_aarch64_simd_poly16"); -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_polyDI_type_node, -+ "__builtin_aarch64_simd_poly64"); -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_polyTI_type_node, -+ "__builtin_aarch64_simd_poly128"); -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intTI_type_node, -+ "__builtin_aarch64_simd_ti"); -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intEI_type_node, -+ "__builtin_aarch64_simd_ei"); -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intOI_type_node, -+ "__builtin_aarch64_simd_oi"); -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intCI_type_node, -+ "__builtin_aarch64_simd_ci"); -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intXI_type_node, -+ "__builtin_aarch64_simd_xi"); - -- intQI_pointer_node = build_pointer_type (aarch64_simd_intQI_type_node); -- intHI_pointer_node = build_pointer_type (aarch64_simd_intHI_type_node); -- intSI_pointer_node = build_pointer_type (aarch64_simd_intSI_type_node); -- intDI_pointer_node = build_pointer_type (aarch64_simd_intDI_type_node); -- float_pointer_node = build_pointer_type (aarch64_simd_float_type_node); -- double_pointer_node = build_pointer_type (aarch64_simd_double_type_node); -- -- /* Next create constant-qualified versions of the above types. */ -- const_intQI_node = build_qualified_type (aarch64_simd_intQI_type_node, -- TYPE_QUAL_CONST); -- const_intHI_node = build_qualified_type (aarch64_simd_intHI_type_node, -- TYPE_QUAL_CONST); -- const_intSI_node = build_qualified_type (aarch64_simd_intSI_type_node, -- TYPE_QUAL_CONST); -- const_intDI_node = build_qualified_type (aarch64_simd_intDI_type_node, -- TYPE_QUAL_CONST); -- const_float_node = build_qualified_type (aarch64_simd_float_type_node, -- TYPE_QUAL_CONST); -- const_double_node = build_qualified_type (aarch64_simd_double_type_node, -- TYPE_QUAL_CONST); -- -- const_intQI_pointer_node = build_pointer_type (const_intQI_node); -- const_intHI_pointer_node = build_pointer_type (const_intHI_node); -- const_intSI_pointer_node = build_pointer_type (const_intSI_node); -- const_intDI_pointer_node = build_pointer_type (const_intDI_node); -- const_float_pointer_node = build_pointer_type (const_float_node); -- const_double_pointer_node = build_pointer_type (const_double_node); -- -- /* Now create vector types based on our AARCH64 SIMD element types. */ -- /* 64-bit vectors. */ -- V8QI_type_node = -- build_vector_type_for_mode (aarch64_simd_intQI_type_node, V8QImode); -- V4HI_type_node = -- build_vector_type_for_mode (aarch64_simd_intHI_type_node, V4HImode); -- V2SI_type_node = -- build_vector_type_for_mode (aarch64_simd_intSI_type_node, V2SImode); -- V2SF_type_node = -- build_vector_type_for_mode (aarch64_simd_float_type_node, V2SFmode); -- /* 128-bit vectors. */ -- V16QI_type_node = -- build_vector_type_for_mode (aarch64_simd_intQI_type_node, V16QImode); -- V8HI_type_node = -- build_vector_type_for_mode (aarch64_simd_intHI_type_node, V8HImode); -- V4SI_type_node = -- build_vector_type_for_mode (aarch64_simd_intSI_type_node, V4SImode); -- V4SF_type_node = -- build_vector_type_for_mode (aarch64_simd_float_type_node, V4SFmode); -- V2DI_type_node = -- build_vector_type_for_mode (aarch64_simd_intDI_type_node, V2DImode); -- V2DF_type_node = -- build_vector_type_for_mode (aarch64_simd_double_type_node, V2DFmode); -- - /* Unsigned integer types for various mode sizes. */ -- intUQI_type_node = make_unsigned_type (GET_MODE_PRECISION (QImode)); -- intUHI_type_node = make_unsigned_type (GET_MODE_PRECISION (HImode)); -- intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode)); -- intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode)); -- -- (*lang_hooks.types.register_builtin_type) (intUQI_type_node, -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intUQI_type_node, - "__builtin_aarch64_simd_uqi"); -- (*lang_hooks.types.register_builtin_type) (intUHI_type_node, -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intUHI_type_node, - "__builtin_aarch64_simd_uhi"); -- (*lang_hooks.types.register_builtin_type) (intUSI_type_node, -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intUSI_type_node, - "__builtin_aarch64_simd_usi"); -- (*lang_hooks.types.register_builtin_type) (intUDI_type_node, -+ (*lang_hooks.types.register_builtin_type) (aarch64_simd_intUDI_type_node, - "__builtin_aarch64_simd_udi"); - -- /* Opaque integer types for structures of vectors. */ -- intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode)); -- intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode)); -- intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode)); -- intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode)); -- -- (*lang_hooks.types.register_builtin_type) (intTI_type_node, -- "__builtin_aarch64_simd_ti"); -- (*lang_hooks.types.register_builtin_type) (intEI_type_node, -- "__builtin_aarch64_simd_ei"); -- (*lang_hooks.types.register_builtin_type) (intOI_type_node, -- "__builtin_aarch64_simd_oi"); -- (*lang_hooks.types.register_builtin_type) (intCI_type_node, -- "__builtin_aarch64_simd_ci"); -- (*lang_hooks.types.register_builtin_type) (intXI_type_node, -- "__builtin_aarch64_simd_xi"); -- -- /* Pointers to vector types. */ -- V8QI_pointer_node = build_pointer_type (V8QI_type_node); -- V4HI_pointer_node = build_pointer_type (V4HI_type_node); -- V2SI_pointer_node = build_pointer_type (V2SI_type_node); -- V2SF_pointer_node = build_pointer_type (V2SF_type_node); -- V16QI_pointer_node = build_pointer_type (V16QI_type_node); -- V8HI_pointer_node = build_pointer_type (V8HI_type_node); -- V4SI_pointer_node = build_pointer_type (V4SI_type_node); -- V4SF_pointer_node = build_pointer_type (V4SF_type_node); -- V2DI_pointer_node = build_pointer_type (V2DI_type_node); -- V2DF_pointer_node = build_pointer_type (V2DF_type_node); -- -- /* Operations which return results as pairs. */ -- void_ftype_pv8qi_v8qi_v8qi = -- build_function_type_list (void_type_node, V8QI_pointer_node, -- V8QI_type_node, V8QI_type_node, NULL); -- void_ftype_pv4hi_v4hi_v4hi = -- build_function_type_list (void_type_node, V4HI_pointer_node, -- V4HI_type_node, V4HI_type_node, NULL); -- void_ftype_pv2si_v2si_v2si = -- build_function_type_list (void_type_node, V2SI_pointer_node, -- V2SI_type_node, V2SI_type_node, NULL); -- void_ftype_pv2sf_v2sf_v2sf = -- build_function_type_list (void_type_node, V2SF_pointer_node, -- V2SF_type_node, V2SF_type_node, NULL); -- void_ftype_pdi_di_di = -- build_function_type_list (void_type_node, intDI_pointer_node, -- aarch64_simd_intDI_type_node, -- aarch64_simd_intDI_type_node, NULL); -- void_ftype_pv16qi_v16qi_v16qi = -- build_function_type_list (void_type_node, V16QI_pointer_node, -- V16QI_type_node, V16QI_type_node, NULL); -- void_ftype_pv8hi_v8hi_v8hi = -- build_function_type_list (void_type_node, V8HI_pointer_node, -- V8HI_type_node, V8HI_type_node, NULL); -- void_ftype_pv4si_v4si_v4si = -- build_function_type_list (void_type_node, V4SI_pointer_node, -- V4SI_type_node, V4SI_type_node, NULL); -- void_ftype_pv4sf_v4sf_v4sf = -- build_function_type_list (void_type_node, V4SF_pointer_node, -- V4SF_type_node, V4SF_type_node, NULL); -- void_ftype_pv2di_v2di_v2di = -- build_function_type_list (void_type_node, V2DI_pointer_node, -- V2DI_type_node, V2DI_type_node, NULL); -- void_ftype_pv2df_v2df_v2df = -- build_function_type_list (void_type_node, V2DF_pointer_node, -- V2DF_type_node, V2DF_type_node, NULL); -- -- dreg_types[0] = V8QI_type_node; -- dreg_types[1] = V4HI_type_node; -- dreg_types[2] = V2SI_type_node; -- dreg_types[3] = V2SF_type_node; -- dreg_types[4] = aarch64_simd_intDI_type_node; -- dreg_types[5] = aarch64_simd_double_type_node; -- -- qreg_types[0] = V16QI_type_node; -- qreg_types[1] = V8HI_type_node; -- qreg_types[2] = V4SI_type_node; -- qreg_types[3] = V4SF_type_node; -- qreg_types[4] = V2DI_type_node; -- qreg_types[5] = V2DF_type_node; -- -- /* If NUM_DREG_TYPES != NUM_QREG_TYPES, we will need separate nested loops -- for qreg and dreg reinterp inits. */ -- for (i = 0; i < NUM_DREG_TYPES; i++) -- { -- int j; -- for (j = 0; j < NUM_DREG_TYPES; j++) -- { -- reinterp_ftype_dreg[i][j] -- = build_function_type_list (dreg_types[i], dreg_types[j], NULL); -- reinterp_ftype_qreg[i][j] -- = build_function_type_list (qreg_types[i], qreg_types[j], NULL); -- } -- } -- - for (i = 0; i < ARRAY_SIZE (aarch64_simd_builtin_data); i++, fcode++) - { -+ bool print_type_signature_p = false; -+ char type_signature[SIMD_MAX_BUILTIN_ARGS] = { 0 }; - aarch64_simd_builtin_datum *d = &aarch64_simd_builtin_data[i]; - const char *const modenames[] = -- { -- "v8qi", "v4hi", "v2si", "v2sf", "di", "df", -- "v16qi", "v8hi", "v4si", "v4sf", "v2di", "v2df", -- "ti", "ei", "oi", "xi", "si", "hi", "qi" -- }; -+ { -+ "v8qi", "v4hi", "v2si", "v2sf", "di", "df", -+ "v16qi", "v8hi", "v4si", "v4sf", "v2di", "v2df", -+ "ti", "ei", "oi", "xi", "si", "sf", "hi", "qi" -+ }; -+ const enum machine_mode modes[] = -+ { -+ V8QImode, V4HImode, V2SImode, V2SFmode, DImode, DFmode, -+ V16QImode, V8HImode, V4SImode, V4SFmode, V2DImode, -+ V2DFmode, TImode, EImode, OImode, XImode, SImode, -+ SFmode, HImode, QImode -+ }; - char namebuf[60]; - tree ftype = NULL; - tree fndecl = NULL; -- int is_load = 0; -- int is_store = 0; - - gcc_assert (ARRAY_SIZE (modenames) == T_MAX); - - d->fcode = fcode; - -- switch (d->itype) -+ /* We must track two variables here. op_num is -+ the operand number as in the RTL pattern. This is -+ required to access the mode (e.g. V4SF mode) of the -+ argument, from which the base type can be derived. -+ arg_num is an index in to the qualifiers data, which -+ gives qualifiers to the type (e.g. const unsigned). -+ The reason these two variables may differ by one is the -+ void return type. While all return types take the 0th entry -+ in the qualifiers array, there is no operand for them in the -+ RTL pattern. */ -+ int op_num = insn_data[d->code].n_operands - 1; -+ int arg_num = d->qualifiers[0] & qualifier_void -+ ? op_num + 1 -+ : op_num; -+ tree return_type = void_type_node, args = void_list_node; -+ tree eltype; -+ -+ /* Build a function type directly from the insn_data for this -+ builtin. The build_function_type () function takes care of -+ removing duplicates for us. */ -+ for (; op_num >= 0; arg_num--, op_num--) - { -- case AARCH64_SIMD_LOAD1: -- case AARCH64_SIMD_LOAD1LANE: -- case AARCH64_SIMD_LOADSTRUCT: -- case AARCH64_SIMD_LOADSTRUCTLANE: -- is_load = 1; -- /* Fall through. */ -- case AARCH64_SIMD_STORE1: -- case AARCH64_SIMD_STORE1LANE: -- case AARCH64_SIMD_STORESTRUCT: -- case AARCH64_SIMD_STORESTRUCTLANE: -- if (!is_load) -- is_store = 1; -- /* Fall through. */ -- case AARCH64_SIMD_UNOP: -- case AARCH64_SIMD_BINOP: -- case AARCH64_SIMD_TERNOP: -- case AARCH64_SIMD_QUADOP: -- case AARCH64_SIMD_COMBINE: -- case AARCH64_SIMD_CONVERT: -- case AARCH64_SIMD_CREATE: -- case AARCH64_SIMD_DUP: -- case AARCH64_SIMD_DUPLANE: -- case AARCH64_SIMD_FIXCONV: -- case AARCH64_SIMD_GETLANE: -- case AARCH64_SIMD_LANEMAC: -- case AARCH64_SIMD_LANEMUL: -- case AARCH64_SIMD_LANEMULH: -- case AARCH64_SIMD_LANEMULL: -- case AARCH64_SIMD_LOGICBINOP: -- case AARCH64_SIMD_SCALARMAC: -- case AARCH64_SIMD_SCALARMUL: -- case AARCH64_SIMD_SCALARMULH: -- case AARCH64_SIMD_SCALARMULL: -- case AARCH64_SIMD_SELECT: -- case AARCH64_SIMD_SETLANE: -- case AARCH64_SIMD_SHIFTACC: -- case AARCH64_SIMD_SHIFTIMM: -- case AARCH64_SIMD_SHIFTINSERT: -- case AARCH64_SIMD_SPLIT: -- case AARCH64_SIMD_VTBL: -- case AARCH64_SIMD_VTBX: -- { -- int k; -- tree return_type = void_type_node, args = void_list_node; -- tree eltype; -- /* Build a function type directly from the insn_data for this -- builtin. The build_function_type () function takes care of -- removing duplicates for us. */ -+ enum machine_mode op_mode = insn_data[d->code].operand[op_num].mode; -+ enum aarch64_type_qualifiers qualifiers = d->qualifiers[arg_num]; - -- for (k = insn_data[d->code].n_operands -1; k >= 0; k--) -- { -- /* Skip an internal operand for vget_{low, high}. */ -- if (k == 2 && d->itype == AARCH64_SIMD_SPLIT) -- continue; -+ if (qualifiers & qualifier_unsigned) -+ { -+ type_signature[arg_num] = 'u'; -+ print_type_signature_p = true; -+ } -+ else if (qualifiers & qualifier_poly) -+ { -+ type_signature[arg_num] = 'p'; -+ print_type_signature_p = true; -+ } -+ else -+ type_signature[arg_num] = 's'; - -- if (is_load && k == 1) -- { -- /* AdvSIMD load patterns always have the memory operand -- (a DImode pointer) in the operand 1 position. We -- want a const pointer to the element type in that -- position. */ -- gcc_assert (insn_data[d->code].operand[k].mode == DImode); -+ /* Skip an internal operand for vget_{low, high}. */ -+ if (qualifiers & qualifier_internal) -+ continue; - -- switch (d->mode) -- { -- case T_V8QI: -- case T_V16QI: -- eltype = const_intQI_pointer_node; -- break; -+ /* Some builtins have different user-facing types -+ for certain arguments, encoded in d->mode. */ -+ if (qualifiers & qualifier_map_mode) -+ op_mode = modes[d->mode]; - -- case T_V4HI: -- case T_V8HI: -- eltype = const_intHI_pointer_node; -- break; -+ /* For pointers, we want a pointer to the basic type -+ of the vector. */ -+ if (qualifiers & qualifier_pointer && VECTOR_MODE_P (op_mode)) -+ op_mode = GET_MODE_INNER (op_mode); - -- case T_V2SI: -- case T_V4SI: -- eltype = const_intSI_pointer_node; -- break; -+ eltype = aarch64_build_type (op_mode, -+ qualifiers & qualifier_unsigned, -+ qualifiers & qualifier_poly); - -- case T_V2SF: -- case T_V4SF: -- eltype = const_float_pointer_node; -- break; -+ /* Add qualifiers. */ -+ if (qualifiers & qualifier_const) -+ eltype = build_qualified_type (eltype, TYPE_QUAL_CONST); - -- case T_DI: -- case T_V2DI: -- eltype = const_intDI_pointer_node; -- break; -+ if (qualifiers & qualifier_pointer) -+ eltype = build_pointer_type (eltype); - -- case T_DF: -- case T_V2DF: -- eltype = const_double_pointer_node; -- break; -+ /* If we have reached arg_num == 0, we are at a non-void -+ return type. Otherwise, we are still processing -+ arguments. */ -+ if (arg_num == 0) -+ return_type = eltype; -+ else -+ args = tree_cons (NULL_TREE, eltype, args); -+ } - -- default: -- gcc_unreachable (); -- } -- } -- else if (is_store && k == 0) -- { -- /* Similarly, AdvSIMD store patterns use operand 0 as -- the memory location to store to (a DImode pointer). -- Use a pointer to the element type of the store in -- that position. */ -- gcc_assert (insn_data[d->code].operand[k].mode == DImode); -+ ftype = build_function_type (return_type, args); - -- switch (d->mode) -- { -- case T_V8QI: -- case T_V16QI: -- eltype = intQI_pointer_node; -- break; -- -- case T_V4HI: -- case T_V8HI: -- eltype = intHI_pointer_node; -- break; -- -- case T_V2SI: -- case T_V4SI: -- eltype = intSI_pointer_node; -- break; -- -- case T_V2SF: -- case T_V4SF: -- eltype = float_pointer_node; -- break; -- -- case T_DI: -- case T_V2DI: -- eltype = intDI_pointer_node; -- break; -- -- case T_DF: -- case T_V2DF: -- eltype = double_pointer_node; -- break; -- -- default: -- gcc_unreachable (); -- } -- } -- else -- { -- switch (insn_data[d->code].operand[k].mode) -- { -- case VOIDmode: -- eltype = void_type_node; -- break; -- /* Scalars. */ -- case QImode: -- eltype = aarch64_simd_intQI_type_node; -- break; -- case HImode: -- eltype = aarch64_simd_intHI_type_node; -- break; -- case SImode: -- eltype = aarch64_simd_intSI_type_node; -- break; -- case SFmode: -- eltype = aarch64_simd_float_type_node; -- break; -- case DFmode: -- eltype = aarch64_simd_double_type_node; -- break; -- case DImode: -- eltype = aarch64_simd_intDI_type_node; -- break; -- case TImode: -- eltype = intTI_type_node; -- break; -- case EImode: -- eltype = intEI_type_node; -- break; -- case OImode: -- eltype = intOI_type_node; -- break; -- case CImode: -- eltype = intCI_type_node; -- break; -- case XImode: -- eltype = intXI_type_node; -- break; -- /* 64-bit vectors. */ -- case V8QImode: -- eltype = V8QI_type_node; -- break; -- case V4HImode: -- eltype = V4HI_type_node; -- break; -- case V2SImode: -- eltype = V2SI_type_node; -- break; -- case V2SFmode: -- eltype = V2SF_type_node; -- break; -- /* 128-bit vectors. */ -- case V16QImode: -- eltype = V16QI_type_node; -- break; -- case V8HImode: -- eltype = V8HI_type_node; -- break; -- case V4SImode: -- eltype = V4SI_type_node; -- break; -- case V4SFmode: -- eltype = V4SF_type_node; -- break; -- case V2DImode: -- eltype = V2DI_type_node; -- break; -- case V2DFmode: -- eltype = V2DF_type_node; -- break; -- default: -- gcc_unreachable (); -- } -- } -- -- if (k == 0 && !is_store) -- return_type = eltype; -- else -- args = tree_cons (NULL_TREE, eltype, args); -- } -- ftype = build_function_type (return_type, args); -- } -- break; -- -- case AARCH64_SIMD_RESULTPAIR: -- { -- switch (insn_data[d->code].operand[1].mode) -- { -- case V8QImode: -- ftype = void_ftype_pv8qi_v8qi_v8qi; -- break; -- case V4HImode: -- ftype = void_ftype_pv4hi_v4hi_v4hi; -- break; -- case V2SImode: -- ftype = void_ftype_pv2si_v2si_v2si; -- break; -- case V2SFmode: -- ftype = void_ftype_pv2sf_v2sf_v2sf; -- break; -- case DImode: -- ftype = void_ftype_pdi_di_di; -- break; -- case V16QImode: -- ftype = void_ftype_pv16qi_v16qi_v16qi; -- break; -- case V8HImode: -- ftype = void_ftype_pv8hi_v8hi_v8hi; -- break; -- case V4SImode: -- ftype = void_ftype_pv4si_v4si_v4si; -- break; -- case V4SFmode: -- ftype = void_ftype_pv4sf_v4sf_v4sf; -- break; -- case V2DImode: -- ftype = void_ftype_pv2di_v2di_v2di; -- break; -- case V2DFmode: -- ftype = void_ftype_pv2df_v2df_v2df; -- break; -- default: -- gcc_unreachable (); -- } -- } -- break; -- -- case AARCH64_SIMD_REINTERP: -- { -- /* We iterate over 6 doubleword types, then 6 quadword -- types. */ -- int rhs_d = d->mode % NUM_DREG_TYPES; -- int rhs_q = (d->mode - NUM_DREG_TYPES) % NUM_QREG_TYPES; -- switch (insn_data[d->code].operand[0].mode) -- { -- case V8QImode: -- ftype = reinterp_ftype_dreg[0][rhs_d]; -- break; -- case V4HImode: -- ftype = reinterp_ftype_dreg[1][rhs_d]; -- break; -- case V2SImode: -- ftype = reinterp_ftype_dreg[2][rhs_d]; -- break; -- case V2SFmode: -- ftype = reinterp_ftype_dreg[3][rhs_d]; -- break; -- case DImode: -- ftype = reinterp_ftype_dreg[4][rhs_d]; -- break; -- case DFmode: -- ftype = reinterp_ftype_dreg[5][rhs_d]; -- break; -- case V16QImode: -- ftype = reinterp_ftype_qreg[0][rhs_q]; -- break; -- case V8HImode: -- ftype = reinterp_ftype_qreg[1][rhs_q]; -- break; -- case V4SImode: -- ftype = reinterp_ftype_qreg[2][rhs_q]; -- break; -- case V4SFmode: -- ftype = reinterp_ftype_qreg[3][rhs_q]; -- break; -- case V2DImode: -- ftype = reinterp_ftype_qreg[4][rhs_q]; -- break; -- case V2DFmode: -- ftype = reinterp_ftype_qreg[5][rhs_q]; -- break; -- default: -- gcc_unreachable (); -- } -- } -- break; -- -- default: -- gcc_unreachable (); -- } - gcc_assert (ftype != NULL); - -- snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s%s", -- d->name, modenames[d->mode]); -+ if (print_type_signature_p) -+ snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s%s_%s", -+ d->name, modenames[d->mode], type_signature); -+ else -+ snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s%s", -+ d->name, modenames[d->mode]); - - fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD, - NULL, NULL_TREE); -@@ -983,8 +732,6 @@ - SIMD_ARG_STOP - } builtin_simd_arg; - --#define SIMD_MAX_BUILTIN_ARGS 5 -- - static rtx - aarch64_simd_expand_args (rtx target, int icode, int have_retval, - tree exp, ...) -@@ -1110,99 +857,58 @@ - { - aarch64_simd_builtin_datum *d = - &aarch64_simd_builtin_data[fcode - (AARCH64_SIMD_BUILTIN_BASE + 1)]; -- aarch64_simd_itype itype = d->itype; - enum insn_code icode = d->code; -+ builtin_simd_arg args[SIMD_MAX_BUILTIN_ARGS]; -+ int num_args = insn_data[d->code].n_operands; -+ int is_void = 0; -+ int k; ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcaltq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return vabsq_f64 (__a) < vabsq_f64 (__b); ++} ++ ++/* vceq - vector. */ ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vceq_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return (uint32x2_t) __builtin_aarch64_cmeqv2sf (__a, __b); ++} ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vceq_f64 (float64x1_t __a, float64x1_t __b) ++{ ++ return __a == __b ? -1ll : 0ll; ++} ++ + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vceq_p8 (poly8x8_t __a, poly8x8_t __b) + { +@@ -19414,7 +17686,7 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vceq_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, __b); ++ return __a == __b ? -1ll : 0ll; + } -- switch (itype) -- { -- case AARCH64_SIMD_UNOP: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_STOP); -+ is_void = !!(d->qualifiers[0] & qualifier_void); + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) +@@ -19441,10 +17713,21 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vceq_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmeqdi ((int64x1_t) __a, +- (int64x1_t) __b); ++ return __a == __b ? -1ll : 0ll; + } -- case AARCH64_SIMD_BINOP: -- { -- rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1)); -- /* Handle constants only if the predicate allows it. */ -- bool op1_const_int_p = -- (CONST_INT_P (arg2) -- && (*insn_data[icode].operand[2].predicate) -- (arg2, insn_data[icode].operand[2].mode)); -- return aarch64_simd_expand_args -- (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- op1_const_int_p ? SIMD_ARG_CONSTANT : SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_STOP); -- } -+ num_args += is_void; ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vceqq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return (uint32x4_t) __builtin_aarch64_cmeqv4sf (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vceqq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return (uint64x2_t) __builtin_aarch64_cmeqv2df (__a, __b); ++} ++ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vceqq_p8 (poly8x16_t __a, poly8x16_t __b) + { +@@ -19504,27 +17787,245 @@ + (int64x2_t) __b); + } -- case AARCH64_SIMD_TERNOP: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_STOP); -+ for (k = 1; k < num_args; k++) -+ { -+ /* We have four arrays of data, each indexed in a different fashion. -+ qualifiers - element 0 always describes the function return type. -+ operands - element 0 is either the operand for return value (if -+ the function has a non-void return type) or the operand for the -+ first argument. -+ expr_args - element 0 always holds the first argument. -+ args - element 0 is always used for the return type. */ -+ int qualifiers_k = k; -+ int operands_k = k - is_void; -+ int expr_args_k = k - 1; - -- case AARCH64_SIMD_QUADOP: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_STOP); -- case AARCH64_SIMD_LOAD1: -- case AARCH64_SIMD_LOADSTRUCT: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, SIMD_ARG_STOP); -+ if (d->qualifiers[qualifiers_k] & qualifier_immediate) -+ args[k] = SIMD_ARG_CONSTANT; -+ else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate) -+ { -+ rtx arg -+ = expand_normal (CALL_EXPR_ARG (exp, -+ (expr_args_k))); -+ /* Handle constants only if the predicate allows it. */ -+ bool op_const_int_p = -+ (CONST_INT_P (arg) -+ && (*insn_data[icode].operand[operands_k].predicate) -+ (arg, insn_data[icode].operand[operands_k].mode)); -+ args[k] = op_const_int_p ? SIMD_ARG_CONSTANT : SIMD_ARG_COPY_TO_REG; -+ } -+ else -+ args[k] = SIMD_ARG_COPY_TO_REG; ++/* vceq - scalar. */ ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vceqs_f32 (float32_t __a, float32_t __b) ++{ ++ return __a == __b ? -1 : 0; ++} ++ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vceqd_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, __b); ++ return __a == __b ? -1ll : 0ll; + } -- case AARCH64_SIMD_STORE1: -- case AARCH64_SIMD_STORESTRUCT: -- return aarch64_simd_expand_args (target, icode, 0, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, SIMD_ARG_STOP); -+ } -+ args[k] = SIMD_ARG_STOP; + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vceqd_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, __b); ++ return __a == __b ? -1ll : 0ll; + } -- case AARCH64_SIMD_REINTERP: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, SIMD_ARG_STOP); -- -- case AARCH64_SIMD_CREATE: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, SIMD_ARG_STOP); -- -- case AARCH64_SIMD_COMBINE: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, SIMD_ARG_STOP); -- -- case AARCH64_SIMD_GETLANE: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_CONSTANT, -- SIMD_ARG_STOP); -- -- case AARCH64_SIMD_SETLANE: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_CONSTANT, -- SIMD_ARG_STOP); -- -- case AARCH64_SIMD_SHIFTIMM: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_CONSTANT, -- SIMD_ARG_STOP); -- -- case AARCH64_SIMD_SHIFTACC: -- case AARCH64_SIMD_SHIFTINSERT: -- return aarch64_simd_expand_args (target, icode, 1, exp, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_COPY_TO_REG, -- SIMD_ARG_CONSTANT, -- SIMD_ARG_STOP); -- -- default: -- gcc_unreachable (); -- } -+ /* The interface to aarch64_simd_expand_args expects a 0 if -+ the function is void, and a 1 if it is not. */ -+ return aarch64_simd_expand_args -+ (target, icode, !is_void, exp, -+ args[1], -+ args[2], -+ args[3], -+ args[4], -+ SIMD_ARG_STOP); - } - - /* Expand an expression EXP that calls a built-in function, -@@ -1242,11 +948,11 @@ - #define AARCH64_CHECK_BUILTIN_MODE(C, N) 1 - #define AARCH64_FIND_FRINT_VARIANT(N) \ - (AARCH64_CHECK_BUILTIN_MODE (2, D) \ -- ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v2df] \ -+ ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2df] \ - : (AARCH64_CHECK_BUILTIN_MODE (4, S) \ -- ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v4sf] \ -+ ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v4sf] \ - : (AARCH64_CHECK_BUILTIN_MODE (2, S) \ -- ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v2sf] \ -+ ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2sf] \ - : NULL_TREE))) - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) - { -@@ -1259,30 +965,82 @@ - && in_mode == N##Fmode && in_n == C) - case BUILT_IN_FLOOR: - case BUILT_IN_FLOORF: -- return AARCH64_FIND_FRINT_VARIANT (frintm); -+ return AARCH64_FIND_FRINT_VARIANT (floor); - case BUILT_IN_CEIL: - case BUILT_IN_CEILF: -- return AARCH64_FIND_FRINT_VARIANT (frintp); -+ return AARCH64_FIND_FRINT_VARIANT (ceil); - case BUILT_IN_TRUNC: - case BUILT_IN_TRUNCF: -- return AARCH64_FIND_FRINT_VARIANT (frintz); -+ return AARCH64_FIND_FRINT_VARIANT (btrunc); - case BUILT_IN_ROUND: - case BUILT_IN_ROUNDF: -- return AARCH64_FIND_FRINT_VARIANT (frinta); -+ return AARCH64_FIND_FRINT_VARIANT (round); - case BUILT_IN_NEARBYINT: - case BUILT_IN_NEARBYINTF: -- return AARCH64_FIND_FRINT_VARIANT (frinti); -+ return AARCH64_FIND_FRINT_VARIANT (nearbyint); - case BUILT_IN_SQRT: - case BUILT_IN_SQRTF: - return AARCH64_FIND_FRINT_VARIANT (sqrt); - #undef AARCH64_CHECK_BUILTIN_MODE - #define AARCH64_CHECK_BUILTIN_MODE(C, N) \ -+ (out_mode == SImode && out_n == C \ -+ && in_mode == N##Imode && in_n == C) -+ case BUILT_IN_CLZ: -+ { -+ if (AARCH64_CHECK_BUILTIN_MODE (4, S)) -+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si]; -+ return NULL_TREE; -+ } -+#undef AARCH64_CHECK_BUILTIN_MODE -+#define AARCH64_CHECK_BUILTIN_MODE(C, N) \ - (out_mode == N##Imode && out_n == C \ - && in_mode == N##Fmode && in_n == C) - case BUILT_IN_LFLOOR: -- return AARCH64_FIND_FRINT_VARIANT (fcvtms); -+ case BUILT_IN_IFLOORF: -+ { -+ enum aarch64_builtins builtin; -+ if (AARCH64_CHECK_BUILTIN_MODE (2, D)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2dfv2di; -+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv4sfv4si; -+ else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2sfv2si; -+ else -+ return NULL_TREE; ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vceqd_f64 (float64_t __a, float64_t __b) ++{ ++ return __a == __b ? -1ll : 0ll; ++} + -+ return aarch64_builtin_decls[builtin]; -+ } - case BUILT_IN_LCEIL: -- return AARCH64_FIND_FRINT_VARIANT (fcvtps); -+ case BUILT_IN_ICEILF: -+ { -+ enum aarch64_builtins builtin; -+ if (AARCH64_CHECK_BUILTIN_MODE (2, D)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2dfv2di; -+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv4sfv4si; -+ else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2sfv2si; -+ else -+ return NULL_TREE; ++/* vceqz - vector. */ + -+ return aarch64_builtin_decls[builtin]; -+ } -+ case BUILT_IN_LROUND: -+ case BUILT_IN_IROUNDF: -+ { -+ enum aarch64_builtins builtin; -+ if (AARCH64_CHECK_BUILTIN_MODE (2, D)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2dfv2di; -+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv4sfv4si; -+ else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) -+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2sfv2si; -+ else -+ return NULL_TREE; ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vceqz_f32 (float32x2_t __a) ++{ ++ float32x2_t __b = {0.0f, 0.0f}; ++ return (uint32x2_t) __builtin_aarch64_cmeqv2sf (__a, __b); ++} + -+ return aarch64_builtin_decls[builtin]; -+ } + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vceqz_f64 (float64x1_t __a) ++{ ++ return __a == 0.0 ? -1ll : 0ll; ++} + - default: - return NULL_TREE; - } -@@ -1290,5 +1048,160 @@ - - return NULL_TREE; - } ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vceqz_p8 (poly8x8_t __a) ++{ ++ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmeqv8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+#undef VAR1 -+#define VAR1(T, N, MAP, A) \ -+ case AARCH64_SIMD_BUILTIN_##T##_##N##A: ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vceqz_s8 (int8x8_t __a) ++{ ++ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmeqv8qi (__a, __b); ++} + -+tree -+aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args, -+ bool ignore ATTRIBUTE_UNUSED) ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vceqz_s16 (int16x4_t __a) +{ -+ int fcode = DECL_FUNCTION_CODE (fndecl); -+ tree type = TREE_TYPE (TREE_TYPE (fndecl)); ++ int16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmeqv4hi (__a, __b); ++} + -+ switch (fcode) -+ { -+ BUILTIN_VALLDI (UNOP, abs, 2) -+ return fold_build1 (ABS_EXPR, type, args[0]); -+ break; -+ BUILTIN_VALLDI (BINOP, cmge, 0) -+ return fold_build2 (GE_EXPR, type, args[0], args[1]); -+ break; -+ BUILTIN_VALLDI (BINOP, cmgt, 0) -+ return fold_build2 (GT_EXPR, type, args[0], args[1]); -+ break; -+ BUILTIN_VALLDI (BINOP, cmeq, 0) -+ return fold_build2 (EQ_EXPR, type, args[0], args[1]); -+ break; -+ BUILTIN_VSDQ_I_DI (BINOP, cmtst, 0) -+ { -+ tree and_node = fold_build2 (BIT_AND_EXPR, type, args[0], args[1]); -+ tree vec_zero_node = build_zero_cst (type); -+ return fold_build2 (NE_EXPR, type, and_node, vec_zero_node); -+ break; -+ } -+ VAR1 (UNOP, floatv2si, 2, v2sf) -+ VAR1 (UNOP, floatv4si, 2, v4sf) -+ VAR1 (UNOP, floatv2di, 2, v2df) -+ return fold_build1 (FLOAT_EXPR, type, args[0]); -+ default: -+ break; -+ } ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vceqz_s32 (int32x2_t __a) ++{ ++ int32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmeqv2si (__a, __b); ++} + -+ return NULL_TREE; ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vceqz_s64 (int64x1_t __a) ++{ ++ return __a == 0ll ? -1ll : 0ll; +} + -+bool -+aarch64_gimple_fold_builtin (gimple_stmt_iterator *gsi) ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vceqz_u8 (uint8x8_t __a) +{ -+ bool changed = false; -+ gimple stmt = gsi_stmt (*gsi); -+ tree call = gimple_call_fn (stmt); -+ tree fndecl; -+ gimple new_stmt = NULL; -+ if (call) -+ { -+ fndecl = gimple_call_fndecl (stmt); -+ if (fndecl) -+ { -+ int fcode = DECL_FUNCTION_CODE (fndecl); -+ int nargs = gimple_call_num_args (stmt); -+ tree *args = (nargs > 0 -+ ? gimple_call_arg_ptr (stmt, 0) -+ : &error_mark_node); ++ uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmeqv8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+ switch (fcode) -+ { -+ BUILTIN_VALL (UNOP, reduc_splus_, 10) -+ new_stmt = gimple_build_assign_with_ops ( -+ REDUC_PLUS_EXPR, -+ gimple_call_lhs (stmt), -+ args[0], -+ NULL_TREE); -+ break; -+ BUILTIN_VDQIF (UNOP, reduc_smax_, 10) -+ new_stmt = gimple_build_assign_with_ops ( -+ REDUC_MAX_EXPR, -+ gimple_call_lhs (stmt), -+ args[0], -+ NULL_TREE); -+ break; -+ BUILTIN_VDQIF (UNOP, reduc_smin_, 10) -+ new_stmt = gimple_build_assign_with_ops ( -+ REDUC_MIN_EXPR, -+ gimple_call_lhs (stmt), -+ args[0], -+ NULL_TREE); -+ break; ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vceqz_u16 (uint16x4_t __a) ++{ ++ uint16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmeqv4hi ((int16x4_t) __a, ++ (int16x4_t) __b); ++} + -+ default: -+ break; -+ } -+ } -+ } ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vceqz_u32 (uint32x2_t __a) ++{ ++ uint32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmeqv2si ((int32x2_t) __a, ++ (int32x2_t) __b); ++} + -+ if (new_stmt) -+ { -+ gsi_replace (gsi, new_stmt, true); -+ changed = true; -+ } ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vceqz_u64 (uint64x1_t __a) ++{ ++ return __a == 0ll ? -1ll : 0ll; ++} + -+ return changed; ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vceqzq_f32 (float32x4_t __a) ++{ ++ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; ++ return (uint32x4_t) __builtin_aarch64_cmeqv4sf (__a, __b); +} + - #undef AARCH64_CHECK_BUILTIN_MODE - #undef AARCH64_FIND_FRINT_VARIANT -+#undef BUILTIN_DX -+#undef BUILTIN_SDQ_I -+#undef BUILTIN_SD_HSI -+#undef BUILTIN_V2F -+#undef BUILTIN_VALL -+#undef BUILTIN_VB -+#undef BUILTIN_VD -+#undef BUILTIN_VDC -+#undef BUILTIN_VDIC -+#undef BUILTIN_VDN -+#undef BUILTIN_VDQ -+#undef BUILTIN_VDQF -+#undef BUILTIN_VDQH -+#undef BUILTIN_VDQHS -+#undef BUILTIN_VDQIF -+#undef BUILTIN_VDQM -+#undef BUILTIN_VDQV -+#undef BUILTIN_VDQ_BHSI -+#undef BUILTIN_VDQ_I -+#undef BUILTIN_VDW -+#undef BUILTIN_VD_BHSI -+#undef BUILTIN_VD_HSI -+#undef BUILTIN_VD_RE -+#undef BUILTIN_VQ -+#undef BUILTIN_VQN -+#undef BUILTIN_VQW -+#undef BUILTIN_VQ_HSI -+#undef BUILTIN_VQ_S -+#undef BUILTIN_VSDQ_HSI -+#undef BUILTIN_VSDQ_I -+#undef BUILTIN_VSDQ_I_BHSI -+#undef BUILTIN_VSDQ_I_DI -+#undef BUILTIN_VSD_HSI -+#undef BUILTIN_VSQN_HSDI -+#undef BUILTIN_VSTRUCT -+#undef CF0 -+#undef CF1 -+#undef CF2 -+#undef CF3 -+#undef CF4 -+#undef CF10 -+#undef VAR1 -+#undef VAR2 -+#undef VAR3 -+#undef VAR4 -+#undef VAR5 -+#undef VAR6 -+#undef VAR7 -+#undef VAR8 -+#undef VAR9 -+#undef VAR10 -+#undef VAR11 ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vceqzq_f64 (float64x2_t __a) ++{ ++ float64x2_t __b = {0.0, 0.0}; ++ return (uint64x2_t) __builtin_aarch64_cmeqv2df (__a, __b); ++} + ---- a/src/gcc/config/aarch64/aarch64-protos.h -+++ b/src/gcc/config/aarch64/aarch64-protos.h -@@ -68,6 +68,24 @@ - Each of of these represents a thread-local symbol, and corresponds to the - thread local storage relocation operator for the symbol being referred to. - -+ SYMBOL_TINY_ABSOLUTE ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vceqzq_p8 (poly8x16_t __a) ++{ ++ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmeqv16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} + -+ Generate symbol accesses as a PC relative address using a single -+ instruction. To compute the address of symbol foo, we generate: ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vceqzq_s8 (int8x16_t __a) ++{ ++ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmeqv16qi (__a, __b); ++} + -+ ADR x0, foo ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vceqzq_s16 (int16x8_t __a) ++{ ++ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmeqv8hi (__a, __b); ++} + -+ SYMBOL_TINY_GOT ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vceqzq_s32 (int32x4_t __a) ++{ ++ int32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmeqv4si (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vceqzq_s64 (int64x2_t __a) ++{ ++ int64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmeqv2di (__a, __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vceqzq_u8 (uint8x16_t __a) ++{ ++ uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmeqv16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} + -+ Generate symbol accesses via the GOT using a single PC relative -+ instruction. To compute the address of symbol foo, we generate: ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vceqzq_u16 (uint16x8_t __a) ++{ ++ uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmeqv8hi ((int16x8_t) __a, ++ (int16x8_t) __b); ++} + -+ ldr t0, :got:foo ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vceqzq_u32 (uint32x4_t __a) ++{ ++ uint32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmeqv4si ((int32x4_t) __a, ++ (int32x4_t) __b); ++} + -+ The value of foo can subsequently read using: ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vceqzq_u64 (uint64x2_t __a) ++{ ++ uint64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmeqv2di ((int64x2_t) __a, ++ (int64x2_t) __b); ++} + -+ ldrb t0, [t0] ++/* vceqz - scalar. */ + - SYMBOL_FORCE_TO_MEM : Global variables are addressed using - constant pool. All variable addresses are spilled into constant - pools. The constant pools themselves are addressed using PC -@@ -81,6 +99,8 @@ - SYMBOL_SMALL_TLSDESC, - SYMBOL_SMALL_GOTTPREL, - SYMBOL_SMALL_TPREL, -+ SYMBOL_TINY_ABSOLUTE, -+ SYMBOL_TINY_GOT, - SYMBOL_FORCE_TO_MEM - }; - -@@ -126,25 +146,55 @@ - const int FP2FP; - }; - -+/* Cost for vector insn classes. */ -+struct cpu_vector_cost ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vceqzs_f32 (float32_t __a) +{ -+ const int scalar_stmt_cost; /* Cost of any scalar operation, -+ excluding load and store. */ -+ const int scalar_load_cost; /* Cost of scalar load. */ -+ const int scalar_store_cost; /* Cost of scalar store. */ -+ const int vec_stmt_cost; /* Cost of any vector operation, -+ excluding load, store, -+ vector-to-scalar and -+ scalar-to-vector operation. */ -+ const int vec_to_scalar_cost; /* Cost of vec-to-scalar operation. */ -+ const int scalar_to_vec_cost; /* Cost of scalar-to-vector -+ operation. */ -+ const int vec_align_load_cost; /* Cost of aligned vector load. */ -+ const int vec_unalign_load_cost; /* Cost of unaligned vector load. */ -+ const int vec_unalign_store_cost; /* Cost of unaligned vector store. */ -+ const int vec_store_cost; /* Cost of vector store. */ -+ const int cond_taken_branch_cost; /* Cost of taken branch. */ -+ const int cond_not_taken_branch_cost; /* Cost of not taken branch. */ -+}; ++ return __a == 0.0f ? -1 : 0; ++} + - struct tune_params ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vceqzd_s64 (int64x1_t __a) { - const struct cpu_rtx_cost_table *const insn_extra_cost; - const struct cpu_addrcost_table *const addr_cost; - const struct cpu_regmove_cost *const regmove_cost; -+ const struct cpu_vector_cost *const vec_costs; - const int memmov_cost; - }; - - HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned); - bool aarch64_bitmask_imm (HOST_WIDE_INT val, enum machine_mode); -+enum aarch64_symbol_type -+aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context); - bool aarch64_constant_address_p (rtx); - bool aarch64_float_const_zero_rtx_p (rtx); - bool aarch64_function_arg_regno_p (unsigned); - bool aarch64_gen_movmemqi (rtx *); -+bool aarch64_gimple_fold_builtin (gimple_stmt_iterator *); - bool aarch64_is_extend_from_extract (enum machine_mode, rtx, rtx); - bool aarch64_is_long_call_p (rtx); - bool aarch64_label_mentioned_p (rtx); - bool aarch64_legitimate_pic_operand_p (rtx); - bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode); -+bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context, -+ enum machine_mode); -+char *aarch64_output_scalar_simd_mov_immediate (rtx, enum machine_mode); -+char *aarch64_output_simd_mov_immediate (rtx, enum machine_mode, unsigned); - bool aarch64_pad_arg_upward (enum machine_mode, const_tree); - bool aarch64_pad_reg_upward (enum machine_mode, const_tree, bool); - bool aarch64_regno_ok_for_base_p (int, bool); -@@ -151,10 +201,11 @@ - bool aarch64_regno_ok_for_index_p (int, bool); - bool aarch64_simd_imm_scalar_p (rtx x, enum machine_mode mode); - bool aarch64_simd_imm_zero_p (rtx, enum machine_mode); -+bool aarch64_simd_scalar_immediate_valid_for_move (rtx, enum machine_mode); - bool aarch64_simd_shift_imm_p (rtx, enum machine_mode, bool); -+bool aarch64_simd_valid_immediate (rtx, enum machine_mode, bool, -+ struct simd_immediate_info *); - bool aarch64_symbolic_address_p (rtx); --bool aarch64_symbolic_constant_p (rtx, enum aarch64_symbol_context, -- enum aarch64_symbol_type *); - bool aarch64_uimm12_shift (HOST_WIDE_INT); - const char *aarch64_output_casesi (rtx *); - enum aarch64_symbol_type aarch64_classify_symbol (rtx, -@@ -165,9 +216,6 @@ - int aarch64_hard_regno_mode_ok (unsigned, enum machine_mode); - int aarch64_hard_regno_nregs (unsigned, enum machine_mode); - int aarch64_simd_attr_length_move (rtx); --int aarch64_simd_immediate_valid_for_move (rtx, enum machine_mode, rtx *, -- int *, unsigned char *, int *, -- int *); - int aarch64_uxt_size (int, HOST_WIDE_INT); - rtx aarch64_final_eh_return_addr (void); - rtx aarch64_legitimize_reload_address (rtx *, enum machine_mode, int, int, int); -@@ -177,6 +225,7 @@ - bool aarch64_simd_mem_operand_p (rtx); - rtx aarch64_simd_vect_par_cnst_half (enum machine_mode, bool); - rtx aarch64_tls_get_addr (void); -+tree aarch64_fold_builtin (tree, int, tree *, bool); - unsigned aarch64_dbx_register_number (unsigned); - unsigned aarch64_trampoline_size (void); - void aarch64_asm_output_labelref (FILE *, const char *); -@@ -216,6 +265,10 @@ +- return (uint64x1_t) __builtin_aarch64_cmeqdi (__a, 0); ++ return __a == 0 ? -1ll : 0ll; + } - bool aarch64_split_128bit_move_p (rtx, rtx); +-/* vcge */ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vceqzd_u64 (int64x1_t __a) ++{ ++ return __a == 0 ? -1ll : 0ll; ++} -+void aarch64_split_simd_combine (rtx, rtx, rtx); -+ -+void aarch64_split_simd_move (rtx, rtx); ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vceqzd_f64 (float64_t __a) ++{ ++ return __a == 0.0 ? -1ll : 0ll; ++} + - /* Check for a legitimate floating point constant for FMOV. */ - bool aarch64_float_const_representable_p (rtx); - -@@ -249,6 +302,4 @@ - extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel); - extern bool - aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel); -- --char* aarch64_output_simd_mov_immediate (rtx *, enum machine_mode, unsigned); - #endif /* GCC_AARCH64_PROTOS_H */ ---- a/src/gcc/config/aarch64/aarch64-simd-builtins.def -+++ b/src/gcc/config/aarch64/aarch64-simd-builtins.def -@@ -18,248 +18,367 @@ - along with GCC; see the file COPYING3. If not see - . */ - --/* In the list below, the BUILTIN_ macros should -- correspond to the iterator used to construct the instruction's -- patterns in aarch64-simd.md. A helpful idiom to follow when -- adding new builtins is to add a line for each pattern in the md -- file. Thus, ADDP, which has one pattern defined for the VD_BHSI -- iterator, and one for DImode, has two entries below. */ -+/* In the list below, the BUILTIN_ macros expand to create -+ builtins for each of the modes described by . When adding -+ new builtins to this list, a helpful idiom to follow is to add -+ a line for each pattern in the md file. Thus, ADDP, which has one -+ pattern defined for the VD_BHSI iterator, and one for DImode, has two -+ entries below. - -- BUILTIN_VD_RE (CREATE, create) -- BUILTIN_VQ_S (GETLANE, get_lane_signed) -- BUILTIN_VDQ (GETLANE, get_lane_unsigned) -- BUILTIN_VDQF (GETLANE, get_lane) -- VAR1 (GETLANE, get_lane, di) -- BUILTIN_VDC (COMBINE, combine) -- BUILTIN_VB (BINOP, pmul) -- BUILTIN_VDQF (UNOP, sqrt) -- BUILTIN_VD_BHSI (BINOP, addp) -- VAR1 (UNOP, addp, di) -+ Parameter 1 is the 'type' of the intrinsic. This is used to -+ describe the type modifiers (for example; unsigned) applied to -+ each of the parameters to the intrinsic function. - -- BUILTIN_VD_RE (REINTERP, reinterpretdi) -- BUILTIN_VDC (REINTERP, reinterpretv8qi) -- BUILTIN_VDC (REINTERP, reinterpretv4hi) -- BUILTIN_VDC (REINTERP, reinterpretv2si) -- BUILTIN_VDC (REINTERP, reinterpretv2sf) -- BUILTIN_VQ (REINTERP, reinterpretv16qi) -- BUILTIN_VQ (REINTERP, reinterpretv8hi) -- BUILTIN_VQ (REINTERP, reinterpretv4si) -- BUILTIN_VQ (REINTERP, reinterpretv4sf) -- BUILTIN_VQ (REINTERP, reinterpretv2di) -- BUILTIN_VQ (REINTERP, reinterpretv2df) -+ Parameter 2 is the name of the intrinsic. This is appended -+ to `__builtin_aarch64_` to give the intrinsic name -+ as exported to the front-ends. - -- BUILTIN_VDQ_I (BINOP, dup_lane) -- BUILTIN_SDQ_I (BINOP, dup_lane) -+ Parameter 3 describes how to map from the name to the CODE_FOR_ -+ macro holding the RTL pattern for the intrinsic. This mapping is: -+ 0 - CODE_FOR_aarch64_ -+ 1-9 - CODE_FOR_<1-9> -+ 10 - CODE_FOR_. */ ++/* vcge - vector. */ + -+ BUILTIN_VD_RE (CREATE, create, 0) -+ BUILTIN_VDC (COMBINE, combine, 0) -+ BUILTIN_VB (BINOP, pmul, 0) -+ BUILTIN_VDQF (UNOP, sqrt, 2) -+ BUILTIN_VD_BHSI (BINOP, addp, 0) -+ VAR1 (UNOP, addp, 0, di) -+ VAR1 (UNOP, clz, 2, v4si) ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcge_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return (uint32x2_t) __builtin_aarch64_cmgev2sf (__a, __b); ++} + -+ BUILTIN_VALL (GETLANE, get_lane, 0) -+ VAR1 (GETLANE, get_lane, 0, di) ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcge_f64 (float64x1_t __a, float64x1_t __b) ++{ ++ return __a >= __b ? -1ll : 0ll; ++} + -+ BUILTIN_VD_RE (REINTERP, reinterpretdi, 0) -+ BUILTIN_VDC (REINTERP, reinterpretv8qi, 0) -+ BUILTIN_VDC (REINTERP, reinterpretv4hi, 0) -+ BUILTIN_VDC (REINTERP, reinterpretv2si, 0) -+ BUILTIN_VDC (REINTERP, reinterpretv2sf, 0) -+ BUILTIN_VQ (REINTERP, reinterpretv16qi, 0) -+ BUILTIN_VQ (REINTERP, reinterpretv8hi, 0) -+ BUILTIN_VQ (REINTERP, reinterpretv4si, 0) -+ BUILTIN_VQ (REINTERP, reinterpretv4sf, 0) -+ BUILTIN_VQ (REINTERP, reinterpretv2di, 0) -+ BUILTIN_VQ (REINTERP, reinterpretv2df, 0) + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcge_p8 (poly8x8_t __a, poly8x8_t __b) ++{ ++ return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+ BUILTIN_VDQ_I (BINOP, dup_lane, 0) - /* Implemented by aarch64_qshl. */ -- BUILTIN_VSDQ_I (BINOP, sqshl) -- BUILTIN_VSDQ_I (BINOP, uqshl) -- BUILTIN_VSDQ_I (BINOP, sqrshl) -- BUILTIN_VSDQ_I (BINOP, uqrshl) -+ BUILTIN_VSDQ_I (BINOP, sqshl, 0) -+ BUILTIN_VSDQ_I (BINOP, uqshl, 0) -+ BUILTIN_VSDQ_I (BINOP, sqrshl, 0) -+ BUILTIN_VSDQ_I (BINOP, uqrshl, 0) - /* Implemented by aarch64_. */ -- BUILTIN_VSDQ_I (BINOP, sqadd) -- BUILTIN_VSDQ_I (BINOP, uqadd) -- BUILTIN_VSDQ_I (BINOP, sqsub) -- BUILTIN_VSDQ_I (BINOP, uqsub) -+ BUILTIN_VSDQ_I (BINOP, sqadd, 0) -+ BUILTIN_VSDQ_I (BINOP, uqadd, 0) -+ BUILTIN_VSDQ_I (BINOP, sqsub, 0) -+ BUILTIN_VSDQ_I (BINOP, uqsub, 0) - /* Implemented by aarch64_qadd. */ -- BUILTIN_VSDQ_I (BINOP, suqadd) -- BUILTIN_VSDQ_I (BINOP, usqadd) -+ BUILTIN_VSDQ_I (BINOP, suqadd, 0) -+ BUILTIN_VSDQ_I (BINOP, usqadd, 0) - - /* Implemented by aarch64_get_dreg. */ -- BUILTIN_VDC (GETLANE, get_dregoi) -- BUILTIN_VDC (GETLANE, get_dregci) -- BUILTIN_VDC (GETLANE, get_dregxi) -+ BUILTIN_VDC (GETLANE, get_dregoi, 0) -+ BUILTIN_VDC (GETLANE, get_dregci, 0) -+ BUILTIN_VDC (GETLANE, get_dregxi, 0) - /* Implemented by aarch64_get_qreg. */ -- BUILTIN_VQ (GETLANE, get_qregoi) -- BUILTIN_VQ (GETLANE, get_qregci) -- BUILTIN_VQ (GETLANE, get_qregxi) -+ BUILTIN_VQ (GETLANE, get_qregoi, 0) -+ BUILTIN_VQ (GETLANE, get_qregci, 0) -+ BUILTIN_VQ (GETLANE, get_qregxi, 0) - /* Implemented by aarch64_set_qreg. */ -- BUILTIN_VQ (SETLANE, set_qregoi) -- BUILTIN_VQ (SETLANE, set_qregci) -- BUILTIN_VQ (SETLANE, set_qregxi) -+ BUILTIN_VQ (SETLANE, set_qregoi, 0) -+ BUILTIN_VQ (SETLANE, set_qregci, 0) -+ BUILTIN_VQ (SETLANE, set_qregxi, 0) - /* Implemented by aarch64_ld. */ -- BUILTIN_VDC (LOADSTRUCT, ld2) -- BUILTIN_VDC (LOADSTRUCT, ld3) -- BUILTIN_VDC (LOADSTRUCT, ld4) -+ BUILTIN_VDC (LOADSTRUCT, ld2, 0) -+ BUILTIN_VDC (LOADSTRUCT, ld3, 0) -+ BUILTIN_VDC (LOADSTRUCT, ld4, 0) - /* Implemented by aarch64_ld. */ -- BUILTIN_VQ (LOADSTRUCT, ld2) -- BUILTIN_VQ (LOADSTRUCT, ld3) -- BUILTIN_VQ (LOADSTRUCT, ld4) -+ BUILTIN_VQ (LOADSTRUCT, ld2, 0) -+ BUILTIN_VQ (LOADSTRUCT, ld3, 0) -+ BUILTIN_VQ (LOADSTRUCT, ld4, 0) - /* Implemented by aarch64_st. */ -- BUILTIN_VDC (STORESTRUCT, st2) -- BUILTIN_VDC (STORESTRUCT, st3) -- BUILTIN_VDC (STORESTRUCT, st4) -+ BUILTIN_VDC (STORESTRUCT, st2, 0) -+ BUILTIN_VDC (STORESTRUCT, st3, 0) -+ BUILTIN_VDC (STORESTRUCT, st4, 0) - /* Implemented by aarch64_st. */ -- BUILTIN_VQ (STORESTRUCT, st2) -- BUILTIN_VQ (STORESTRUCT, st3) -- BUILTIN_VQ (STORESTRUCT, st4) -+ BUILTIN_VQ (STORESTRUCT, st2, 0) -+ BUILTIN_VQ (STORESTRUCT, st3, 0) -+ BUILTIN_VQ (STORESTRUCT, st4, 0) ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vcge_s8 (int8x8_t __a, int8x8_t __b) + { + return (uint8x8_t) __builtin_aarch64_cmgev8qi (__a, __b); +@@ -19545,38 +18046,56 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcge_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmgedi (__a, __b); ++ return __a >= __b ? -1ll : 0ll; + } -- BUILTIN_VQW (BINOP, saddl2) -- BUILTIN_VQW (BINOP, uaddl2) -- BUILTIN_VQW (BINOP, ssubl2) -- BUILTIN_VQW (BINOP, usubl2) -- BUILTIN_VQW (BINOP, saddw2) -- BUILTIN_VQW (BINOP, uaddw2) -- BUILTIN_VQW (BINOP, ssubw2) -- BUILTIN_VQW (BINOP, usubw2) -+ BUILTIN_VQW (BINOP, saddl2, 0) -+ BUILTIN_VQW (BINOP, uaddl2, 0) -+ BUILTIN_VQW (BINOP, ssubl2, 0) -+ BUILTIN_VQW (BINOP, usubl2, 0) -+ BUILTIN_VQW (BINOP, saddw2, 0) -+ BUILTIN_VQW (BINOP, uaddw2, 0) -+ BUILTIN_VQW (BINOP, ssubw2, 0) -+ BUILTIN_VQW (BINOP, usubw2, 0) - /* Implemented by aarch64_l. */ -- BUILTIN_VDW (BINOP, saddl) -- BUILTIN_VDW (BINOP, uaddl) -- BUILTIN_VDW (BINOP, ssubl) -- BUILTIN_VDW (BINOP, usubl) -+ BUILTIN_VDW (BINOP, saddl, 0) -+ BUILTIN_VDW (BINOP, uaddl, 0) -+ BUILTIN_VDW (BINOP, ssubl, 0) -+ BUILTIN_VDW (BINOP, usubl, 0) - /* Implemented by aarch64_w. */ -- BUILTIN_VDW (BINOP, saddw) -- BUILTIN_VDW (BINOP, uaddw) -- BUILTIN_VDW (BINOP, ssubw) -- BUILTIN_VDW (BINOP, usubw) -+ BUILTIN_VDW (BINOP, saddw, 0) -+ BUILTIN_VDW (BINOP, uaddw, 0) -+ BUILTIN_VDW (BINOP, ssubw, 0) -+ BUILTIN_VDW (BINOP, usubw, 0) - /* Implemented by aarch64_h. */ -- BUILTIN_VQ_S (BINOP, shadd) -- BUILTIN_VQ_S (BINOP, uhadd) -- BUILTIN_VQ_S (BINOP, srhadd) -- BUILTIN_VQ_S (BINOP, urhadd) -+ BUILTIN_VQ_S (BINOP, shadd, 0) -+ BUILTIN_VQ_S (BINOP, uhadd, 0) -+ BUILTIN_VQ_S (BINOP, srhadd, 0) -+ BUILTIN_VQ_S (BINOP, urhadd, 0) - /* Implemented by aarch64_hn. */ -- BUILTIN_VQN (BINOP, addhn) -- BUILTIN_VQN (BINOP, raddhn) -+ BUILTIN_VQN (BINOP, addhn, 0) -+ BUILTIN_VQN (BINOP, raddhn, 0) - /* Implemented by aarch64_hn2. */ -- BUILTIN_VQN (TERNOP, addhn2) -- BUILTIN_VQN (TERNOP, raddhn2) -+ BUILTIN_VQN (TERNOP, addhn2, 0) -+ BUILTIN_VQN (TERNOP, raddhn2, 0) + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vcge_u8 (uint8x8_t __a, uint8x8_t __b) + { +- return (uint8x8_t) __builtin_aarch64_cmhsv8qi ((int8x8_t) __a, ++ return (uint8x8_t) __builtin_aarch64_cmgeuv8qi ((int8x8_t) __a, + (int8x8_t) __b); + } -- BUILTIN_VSQN_HSDI (UNOP, sqmovun) -+ BUILTIN_VSQN_HSDI (UNOP, sqmovun, 0) - /* Implemented by aarch64_qmovn. */ -- BUILTIN_VSQN_HSDI (UNOP, sqmovn) -- BUILTIN_VSQN_HSDI (UNOP, uqmovn) -+ BUILTIN_VSQN_HSDI (UNOP, sqmovn, 0) -+ BUILTIN_VSQN_HSDI (UNOP, uqmovn, 0) - /* Implemented by aarch64_s. */ -- BUILTIN_VSDQ_I_BHSI (UNOP, sqabs) -- BUILTIN_VSDQ_I_BHSI (UNOP, sqneg) -+ BUILTIN_VSDQ_I_BHSI (UNOP, sqabs, 0) -+ BUILTIN_VSDQ_I_BHSI (UNOP, sqneg, 0) + __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) + vcge_u16 (uint16x4_t __a, uint16x4_t __b) + { +- return (uint16x4_t) __builtin_aarch64_cmhsv4hi ((int16x4_t) __a, ++ return (uint16x4_t) __builtin_aarch64_cmgeuv4hi ((int16x4_t) __a, + (int16x4_t) __b); + } -- BUILTIN_VSD_HSI (QUADOP, sqdmlal_lane) -- BUILTIN_VSD_HSI (QUADOP, sqdmlsl_lane) -- BUILTIN_VSD_HSI (QUADOP, sqdmlal_laneq) -- BUILTIN_VSD_HSI (QUADOP, sqdmlsl_laneq) -- BUILTIN_VQ_HSI (TERNOP, sqdmlal2) -- BUILTIN_VQ_HSI (TERNOP, sqdmlsl2) -- BUILTIN_VQ_HSI (QUADOP, sqdmlal2_lane) -- BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_lane) -- BUILTIN_VQ_HSI (QUADOP, sqdmlal2_laneq) -- BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_laneq) -- BUILTIN_VQ_HSI (TERNOP, sqdmlal2_n) -- BUILTIN_VQ_HSI (TERNOP, sqdmlsl2_n) -+ BUILTIN_VSD_HSI (QUADOP, sqdmlal_lane, 0) -+ BUILTIN_VSD_HSI (QUADOP, sqdmlsl_lane, 0) -+ BUILTIN_VSD_HSI (QUADOP, sqdmlal_laneq, 0) -+ BUILTIN_VSD_HSI (QUADOP, sqdmlsl_laneq, 0) -+ BUILTIN_VQ_HSI (TERNOP, sqdmlal2, 0) -+ BUILTIN_VQ_HSI (TERNOP, sqdmlsl2, 0) -+ BUILTIN_VQ_HSI (QUADOP, sqdmlal2_lane, 0) -+ BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_lane, 0) -+ BUILTIN_VQ_HSI (QUADOP, sqdmlal2_laneq, 0) -+ BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_laneq, 0) -+ BUILTIN_VQ_HSI (TERNOP, sqdmlal2_n, 0) -+ BUILTIN_VQ_HSI (TERNOP, sqdmlsl2_n, 0) - /* Implemented by aarch64_sqdmll. */ -- BUILTIN_VSD_HSI (TERNOP, sqdmlal) -- BUILTIN_VSD_HSI (TERNOP, sqdmlsl) -+ BUILTIN_VSD_HSI (TERNOP, sqdmlal, 0) -+ BUILTIN_VSD_HSI (TERNOP, sqdmlsl, 0) - /* Implemented by aarch64_sqdmll_n. */ -- BUILTIN_VD_HSI (TERNOP, sqdmlal_n) -- BUILTIN_VD_HSI (TERNOP, sqdmlsl_n) -+ BUILTIN_VD_HSI (TERNOP, sqdmlal_n, 0) -+ BUILTIN_VD_HSI (TERNOP, sqdmlsl_n, 0) + __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) + vcge_u32 (uint32x2_t __a, uint32x2_t __b) + { +- return (uint32x2_t) __builtin_aarch64_cmhsv2si ((int32x2_t) __a, ++ return (uint32x2_t) __builtin_aarch64_cmgeuv2si ((int32x2_t) __a, + (int32x2_t) __b); + } -- BUILTIN_VSD_HSI (BINOP, sqdmull) -- BUILTIN_VSD_HSI (TERNOP, sqdmull_lane) -- BUILTIN_VD_HSI (TERNOP, sqdmull_laneq) -- BUILTIN_VD_HSI (BINOP, sqdmull_n) -- BUILTIN_VQ_HSI (BINOP, sqdmull2) -- BUILTIN_VQ_HSI (TERNOP, sqdmull2_lane) -- BUILTIN_VQ_HSI (TERNOP, sqdmull2_laneq) -- BUILTIN_VQ_HSI (BINOP, sqdmull2_n) -+ BUILTIN_VSD_HSI (BINOP, sqdmull, 0) -+ BUILTIN_VSD_HSI (TERNOP, sqdmull_lane, 0) -+ BUILTIN_VD_HSI (TERNOP, sqdmull_laneq, 0) -+ BUILTIN_VD_HSI (BINOP, sqdmull_n, 0) -+ BUILTIN_VQ_HSI (BINOP, sqdmull2, 0) -+ BUILTIN_VQ_HSI (TERNOP, sqdmull2_lane, 0) -+ BUILTIN_VQ_HSI (TERNOP, sqdmull2_laneq, 0) -+ BUILTIN_VQ_HSI (BINOP, sqdmull2_n, 0) - /* Implemented by aarch64_sqdmulh. */ -- BUILTIN_VSDQ_HSI (BINOP, sqdmulh) -- BUILTIN_VSDQ_HSI (BINOP, sqrdmulh) -+ BUILTIN_VSDQ_HSI (BINOP, sqdmulh, 0) -+ BUILTIN_VSDQ_HSI (BINOP, sqrdmulh, 0) - /* Implemented by aarch64_sqdmulh_lane. */ -- BUILTIN_VDQHS (TERNOP, sqdmulh_lane) -- BUILTIN_VDQHS (TERNOP, sqdmulh_laneq) -- BUILTIN_VDQHS (TERNOP, sqrdmulh_lane) -- BUILTIN_VDQHS (TERNOP, sqrdmulh_laneq) -- BUILTIN_SD_HSI (TERNOP, sqdmulh_lane) -- BUILTIN_SD_HSI (TERNOP, sqrdmulh_lane) -+ BUILTIN_VDQHS (TERNOP, sqdmulh_lane, 0) -+ BUILTIN_VDQHS (TERNOP, sqdmulh_laneq, 0) -+ BUILTIN_VDQHS (TERNOP, sqrdmulh_lane, 0) -+ BUILTIN_VDQHS (TERNOP, sqrdmulh_laneq, 0) -+ BUILTIN_SD_HSI (TERNOP, sqdmulh_lane, 0) -+ BUILTIN_SD_HSI (TERNOP, sqrdmulh_lane, 0) + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcge_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmhsdi ((int64x1_t) __a, +- (int64x1_t) __b); ++ return __a >= __b ? -1ll : 0ll; + } -- BUILTIN_VSDQ_I_DI (BINOP, sshl_n) -- BUILTIN_VSDQ_I_DI (BINOP, ushl_n) -+ BUILTIN_VSDQ_I_DI (BINOP, ashl, 3) - /* Implemented by aarch64_shl. */ -- BUILTIN_VSDQ_I_DI (BINOP, sshl) -- BUILTIN_VSDQ_I_DI (BINOP, ushl) -- BUILTIN_VSDQ_I_DI (BINOP, srshl) -- BUILTIN_VSDQ_I_DI (BINOP, urshl) -+ BUILTIN_VSDQ_I_DI (BINOP, sshl, 0) -+ BUILTIN_VSDQ_I_DI (BINOP, ushl, 0) -+ BUILTIN_VSDQ_I_DI (BINOP, srshl, 0) -+ BUILTIN_VSDQ_I_DI (BINOP, urshl, 0) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgeq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return (uint32x4_t) __builtin_aarch64_cmgev4sf (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgeq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return (uint64x2_t) __builtin_aarch64_cmgev2df (__a, __b); ++} ++ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgeq_p8 (poly8x16_t __a, poly8x16_t __b) ++{ ++ return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcgeq_s8 (int8x16_t __a, int8x16_t __b) + { + return (uint8x16_t) __builtin_aarch64_cmgev16qi (__a, __b); +@@ -19603,53 +18122,270 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcgeq_u8 (uint8x16_t __a, uint8x16_t __b) + { +- return (uint8x16_t) __builtin_aarch64_cmhsv16qi ((int8x16_t) __a, ++ return (uint8x16_t) __builtin_aarch64_cmgeuv16qi ((int8x16_t) __a, + (int8x16_t) __b); + } -- BUILTIN_VSDQ_I_DI (SHIFTIMM, sshr_n) -- BUILTIN_VSDQ_I_DI (SHIFTIMM, ushr_n) -+ BUILTIN_VSDQ_I_DI (SHIFTIMM, ashr, 3) -+ BUILTIN_VSDQ_I_DI (SHIFTIMM, lshr, 3) - /* Implemented by aarch64_shr_n. */ -- BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n) -- BUILTIN_VSDQ_I_DI (SHIFTIMM, urshr_n) -+ BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n, 0) -+ BUILTIN_VSDQ_I_DI (SHIFTIMM, urshr_n, 0) - /* Implemented by aarch64_sra_n. */ -- BUILTIN_VSDQ_I_DI (SHIFTACC, ssra_n) -- BUILTIN_VSDQ_I_DI (SHIFTACC, usra_n) -- BUILTIN_VSDQ_I_DI (SHIFTACC, srsra_n) -- BUILTIN_VSDQ_I_DI (SHIFTACC, ursra_n) -+ BUILTIN_VSDQ_I_DI (SHIFTACC, ssra_n, 0) -+ BUILTIN_VSDQ_I_DI (SHIFTACC, usra_n, 0) -+ BUILTIN_VSDQ_I_DI (SHIFTACC, srsra_n, 0) -+ BUILTIN_VSDQ_I_DI (SHIFTACC, ursra_n, 0) - /* Implemented by aarch64_shll_n. */ -- BUILTIN_VDW (SHIFTIMM, sshll_n) -- BUILTIN_VDW (SHIFTIMM, ushll_n) -+ BUILTIN_VDW (SHIFTIMM, sshll_n, 0) -+ BUILTIN_VDW (SHIFTIMM, ushll_n, 0) - /* Implemented by aarch64_shll2_n. */ -- BUILTIN_VQW (SHIFTIMM, sshll2_n) -- BUILTIN_VQW (SHIFTIMM, ushll2_n) -+ BUILTIN_VQW (SHIFTIMM, sshll2_n, 0) -+ BUILTIN_VQW (SHIFTIMM, ushll2_n, 0) - /* Implemented by aarch64_qshrn_n. */ -- BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrun_n) -- BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrun_n) -- BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrn_n) -- BUILTIN_VSQN_HSDI (SHIFTIMM, uqshrn_n) -- BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrn_n) -- BUILTIN_VSQN_HSDI (SHIFTIMM, uqrshrn_n) -+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrun_n, 0) -+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrun_n, 0) -+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrn_n, 0) -+ BUILTIN_VSQN_HSDI (SHIFTIMM, uqshrn_n, 0) -+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrn_n, 0) -+ BUILTIN_VSQN_HSDI (SHIFTIMM, uqrshrn_n, 0) - /* Implemented by aarch64_si_n. */ -- BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssri_n) -- BUILTIN_VSDQ_I_DI (SHIFTINSERT, usri_n) -- BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssli_n) -- BUILTIN_VSDQ_I_DI (SHIFTINSERT, usli_n) -+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssri_n, 0) -+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, usri_n, 0) -+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssli_n, 0) -+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, usli_n, 0) - /* Implemented by aarch64_qshl_n. */ -- BUILTIN_VSDQ_I (SHIFTIMM, sqshlu_n) -- BUILTIN_VSDQ_I (SHIFTIMM, sqshl_n) -- BUILTIN_VSDQ_I (SHIFTIMM, uqshl_n) -+ BUILTIN_VSDQ_I (SHIFTIMM, sqshlu_n, 0) -+ BUILTIN_VSDQ_I (SHIFTIMM, sqshl_n, 0) -+ BUILTIN_VSDQ_I (SHIFTIMM, uqshl_n, 0) + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vcgeq_u16 (uint16x8_t __a, uint16x8_t __b) + { +- return (uint16x8_t) __builtin_aarch64_cmhsv8hi ((int16x8_t) __a, ++ return (uint16x8_t) __builtin_aarch64_cmgeuv8hi ((int16x8_t) __a, + (int16x8_t) __b); + } - /* Implemented by aarch64_cm. */ -- BUILTIN_VSDQ_I_DI (BINOP, cmeq) -- BUILTIN_VSDQ_I_DI (BINOP, cmge) -- BUILTIN_VSDQ_I_DI (BINOP, cmgt) -- BUILTIN_VSDQ_I_DI (BINOP, cmle) -- BUILTIN_VSDQ_I_DI (BINOP, cmlt) -+ BUILTIN_VALLDI (BINOP, cmeq, 0) -+ BUILTIN_VALLDI (BINOP, cmge, 0) -+ BUILTIN_VALLDI (BINOP, cmgt, 0) -+ BUILTIN_VALLDI (BINOP, cmle, 0) -+ BUILTIN_VALLDI (BINOP, cmlt, 0) - /* Implemented by aarch64_cm. */ -- BUILTIN_VSDQ_I_DI (BINOP, cmgeu) -- BUILTIN_VSDQ_I_DI (BINOP, cmgtu) -- BUILTIN_VSDQ_I_DI (BINOP, cmtst) -+ BUILTIN_VSDQ_I_DI (BINOP, cmgeu, 0) -+ BUILTIN_VSDQ_I_DI (BINOP, cmgtu, 0) -+ BUILTIN_VSDQ_I_DI (BINOP, cmtst, 0) + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vcgeq_u32 (uint32x4_t __a, uint32x4_t __b) + { +- return (uint32x4_t) __builtin_aarch64_cmhsv4si ((int32x4_t) __a, ++ return (uint32x4_t) __builtin_aarch64_cmgeuv4si ((int32x4_t) __a, + (int32x4_t) __b); + } -- /* Implemented by aarch64_. */ -- BUILTIN_VDQF (BINOP, fmax) -- BUILTIN_VDQF (BINOP, fmin) -- /* Implemented by aarch64_. */ -- BUILTIN_VDQ_BHSI (BINOP, smax) -- BUILTIN_VDQ_BHSI (BINOP, smin) -- BUILTIN_VDQ_BHSI (BINOP, umax) -- BUILTIN_VDQ_BHSI (BINOP, umin) -+ /* Implemented by reduc_plus_. */ -+ BUILTIN_VALL (UNOP, reduc_splus_, 10) -+ BUILTIN_VDQ (UNOP, reduc_uplus_, 10) + __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) + vcgeq_u64 (uint64x2_t __a, uint64x2_t __b) + { +- return (uint64x2_t) __builtin_aarch64_cmhsv2di ((int64x2_t) __a, ++ return (uint64x2_t) __builtin_aarch64_cmgeuv2di ((int64x2_t) __a, + (int64x2_t) __b); + } -- /* Implemented by aarch64_frint. */ -- BUILTIN_VDQF (UNOP, frintz) -- BUILTIN_VDQF (UNOP, frintp) -- BUILTIN_VDQF (UNOP, frintm) -- BUILTIN_VDQF (UNOP, frinti) -- BUILTIN_VDQF (UNOP, frintx) -- BUILTIN_VDQF (UNOP, frinta) -+ /* Implemented by reduc__. */ -+ BUILTIN_VDQIF (UNOP, reduc_smax_, 10) -+ BUILTIN_VDQIF (UNOP, reduc_smin_, 10) -+ BUILTIN_VDQ_BHSI (UNOP, reduc_umax_, 10) -+ BUILTIN_VDQ_BHSI (UNOP, reduc_umin_, 10) -+ BUILTIN_VDQF (UNOP, reduc_smax_nan_, 10) -+ BUILTIN_VDQF (UNOP, reduc_smin_nan_, 10) ++/* vcge - scalar. */ ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcges_f32 (float32_t __a, float32_t __b) ++{ ++ return __a >= __b ? -1 : 0; ++} ++ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcged_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmgedi (__a, __b); ++ return __a >= __b ? -1ll : 0ll; + } -- /* Implemented by aarch64_fcvt. */ -- BUILTIN_VDQF (UNOP, fcvtzs) -- BUILTIN_VDQF (UNOP, fcvtzu) -- BUILTIN_VDQF (UNOP, fcvtas) -- BUILTIN_VDQF (UNOP, fcvtau) -- BUILTIN_VDQF (UNOP, fcvtps) -- BUILTIN_VDQF (UNOP, fcvtpu) -- BUILTIN_VDQF (UNOP, fcvtms) -- BUILTIN_VDQF (UNOP, fcvtmu) -+ /* Implemented by 3. -+ smax variants map to fmaxnm, -+ smax_nan variants map to fmax. */ -+ BUILTIN_VDQIF (BINOP, smax, 3) -+ BUILTIN_VDQIF (BINOP, smin, 3) -+ BUILTIN_VDQ_BHSI (BINOP, umax, 3) -+ BUILTIN_VDQ_BHSI (BINOP, umin, 3) -+ BUILTIN_VDQF (BINOP, smax_nan, 3) -+ BUILTIN_VDQF (BINOP, smin_nan, 3) + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcged_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmhsdi ((int64x1_t) __a, +- (int64x1_t) __b); ++ return __a >= __b ? -1ll : 0ll; + } -+ /* Implemented by 2. */ -+ BUILTIN_VDQF (UNOP, btrunc, 2) -+ BUILTIN_VDQF (UNOP, ceil, 2) -+ BUILTIN_VDQF (UNOP, floor, 2) -+ BUILTIN_VDQF (UNOP, nearbyint, 2) -+ BUILTIN_VDQF (UNOP, rint, 2) -+ BUILTIN_VDQF (UNOP, round, 2) -+ BUILTIN_VDQF (UNOP, frintn, 2) ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcged_f64 (float64_t __a, float64_t __b) ++{ ++ return __a >= __b ? -1ll : 0ll; ++} + -+ /* Implemented by l2. */ -+ VAR1 (UNOP, lbtruncv2sf, 2, v2si) -+ VAR1 (UNOP, lbtruncv4sf, 2, v4si) -+ VAR1 (UNOP, lbtruncv2df, 2, v2di) ++/* vcgez - vector. */ + -+ VAR1 (UNOP, lbtruncuv2sf, 2, v2si) -+ VAR1 (UNOP, lbtruncuv4sf, 2, v4si) -+ VAR1 (UNOP, lbtruncuv2df, 2, v2di) ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcgez_f32 (float32x2_t __a) ++{ ++ float32x2_t __b = {0.0f, 0.0f}; ++ return (uint32x2_t) __builtin_aarch64_cmgev2sf (__a, __b); ++} + -+ VAR1 (UNOP, lroundv2sf, 2, v2si) -+ VAR1 (UNOP, lroundv4sf, 2, v4si) -+ VAR1 (UNOP, lroundv2df, 2, v2di) -+ /* Implemented by l2. */ -+ VAR1 (UNOP, lroundsf, 2, si) -+ VAR1 (UNOP, lrounddf, 2, di) + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgez_f64 (float64x1_t __a) ++{ ++ return __a >= 0.0 ? -1ll : 0ll; ++} + -+ VAR1 (UNOP, lrounduv2sf, 2, v2si) -+ VAR1 (UNOP, lrounduv4sf, 2, v4si) -+ VAR1 (UNOP, lrounduv2df, 2, v2di) -+ VAR1 (UNOP, lroundusf, 2, si) -+ VAR1 (UNOP, lroundudf, 2, di) ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcgez_p8 (poly8x8_t __a) ++{ ++ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+ VAR1 (UNOP, lceilv2sf, 2, v2si) -+ VAR1 (UNOP, lceilv4sf, 2, v4si) -+ VAR1 (UNOP, lceilv2df, 2, v2di) ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcgez_s8 (int8x8_t __a) ++{ ++ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmgev8qi (__a, __b); ++} + -+ VAR1 (UNOP, lceiluv2sf, 2, v2si) -+ VAR1 (UNOP, lceiluv4sf, 2, v4si) -+ VAR1 (UNOP, lceiluv2df, 2, v2di) -+ VAR1 (UNOP, lceilusf, 2, si) -+ VAR1 (UNOP, lceiludf, 2, di) ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vcgez_s16 (int16x4_t __a) ++{ ++ int16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmgev4hi (__a, __b); ++} + -+ VAR1 (UNOP, lfloorv2sf, 2, v2si) -+ VAR1 (UNOP, lfloorv4sf, 2, v4si) -+ VAR1 (UNOP, lfloorv2df, 2, v2di) ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcgez_s32 (int32x2_t __a) ++{ ++ int32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmgev2si (__a, __b); ++} + -+ VAR1 (UNOP, lflooruv2sf, 2, v2si) -+ VAR1 (UNOP, lflooruv4sf, 2, v4si) -+ VAR1 (UNOP, lflooruv2df, 2, v2di) -+ VAR1 (UNOP, lfloorusf, 2, si) -+ VAR1 (UNOP, lfloorudf, 2, di) ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgez_s64 (int64x1_t __a) ++{ ++ return __a >= 0ll ? -1ll : 0ll; ++} + -+ VAR1 (UNOP, lfrintnv2sf, 2, v2si) -+ VAR1 (UNOP, lfrintnv4sf, 2, v4si) -+ VAR1 (UNOP, lfrintnv2df, 2, v2di) -+ VAR1 (UNOP, lfrintnsf, 2, si) -+ VAR1 (UNOP, lfrintndf, 2, di) ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcgez_u8 (uint8x8_t __a) ++{ ++ uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmgeuv8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+ VAR1 (UNOP, lfrintnuv2sf, 2, v2si) -+ VAR1 (UNOP, lfrintnuv4sf, 2, v4si) -+ VAR1 (UNOP, lfrintnuv2df, 2, v2di) -+ VAR1 (UNOP, lfrintnusf, 2, si) -+ VAR1 (UNOP, lfrintnudf, 2, di) ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vcgez_u16 (uint16x4_t __a) ++{ ++ uint16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmgeuv4hi ((int16x4_t) __a, ++ (int16x4_t) __b); ++} + -+ /* Implemented by 2. */ -+ VAR1 (UNOP, floatv2si, 2, v2sf) -+ VAR1 (UNOP, floatv4si, 2, v4sf) -+ VAR1 (UNOP, floatv2di, 2, v2df) ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcgez_u32 (uint32x2_t __a) ++{ ++ uint32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmgeuv2si ((int32x2_t) __a, ++ (int32x2_t) __b); ++} + -+ VAR1 (UNOP, floatunsv2si, 2, v2sf) -+ VAR1 (UNOP, floatunsv4si, 2, v4sf) -+ VAR1 (UNOP, floatunsv2di, 2, v2df) ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgez_u64 (uint64x1_t __a) ++{ ++ return __a >= 0ll ? -1ll : 0ll; ++} + - /* Implemented by - aarch64_. */ -- BUILTIN_VALL (BINOP, zip1) -- BUILTIN_VALL (BINOP, zip2) -- BUILTIN_VALL (BINOP, uzp1) -- BUILTIN_VALL (BINOP, uzp2) -- BUILTIN_VALL (BINOP, trn1) -- BUILTIN_VALL (BINOP, trn2) -+ BUILTIN_VALL (BINOP, zip1, 0) -+ BUILTIN_VALL (BINOP, zip2, 0) -+ BUILTIN_VALL (BINOP, uzp1, 0) -+ BUILTIN_VALL (BINOP, uzp2, 0) -+ BUILTIN_VALL (BINOP, trn1, 0) -+ BUILTIN_VALL (BINOP, trn2, 0) - -+ /* Implemented by -+ aarch64_frecp. */ -+ BUILTIN_GPF (UNOP, frecpe, 0) -+ BUILTIN_GPF (BINOP, frecps, 0) -+ BUILTIN_GPF (UNOP, frecpx, 0) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgezq_f32 (float32x4_t __a) ++{ ++ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; ++ return (uint32x4_t) __builtin_aarch64_cmgev4sf (__a, __b); ++} + -+ BUILTIN_VDQF (UNOP, frecpe, 0) -+ BUILTIN_VDQF (BINOP, frecps, 0) ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgezq_f64 (float64x2_t __a) ++{ ++ float64x2_t __b = {0.0, 0.0}; ++ return (uint64x2_t) __builtin_aarch64_cmgev2df (__a, __b); ++} + -+ BUILTIN_VALLDI (UNOP, abs, 2) ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgezq_p8 (poly8x16_t __a) ++{ ++ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} + -+ VAR1 (UNOP, vec_unpacks_hi_, 10, v4sf) -+ VAR1 (BINOP, float_truncate_hi_, 0, v4sf) ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgezq_s8 (int8x16_t __a) ++{ ++ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmgev16qi (__a, __b); ++} + -+ VAR1 (UNOP, float_extend_lo_, 0, v2df) -+ VAR1 (UNOP, float_truncate_lo_, 0, v2sf) ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vcgezq_s16 (int16x8_t __a) ++{ ++ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmgev8hi (__a, __b); ++} + - /* Implemented by aarch64_ld1. */ -- BUILTIN_VALL (LOAD1, ld1) -+ BUILTIN_VALL (LOAD1, ld1, 0) - - /* Implemented by aarch64_st1. */ -- BUILTIN_VALL (STORE1, st1) -+ BUILTIN_VALL (STORE1, st1, 0) - -+ /* Implemented by aarch64_crypto_aes. */ -+ VAR1 (BINOPU, crypto_aese, 0, v16qi) -+ VAR1 (BINOPU, crypto_aesd, 0, v16qi) -+ VAR1 (UNOPU, crypto_aesmc, 0, v16qi) -+ VAR1 (UNOPU, crypto_aesimc, 0, v16qi) -+ -+ /* Implemented by aarch64_crypto_sha1. */ -+ VAR1 (UNOPU, crypto_sha1h, 0, si) -+ VAR1 (BINOPU, crypto_sha1su1, 0, v4si) -+ VAR1 (TERNOPU, crypto_sha1c, 0, v4si) -+ VAR1 (TERNOPU, crypto_sha1m, 0, v4si) -+ VAR1 (TERNOPU, crypto_sha1p, 0, v4si) -+ VAR1 (TERNOPU, crypto_sha1su0, 0, v4si) -+ -+ /* Implemented by aarch64_crypto_sha256. */ -+ VAR1 (TERNOPU, crypto_sha256h, 0, v4si) -+ VAR1 (TERNOPU, crypto_sha256h2, 0, v4si) -+ VAR1 (BINOPU, crypto_sha256su0, 0, v4si) -+ VAR1 (TERNOPU, crypto_sha256su1, 0, v4si) -+ -+ /* Implemented by aarch64_crypto_pmull. */ -+ VAR1 (BINOPP, crypto_pmull, 0, di) -+ VAR1 (BINOPP, crypto_pmull, 0, v2di) ---- a/src/gcc/config/aarch64/constraints.md -+++ b/src/gcc/config/aarch64/constraints.md -@@ -75,11 +75,6 @@ - "Integer constant zero." - (match_test "op == const0_rtx")) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgezq_s32 (int32x4_t __a) ++{ ++ int32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmgev4si (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgezq_s64 (int64x2_t __a) ++{ ++ int64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmgev2di (__a, __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgezq_u8 (uint8x16_t __a) ++{ ++ uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmgeuv16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} ++ ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vcgezq_u16 (uint16x8_t __a) ++{ ++ uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmgeuv8hi ((int16x8_t) __a, ++ (int16x8_t) __b); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgezq_u32 (uint32x4_t __a) ++{ ++ uint32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmgeuv4si ((int32x4_t) __a, ++ (int32x4_t) __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgezq_u64 (uint64x2_t __a) ++{ ++ uint64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmgeuv2di ((int64x2_t) __a, ++ (int64x2_t) __b); ++} ++ ++/* vcgez - scalar. */ ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcgezs_f32 (float32_t __a) ++{ ++ return __a >= 0.0f ? -1 : 0; ++} ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcgezd_s64 (int64x1_t __a) + { +- return (uint64x1_t) __builtin_aarch64_cmgedi (__a, 0); ++ return __a >= 0 ? -1ll : 0ll; + } --(define_constraint "Usa" -- "A constraint that matches an absolute symbolic address." -- (and (match_code "const,symbol_ref") -- (match_test "aarch64_symbolic_address_p (op)"))) -- - (define_constraint "Ush" - "A constraint that matches an absolute symbolic address high part." - (and (match_code "high") -@@ -148,10 +143,25 @@ - "@internal - A constraint that matches vector of immediates." - (and (match_code "const_vector") -- (match_test "aarch64_simd_immediate_valid_for_move (op, GET_MODE (op), -- NULL, NULL, NULL, -- NULL, NULL) != 0"))) -+ (match_test "aarch64_simd_valid_immediate (op, GET_MODE (op), -+ false, NULL)"))) +-/* vcgt */ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgezd_u64 (int64x1_t __a) ++{ ++ return __a >= 0 ? -1ll : 0ll; ++} -+(define_constraint "Dh" -+ "@internal -+ A constraint that matches an immediate operand valid for\ -+ AdvSIMD scalar move in HImode." -+ (and (match_code "const_int") -+ (match_test "aarch64_simd_scalar_immediate_valid_for_move (op, -+ HImode)"))) ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcgezd_f64 (float64_t __a) ++{ ++ return __a >= 0.0 ? -1ll : 0ll; ++} + -+(define_constraint "Dq" -+ "@internal -+ A constraint that matches an immediate operand valid for\ -+ AdvSIMD scalar move in QImode." -+ (and (match_code "const_int") -+ (match_test "aarch64_simd_scalar_immediate_valid_for_move (op, -+ QImode)"))) ++/* vcgt - vector. */ + - (define_constraint "Dl" - "@internal - A constraint that matches vector of immediates for left shifts." ---- a/src/gcc/config/aarch64/aarch64.c -+++ b/src/gcc/config/aarch64/aarch64.c -@@ -45,6 +45,8 @@ - #include "gimple.h" - #include "optabs.h" - #include "dwarf2.h" -+#include "cfgloop.h" -+#include "tree-vectorizer.h" ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcgt_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return (uint32x2_t) __builtin_aarch64_cmgtv2sf (__a, __b); ++} ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgt_f64 (float64x1_t __a, float64x1_t __b) ++{ ++ return __a > __b ? -1ll : 0ll; ++} ++ + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcgt_p8 (poly8x8_t __a, poly8x8_t __b) ++{ ++ return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} ++ ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vcgt_s8 (int8x8_t __a, int8x8_t __b) + { + return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__a, __b); +@@ -19670,38 +18406,56 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcgt_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmgtdi (__a, __b); ++ return __a > __b ? -1ll : 0ll; + } - /* Classifies an address. + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vcgt_u8 (uint8x8_t __a, uint8x8_t __b) + { +- return (uint8x8_t) __builtin_aarch64_cmhiv8qi ((int8x8_t) __a, ++ return (uint8x8_t) __builtin_aarch64_cmgtuv8qi ((int8x8_t) __a, + (int8x8_t) __b); + } -@@ -87,6 +89,15 @@ - enum aarch64_symbol_type symbol_type; - }; + __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) + vcgt_u16 (uint16x4_t __a, uint16x4_t __b) + { +- return (uint16x4_t) __builtin_aarch64_cmhiv4hi ((int16x4_t) __a, ++ return (uint16x4_t) __builtin_aarch64_cmgtuv4hi ((int16x4_t) __a, + (int16x4_t) __b); + } -+struct simd_immediate_info -+{ -+ rtx value; -+ int shift; -+ int element_width; -+ bool mvn; -+ bool msl; -+}; -+ - /* The current code model. */ - enum aarch64_code_model aarch64_cmodel; + __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) + vcgt_u32 (uint32x2_t __a, uint32x2_t __b) + { +- return (uint32x2_t) __builtin_aarch64_cmhiv2si ((int32x2_t) __a, ++ return (uint32x2_t) __builtin_aarch64_cmgtuv2si ((int32x2_t) __a, + (int32x2_t) __b); + } -@@ -103,8 +114,6 @@ - static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED; - static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED; - static void aarch64_override_options_after_change (void); --static int aarch64_simd_valid_immediate (rtx, enum machine_mode, int, rtx *, -- int *, unsigned char *, int *, int *); - static bool aarch64_vector_mode_supported_p (enum machine_mode); - static unsigned bit_count (unsigned HOST_WIDE_INT); - static bool aarch64_const_vec_all_same_int_p (rtx, -@@ -178,14 +187,35 @@ - NAMED_PARAM (FP2FP, 4) - }; + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcgt_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmhidi ((int64x1_t) __a, +- (int64x1_t) __b); ++ return __a > __b ? -1ll : 0ll; + } -+/* Generic costs for vector insn classes. */ - #if HAVE_DESIGNATED_INITIALIZERS && GCC_VERSION >= 2007 - __extension__ - #endif -+static const struct cpu_vector_cost generic_vector_cost = ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgtq_f32 (float32x4_t __a, float32x4_t __b) +{ -+ NAMED_PARAM (scalar_stmt_cost, 1), -+ NAMED_PARAM (scalar_load_cost, 1), -+ NAMED_PARAM (scalar_store_cost, 1), -+ NAMED_PARAM (vec_stmt_cost, 1), -+ NAMED_PARAM (vec_to_scalar_cost, 1), -+ NAMED_PARAM (scalar_to_vec_cost, 1), -+ NAMED_PARAM (vec_align_load_cost, 1), -+ NAMED_PARAM (vec_unalign_load_cost, 1), -+ NAMED_PARAM (vec_unalign_store_cost, 1), -+ NAMED_PARAM (vec_store_cost, 1), -+ NAMED_PARAM (cond_taken_branch_cost, 3), -+ NAMED_PARAM (cond_not_taken_branch_cost, 1) -+}; ++ return (uint32x4_t) __builtin_aarch64_cmgtv4sf (__a, __b); ++} + -+#if HAVE_DESIGNATED_INITIALIZERS && GCC_VERSION >= 2007 -+__extension__ -+#endif - static const struct tune_params generic_tunings = - { - &generic_rtx_cost_table, - &generic_addrcost_table, - &generic_regmove_cost, -+ &generic_vector_cost, - NAMED_PARAM (memmov_cost, 4) - }; - -@@ -524,13 +554,15 @@ - return; - } - -+ case SYMBOL_TINY_ABSOLUTE: -+ emit_insn (gen_rtx_SET (Pmode, dest, imm)); -+ return; ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgtq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return (uint64x2_t) __builtin_aarch64_cmgtv2df (__a, __b); ++} + - case SYMBOL_SMALL_GOT: - { - rtx tmp_reg = dest; - if (can_create_pseudo_p ()) -- { -- tmp_reg = gen_reg_rtx (Pmode); -- } -+ tmp_reg = gen_reg_rtx (Pmode); - emit_move_insn (tmp_reg, gen_rtx_HIGH (Pmode, imm)); - emit_insn (gen_ldr_got_small (dest, tmp_reg, imm)); - return; -@@ -581,6 +613,10 @@ - return; - } - -+ case SYMBOL_TINY_GOT: -+ emit_insn (gen_ldr_got_tiny (dest, imm)); -+ return; + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgtq_p8 (poly8x16_t __a, poly8x16_t __b) ++{ ++ return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} + - default: - gcc_unreachable (); - } -@@ -604,49 +640,85 @@ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcgtq_s8 (int8x16_t __a, int8x16_t __b) { - rtx low_dst; + return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__a, __b); +@@ -19728,53 +18482,270 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcgtq_u8 (uint8x16_t __a, uint8x16_t __b) + { +- return (uint8x16_t) __builtin_aarch64_cmhiv16qi ((int8x16_t) __a, ++ return (uint8x16_t) __builtin_aarch64_cmgtuv16qi ((int8x16_t) __a, + (int8x16_t) __b); + } -- gcc_assert (GET_MODE (dst) == TImode); -+ enum machine_mode src_mode = GET_MODE (src); -+ enum machine_mode dst_mode = GET_MODE (dst); -+ int src_regno = REGNO (src); -+ int dst_regno = REGNO (dst); + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vcgtq_u16 (uint16x8_t __a, uint16x8_t __b) + { +- return (uint16x8_t) __builtin_aarch64_cmhiv8hi ((int16x8_t) __a, ++ return (uint16x8_t) __builtin_aarch64_cmgtuv8hi ((int16x8_t) __a, + (int16x8_t) __b); + } -+ gcc_assert (dst_mode == TImode || dst_mode == TFmode); -+ - if (REG_P (dst) && REG_P (src)) - { -- int src_regno = REGNO (src); -- int dst_regno = REGNO (dst); -+ gcc_assert (src_mode == TImode || src_mode == TFmode); + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vcgtq_u32 (uint32x4_t __a, uint32x4_t __b) + { +- return (uint32x4_t) __builtin_aarch64_cmhiv4si ((int32x4_t) __a, ++ return (uint32x4_t) __builtin_aarch64_cmgtuv4si ((int32x4_t) __a, + (int32x4_t) __b); + } -- gcc_assert (GET_MODE (src) == TImode); -- - /* Handle r -> w, w -> r. */ - if (FP_REGNUM_P (dst_regno) && GP_REGNUM_P (src_regno)) - { -- emit_insn (gen_aarch64_movtilow_di (dst, -- gen_lowpart (word_mode, src))); -- emit_insn (gen_aarch64_movtihigh_di (dst, -- gen_highpart (word_mode, src))); -- return; -+ switch (src_mode) { -+ case TImode: -+ emit_insn -+ (gen_aarch64_movtilow_di (dst, gen_lowpart (word_mode, src))); -+ emit_insn -+ (gen_aarch64_movtihigh_di (dst, gen_highpart (word_mode, src))); -+ return; -+ case TFmode: -+ emit_insn -+ (gen_aarch64_movtflow_di (dst, gen_lowpart (word_mode, src))); -+ emit_insn -+ (gen_aarch64_movtfhigh_di (dst, gen_highpart (word_mode, src))); -+ return; -+ default: -+ gcc_unreachable (); -+ } - } - else if (GP_REGNUM_P (dst_regno) && FP_REGNUM_P (src_regno)) - { -- emit_insn (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst), -- src)); -- emit_insn (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst), -- src)); -- return; -+ switch (src_mode) { -+ case TImode: -+ emit_insn -+ (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst), src)); -+ emit_insn -+ (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst), src)); -+ return; -+ case TFmode: -+ emit_insn -+ (gen_aarch64_movdi_tflow (gen_lowpart (word_mode, dst), src)); -+ emit_insn -+ (gen_aarch64_movdi_tfhigh (gen_highpart (word_mode, dst), src)); -+ return; -+ default: -+ gcc_unreachable (); -+ } - } - /* Fall through to r -> r cases. */ - } + __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) + vcgtq_u64 (uint64x2_t __a, uint64x2_t __b) + { +- return (uint64x2_t) __builtin_aarch64_cmhiv2di ((int64x2_t) __a, ++ return (uint64x2_t) __builtin_aarch64_cmgtuv2di ((int64x2_t) __a, + (int64x2_t) __b); + } -- low_dst = gen_lowpart (word_mode, dst); -- if (REG_P (low_dst) -- && reg_overlap_mentioned_p (low_dst, src)) -- { -- aarch64_emit_move (gen_highpart (word_mode, dst), -- gen_highpart_mode (word_mode, TImode, src)); -- aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); -- } -- else -- { -- aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); -- aarch64_emit_move (gen_highpart (word_mode, dst), -- gen_highpart_mode (word_mode, TImode, src)); -- } -+ switch (dst_mode) { -+ case TImode: -+ low_dst = gen_lowpart (word_mode, dst); -+ if (REG_P (low_dst) -+ && reg_overlap_mentioned_p (low_dst, src)) -+ { -+ aarch64_emit_move (gen_highpart (word_mode, dst), -+ gen_highpart_mode (word_mode, TImode, src)); -+ aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); -+ } -+ else -+ { -+ aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); -+ aarch64_emit_move (gen_highpart (word_mode, dst), -+ gen_highpart_mode (word_mode, TImode, src)); -+ } -+ return; -+ case TFmode: -+ emit_move_insn (gen_rtx_REG (DFmode, dst_regno), -+ gen_rtx_REG (DFmode, src_regno)); -+ emit_move_insn (gen_rtx_REG (DFmode, dst_regno + 1), -+ gen_rtx_REG (DFmode, src_regno + 1)); -+ return; -+ default: -+ gcc_unreachable (); -+ } ++/* vcgt - scalar. */ ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcgts_f32 (float32_t __a, float32_t __b) ++{ ++ return __a > __b ? -1 : 0; ++} ++ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcgtd_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmgtdi (__a, __b); ++ return __a > __b ? -1ll : 0ll; } - bool -@@ -656,11 +728,99 @@ - || ! (FP_REGNUM_P (REGNO (dst)) && FP_REGNUM_P (REGNO (src)))); + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcgtd_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmhidi ((int64x1_t) __a, +- (int64x1_t) __b); ++ return __a > __b ? -1ll : 0ll; } -+/* Split a complex SIMD combine. */ ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcgtd_f64 (float64_t __a, float64_t __b) ++{ ++ return __a > __b ? -1ll : 0ll; ++} + -+void -+aarch64_split_simd_combine (rtx dst, rtx src1, rtx src2) ++/* vcgtz - vector. */ ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcgtz_f32 (float32x2_t __a) +{ -+ enum machine_mode src_mode = GET_MODE (src1); -+ enum machine_mode dst_mode = GET_MODE (dst); ++ float32x2_t __b = {0.0f, 0.0f}; ++ return (uint32x2_t) __builtin_aarch64_cmgtv2sf (__a, __b); ++} + -+ gcc_assert (VECTOR_MODE_P (dst_mode)); + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgtz_f64 (float64x1_t __a) ++{ ++ return __a > 0.0 ? -1ll : 0ll; ++} + -+ if (REG_P (dst) && REG_P (src1) && REG_P (src2)) -+ { -+ rtx (*gen) (rtx, rtx, rtx); ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcgtz_p8 (poly8x8_t __a) ++{ ++ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+ switch (src_mode) -+ { -+ case V8QImode: -+ gen = gen_aarch64_simd_combinev8qi; -+ break; -+ case V4HImode: -+ gen = gen_aarch64_simd_combinev4hi; -+ break; -+ case V2SImode: -+ gen = gen_aarch64_simd_combinev2si; -+ break; -+ case V2SFmode: -+ gen = gen_aarch64_simd_combinev2sf; -+ break; -+ case DImode: -+ gen = gen_aarch64_simd_combinedi; -+ break; -+ case DFmode: -+ gen = gen_aarch64_simd_combinedf; -+ break; -+ default: -+ gcc_unreachable (); -+ } ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcgtz_s8 (int8x8_t __a) ++{ ++ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__a, __b); ++} + -+ emit_insn (gen (dst, src1, src2)); -+ return; -+ } ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vcgtz_s16 (int16x4_t __a) ++{ ++ int16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmgtv4hi (__a, __b); +} + -+/* Split a complex SIMD move. */ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcgtz_s32 (int32x2_t __a) ++{ ++ int32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmgtv2si (__a, __b); ++} + -+void -+aarch64_split_simd_move (rtx dst, rtx src) ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgtz_s64 (int64x1_t __a) +{ -+ enum machine_mode src_mode = GET_MODE (src); -+ enum machine_mode dst_mode = GET_MODE (dst); ++ return __a > 0ll ? -1ll : 0ll; ++} + -+ gcc_assert (VECTOR_MODE_P (dst_mode)); ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcgtz_u8 (uint8x8_t __a) ++{ ++ uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmgtuv8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+ if (REG_P (dst) && REG_P (src)) -+ { -+ rtx (*gen) (rtx, rtx); ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vcgtz_u16 (uint16x4_t __a) ++{ ++ uint16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmgtuv4hi ((int16x4_t) __a, ++ (int16x4_t) __b); ++} + -+ gcc_assert (VECTOR_MODE_P (src_mode)); ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcgtz_u32 (uint32x2_t __a) ++{ ++ uint32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmgtuv2si ((int32x2_t) __a, ++ (int32x2_t) __b); ++} + -+ switch (src_mode) -+ { -+ case V16QImode: -+ gen = gen_aarch64_split_simd_movv16qi; -+ break; -+ case V8HImode: -+ gen = gen_aarch64_split_simd_movv8hi; -+ break; -+ case V4SImode: -+ gen = gen_aarch64_split_simd_movv4si; -+ break; -+ case V2DImode: -+ gen = gen_aarch64_split_simd_movv2di; -+ break; -+ case V4SFmode: -+ gen = gen_aarch64_split_simd_movv4sf; -+ break; -+ case V2DFmode: -+ gen = gen_aarch64_split_simd_movv2df; -+ break; -+ default: -+ gcc_unreachable (); -+ } ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgtz_u64 (uint64x1_t __a) ++{ ++ return __a > 0ll ? -1ll : 0ll; ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgtzq_f32 (float32x4_t __a) ++{ ++ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; ++ return (uint32x4_t) __builtin_aarch64_cmgtv4sf (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgtzq_f64 (float64x2_t __a) ++{ ++ float64x2_t __b = {0.0, 0.0}; ++ return (uint64x2_t) __builtin_aarch64_cmgtv2df (__a, __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgtzq_p8 (poly8x16_t __a) ++{ ++ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgtzq_s8 (int8x16_t __a) ++{ ++ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__a, __b); ++} ++ ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vcgtzq_s16 (int16x8_t __a) ++{ ++ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmgtv8hi (__a, __b); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgtzq_s32 (int32x4_t __a) ++{ ++ int32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmgtv4si (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgtzq_s64 (int64x2_t __a) ++{ ++ int64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmgtv2di (__a, __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcgtzq_u8 (uint8x16_t __a) ++{ ++ uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmgtuv16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} ++ ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vcgtzq_u16 (uint16x8_t __a) ++{ ++ uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmgtuv8hi ((int16x8_t) __a, ++ (int16x8_t) __b); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcgtzq_u32 (uint32x4_t __a) ++{ ++ uint32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmgtuv4si ((int32x4_t) __a, ++ (int32x4_t) __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcgtzq_u64 (uint64x2_t __a) ++{ ++ uint64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmgtuv2di ((int64x2_t) __a, ++ (int64x2_t) __b); ++} ++ ++/* vcgtz - scalar. */ ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcgtzs_f32 (float32_t __a) ++{ ++ return __a > 0.0f ? -1 : 0; ++} ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcgtzd_s64 (int64x1_t __a) + { +- return (uint64x1_t) __builtin_aarch64_cmgtdi (__a, 0); ++ return __a > 0 ? -1ll : 0ll; + } + +-/* vcle */ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcgtzd_u64 (int64x1_t __a) ++{ ++ return __a > 0 ? -1ll : 0ll; ++} + ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcgtzd_f64 (float64_t __a) ++{ ++ return __a > 0.0 ? -1ll : 0ll; ++} + -+ emit_insn (gen (dst, src)); -+ return; -+ } ++/* vcle - vector. */ ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcle_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return (uint32x2_t) __builtin_aarch64_cmgev2sf (__b, __a); +} + - static rtx --aarch64_force_temporary (rtx x, rtx value) -+aarch64_force_temporary (enum machine_mode mode, rtx x, rtx value) ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcle_f64 (float64x1_t __a, float64x1_t __b) ++{ ++ return __a <= __b ? -1ll : 0ll; ++} ++ + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcle_p8 (poly8x8_t __a, poly8x8_t __b) ++{ ++ return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __b, ++ (int8x8_t) __a); ++} ++ ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vcle_s8 (int8x8_t __a, int8x8_t __b) { - if (can_create_pseudo_p ()) -- return force_reg (Pmode, value); -+ return force_reg (mode, value); - else - { - x = aarch64_emit_move (x, value); -@@ -672,7 +832,7 @@ - static rtx - aarch64_add_offset (enum machine_mode mode, rtx temp, rtx reg, HOST_WIDE_INT offset) + return (uint8x8_t) __builtin_aarch64_cmgev8qi (__b, __a); +@@ -19795,38 +18766,56 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcle_s64 (int64x1_t __a, int64x1_t __b) { -- if (!aarch64_plus_immediate (GEN_INT (offset), DImode)) -+ if (!aarch64_plus_immediate (GEN_INT (offset), mode)) - { - rtx high; - /* Load the full offset into a register. This -@@ -679,8 +839,9 @@ - might be improvable in the future. */ - high = GEN_INT (offset); - offset = 0; -- high = aarch64_force_temporary (temp, high); -- reg = aarch64_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg)); -+ high = aarch64_force_temporary (mode, temp, high); -+ reg = aarch64_force_temporary (mode, temp, -+ gen_rtx_PLUS (mode, high, reg)); - } - return plus_constant (mode, reg, offset); +- return (uint64x1_t) __builtin_aarch64_cmgedi (__b, __a); ++ return __a <= __b ? -1ll : 0ll; } -@@ -719,7 +880,7 @@ - && targetm.cannot_force_const_mem (mode, imm)) - { - gcc_assert(can_create_pseudo_p ()); -- base = aarch64_force_temporary (dest, base); -+ base = aarch64_force_temporary (mode, dest, base); - base = aarch64_add_offset (mode, NULL, base, INTVAL (offset)); - aarch64_emit_move (dest, base); - return; -@@ -733,10 +894,11 @@ - case SYMBOL_SMALL_TLSDESC: - case SYMBOL_SMALL_GOTTPREL: - case SYMBOL_SMALL_GOT: -+ case SYMBOL_TINY_GOT: - if (offset != const0_rtx) - { - gcc_assert(can_create_pseudo_p ()); -- base = aarch64_force_temporary (dest, base); -+ base = aarch64_force_temporary (mode, dest, base); - base = aarch64_add_offset (mode, NULL, base, INTVAL (offset)); - aarch64_emit_move (dest, base); - return; -@@ -745,6 +907,7 @@ - - case SYMBOL_SMALL_TPREL: - case SYMBOL_SMALL_ABSOLUTE: -+ case SYMBOL_TINY_ABSOLUTE: - aarch64_load_symref_appropriately (dest, imm, sty); - return; -@@ -1810,7 +1973,7 @@ - Establish the stack frame by decreasing the stack pointer with a - properly calculated size and, if necessary, create a frame record - filled with the values of LR and previous frame pointer. The -- current FP is also set up is it is in use. */ -+ current FP is also set up if it is in use. */ + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vcle_u8 (uint8x8_t __a, uint8x8_t __b) + { +- return (uint8x8_t) __builtin_aarch64_cmhsv8qi ((int8x8_t) __b, ++ return (uint8x8_t) __builtin_aarch64_cmgeuv8qi ((int8x8_t) __b, + (int8x8_t) __a); + } - void - aarch64_expand_prologue (void) -@@ -2553,12 +2716,14 @@ - aarch64_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) + __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) + vcle_u16 (uint16x4_t __a, uint16x4_t __b) { - rtx base, offset; -+ - if (GET_CODE (x) == HIGH) - return true; +- return (uint16x4_t) __builtin_aarch64_cmhsv4hi ((int16x4_t) __b, ++ return (uint16x4_t) __builtin_aarch64_cmgeuv4hi ((int16x4_t) __b, + (int16x4_t) __a); + } - split_const (x, &base, &offset); - if (GET_CODE (base) == SYMBOL_REF || GET_CODE (base) == LABEL_REF) -- return (aarch64_classify_symbol (base, SYMBOL_CONTEXT_ADR) != SYMBOL_FORCE_TO_MEM); -+ return (aarch64_classify_symbol (base, SYMBOL_CONTEXT_ADR) -+ != SYMBOL_FORCE_TO_MEM); + __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) + vcle_u32 (uint32x2_t __a, uint32x2_t __b) + { +- return (uint32x2_t) __builtin_aarch64_cmhsv2si ((int32x2_t) __b, ++ return (uint32x2_t) __builtin_aarch64_cmgeuv2si ((int32x2_t) __b, + (int32x2_t) __a); + } - return aarch64_tls_referenced_p (x); + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcle_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmhsdi ((int64x1_t) __b, +- (int64x1_t) __a); ++ return __a <= __b ? -1ll : 0ll; } -@@ -2996,10 +3161,13 @@ - /* Classify the base of symbolic expression X, given that X appears in - context CONTEXT. */ --static enum aarch64_symbol_type --aarch64_classify_symbolic_expression (rtx x, enum aarch64_symbol_context context) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcleq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return (uint32x4_t) __builtin_aarch64_cmgev4sf (__b, __a); ++} + -+enum aarch64_symbol_type -+aarch64_classify_symbolic_expression (rtx x, -+ enum aarch64_symbol_context context) - { - rtx offset; ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcleq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return (uint64x2_t) __builtin_aarch64_cmgev2df (__b, __a); ++} + - split_const (x, &x, &offset); - return aarch64_classify_symbol (x, context); + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcleq_p8 (poly8x16_t __a, poly8x16_t __b) ++{ ++ return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __b, ++ (int8x16_t) __a); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcleq_s8 (int8x16_t __a, int8x16_t __b) + { + return (uint8x16_t) __builtin_aarch64_cmgev16qi (__b, __a); +@@ -19853,46 +18842,213 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcleq_u8 (uint8x16_t __a, uint8x16_t __b) + { +- return (uint8x16_t) __builtin_aarch64_cmhsv16qi ((int8x16_t) __b, ++ return (uint8x16_t) __builtin_aarch64_cmgeuv16qi ((int8x16_t) __b, + (int8x16_t) __a); } -@@ -3087,10 +3255,11 @@ - if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode) - && y == const0_rtx - && (code == EQ || code == NE || code == LT || code == GE) -- && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS || GET_CODE (x) == AND)) -+ && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS || GET_CODE (x) == AND -+ || GET_CODE (x) == NEG)) - return CC_NZmode; - -- /* A compare with a shifted operand. Because of canonicalization, -+ /* A compare with a shifted or negated operand. Because of canonicalization, - the comparison will have to be swapped when we emit the assembly - code. */ - if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode) -@@ -3097,7 +3266,8 @@ - && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG) - && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT - || GET_CODE (x) == LSHIFTRT -- || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)) -+ || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND -+ || GET_CODE (x) == NEG)) - return CC_SWPmode; - - /* A compare of a mode narrower than SI mode against zero can be done -@@ -3282,26 +3452,6 @@ - asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]); - break; - -- case 'Q': -- /* Print the least significant register of a pair (TImode) of regs. */ -- if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1)) -- { -- output_operand_lossage ("invalid operand for '%%%c'", code); -- return; -- } -- asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0)]); -- break; -- -- case 'R': -- /* Print the most significant register of a pair (TImode) of regs. */ -- if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1)) -- { -- output_operand_lossage ("invalid operand for '%%%c'", code); -- return; -- } -- asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1)]); -- break; -- - case 'm': - /* Print a condition (eq, ne, etc). */ - -@@ -3349,7 +3499,7 @@ - output_operand_lossage ("incompatible floating point / vector register operand for '%%%c'", code); - return; - } -- asm_fprintf (f, "%s%c%d", REGISTER_PREFIX, code, REGNO (x) - V0_REGNUM); -+ asm_fprintf (f, "%c%d", code, REGNO (x) - V0_REGNUM); - break; - - case 'S': -@@ -3362,18 +3512,17 @@ - output_operand_lossage ("incompatible floating point / vector register operand for '%%%c'", code); - return; - } -- asm_fprintf (f, "%sv%d", REGISTER_PREFIX, -- REGNO (x) - V0_REGNUM + (code - 'S')); -+ asm_fprintf (f, "v%d", REGNO (x) - V0_REGNUM + (code - 'S')); - break; - - case 'X': -- /* Print integer constant in hex. */ -+ /* Print bottom 16 bits of integer constant in hex. */ - if (GET_CODE (x) != CONST_INT) - { - output_operand_lossage ("invalid operand for '%%%c'", code); - return; - } -- asm_fprintf (f, "0x%wx", UINTVAL (x)); -+ asm_fprintf (f, "0x%wx", UINTVAL (x) & 0xffff); - break; - - case 'w': -@@ -3383,20 +3532,19 @@ - if (x == const0_rtx - || (CONST_DOUBLE_P (x) && aarch64_float_const_zero_rtx_p (x))) - { -- asm_fprintf (f, "%s%czr", REGISTER_PREFIX, code); -+ asm_fprintf (f, "%czr", code); - break; - } - if (REG_P (x) && GP_REGNUM_P (REGNO (x))) - { -- asm_fprintf (f, "%s%c%d", REGISTER_PREFIX, code, -- REGNO (x) - R0_REGNUM); -+ asm_fprintf (f, "%c%d", code, REGNO (x) - R0_REGNUM); - break; - } + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vcleq_u16 (uint16x8_t __a, uint16x8_t __b) + { +- return (uint16x8_t) __builtin_aarch64_cmhsv8hi ((int16x8_t) __b, ++ return (uint16x8_t) __builtin_aarch64_cmgeuv8hi ((int16x8_t) __b, + (int16x8_t) __a); + } - if (REG_P (x) && REGNO (x) == SP_REGNUM) - { -- asm_fprintf (f, "%s%ssp", REGISTER_PREFIX, code == 'w' ? "w" : ""); -+ asm_fprintf (f, "%ssp", code == 'w' ? "w" : ""); - break; - } + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vcleq_u32 (uint32x4_t __a, uint32x4_t __b) + { +- return (uint32x4_t) __builtin_aarch64_cmhsv4si ((int32x4_t) __b, ++ return (uint32x4_t) __builtin_aarch64_cmgeuv4si ((int32x4_t) __b, + (int32x4_t) __a); + } -@@ -3504,6 +3652,10 @@ - asm_fprintf (asm_out_file, ":tprel:"); - break; + __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) + vcleq_u64 (uint64x2_t __a, uint64x2_t __b) + { +- return (uint64x2_t) __builtin_aarch64_cmhsv2di ((int64x2_t) __b, ++ return (uint64x2_t) __builtin_aarch64_cmgeuv2di ((int64x2_t) __b, + (int64x2_t) __a); + } -+ case SYMBOL_TINY_GOT: -+ gcc_unreachable (); -+ break; ++/* vcle - scalar. */ + - default: - break; - } -@@ -3533,6 +3685,10 @@ - asm_fprintf (asm_out_file, ":tprel_lo12_nc:"); - break; - -+ case SYMBOL_TINY_GOT: -+ asm_fprintf (asm_out_file, ":got:"); -+ break; ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcles_f32 (float32_t __a, float32_t __b) ++{ ++ return __a <= __b ? -1 : 0; ++} + - default: - break; - } -@@ -3647,13 +3803,6 @@ - output_addr_const (f, x); - } - --void --aarch64_function_profiler (FILE *f ATTRIBUTE_UNUSED, -- int labelno ATTRIBUTE_UNUSED) --{ -- sorry ("function profiling"); --} -- - bool - aarch64_label_mentioned_p (rtx x) + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcled_s64 (int64x1_t __a, int64x1_t __b) { -@@ -3919,7 +4068,7 @@ - return offset - crtl->outgoing_args_size; - - if (from == FRAME_POINTER_REGNUM) -- return cfun->machine->frame.saved_regs_size; -+ return cfun->machine->frame.saved_regs_size + get_frame_size (); - } - - if (to == STACK_POINTER_REGNUM) -@@ -3928,6 +4077,7 @@ - { - HOST_WIDE_INT elim = crtl->outgoing_args_size - + cfun->machine->frame.saved_regs_size -+ + get_frame_size () - - cfun->machine->frame.fp_lr_offset; - elim = AARCH64_ROUND_UP (elim, STACK_BOUNDARY / BITS_PER_UNIT); - return elim; -@@ -4601,6 +4751,101 @@ - return aarch64_tune_params->memmov_cost; +- return (uint64x1_t) __builtin_aarch64_cmgedi (__b, __a); ++ return __a <= __b ? -1ll : 0ll; } -+/* Vectorizer cost model target hooks. */ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcled_u64 (uint64x1_t __a, uint64x1_t __b) ++{ ++ return __a <= __b ? -1ll : 0ll; ++} + -+/* Implement targetm.vectorize.builtin_vectorization_cost. */ -+static int -+aarch64_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, -+ tree vectype, -+ int misalign ATTRIBUTE_UNUSED) ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcled_f64 (float64_t __a, float64_t __b) +{ -+ unsigned elements; ++ return __a <= __b ? -1ll : 0ll; ++} + -+ switch (type_of_cost) -+ { -+ case scalar_stmt: -+ return aarch64_tune_params->vec_costs->scalar_stmt_cost; ++/* vclez - vector. */ + -+ case scalar_load: -+ return aarch64_tune_params->vec_costs->scalar_load_cost; ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vclez_f32 (float32x2_t __a) ++{ ++ float32x2_t __b = {0.0f, 0.0f}; ++ return (uint32x2_t) __builtin_aarch64_cmlev2sf (__a, __b); ++} + -+ case scalar_store: -+ return aarch64_tune_params->vec_costs->scalar_store_cost; ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vclez_f64 (float64x1_t __a) ++{ ++ return __a <= 0.0 ? -1ll : 0ll; ++} + -+ case vector_stmt: -+ return aarch64_tune_params->vec_costs->vec_stmt_cost; ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vclez_p8 (poly8x8_t __a) ++{ ++ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmlev8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} + -+ case vector_load: -+ return aarch64_tune_params->vec_costs->vec_align_load_cost; ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vclez_s8 (int8x8_t __a) ++{ ++ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmlev8qi (__a, __b); ++} + -+ case vector_store: -+ return aarch64_tune_params->vec_costs->vec_store_cost; ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vclez_s16 (int16x4_t __a) ++{ ++ int16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmlev4hi (__a, __b); ++} + -+ case vec_to_scalar: -+ return aarch64_tune_params->vec_costs->vec_to_scalar_cost; ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vclez_s32 (int32x2_t __a) ++{ ++ int32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmlev2si (__a, __b); ++} + -+ case scalar_to_vec: -+ return aarch64_tune_params->vec_costs->scalar_to_vec_cost; ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vclez_s64 (int64x1_t __a) ++{ ++ return __a <= 0ll ? -1ll : 0ll; ++} + -+ case unaligned_load: -+ return aarch64_tune_params->vec_costs->vec_unalign_load_cost; ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vclez_u64 (uint64x1_t __a) ++{ ++ return __a <= 0ll ? -1ll : 0ll; ++} + -+ case unaligned_store: -+ return aarch64_tune_params->vec_costs->vec_unalign_store_cost; ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vclezq_f32 (float32x4_t __a) ++{ ++ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; ++ return (uint32x4_t) __builtin_aarch64_cmlev4sf (__a, __b); ++} + -+ case cond_branch_taken: -+ return aarch64_tune_params->vec_costs->cond_taken_branch_cost; ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vclezq_f64 (float64x2_t __a) ++{ ++ float64x2_t __b = {0.0, 0.0}; ++ return (uint64x2_t) __builtin_aarch64_cmlev2df (__a, __b); ++} + -+ case cond_branch_not_taken: -+ return aarch64_tune_params->vec_costs->cond_not_taken_branch_cost; ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vclezq_p8 (poly8x16_t __a) ++{ ++ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmlev16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} + -+ case vec_perm: -+ case vec_promote_demote: -+ return aarch64_tune_params->vec_costs->vec_stmt_cost; ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vclezq_s8 (int8x16_t __a) ++{ ++ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmlev16qi (__a, __b); ++} + -+ case vec_construct: -+ elements = TYPE_VECTOR_SUBPARTS (vectype); -+ return elements / 2 + 1; ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vclezq_s16 (int16x8_t __a) ++{ ++ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmlev8hi (__a, __b); ++} + -+ default: -+ gcc_unreachable (); -+ } ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vclezq_s32 (int32x4_t __a) ++{ ++ int32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmlev4si (__a, __b); +} + -+/* Implement targetm.vectorize.add_stmt_cost. */ -+static unsigned -+aarch64_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, -+ struct _stmt_vec_info *stmt_info, int misalign, -+ enum vect_cost_model_location where) ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vclezq_s64 (int64x2_t __a) +{ -+ unsigned *cost = (unsigned *) data; -+ unsigned retval = 0; ++ int64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmlev2di (__a, __b); ++} + -+ if (flag_vect_cost_model) -+ { -+ tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; -+ int stmt_cost = -+ aarch64_builtin_vectorization_cost (kind, vectype, misalign); ++/* vclez - scalar. */ + -+ /* Statements in an inner loop relative to the loop being -+ vectorized are weighted more heavily. The value here is -+ a function (linear for now) of the loop nest level. */ -+ if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) -+ { -+ loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info); -+ struct loop *loop = LOOP_VINFO_LOOP (loop_info); -+ unsigned nest_level = loop_depth (loop); ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vclezs_f32 (float32_t __a) ++{ ++ return __a <= 0.0f ? -1 : 0; ++} + -+ count *= nest_level; -+ } ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vclezd_s64 (int64x1_t __a) + { +- return (uint64x1_t) __builtin_aarch64_cmledi (__a, 0); ++ return __a <= 0 ? -1ll : 0ll; + } + +-/* vclt */ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vclezd_u64 (int64x1_t __a) ++{ ++ return __a <= 0 ? -1ll : 0ll; ++} + ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vclezd_f64 (float64_t __a) ++{ ++ return __a <= 0.0 ? -1ll : 0ll; ++} + -+ retval = (unsigned) (count * stmt_cost); -+ cost[where] += retval; -+ } ++/* vclt - vector. */ + -+ return retval; ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vclt_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return (uint32x2_t) __builtin_aarch64_cmgtv2sf (__b, __a); ++} ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vclt_f64 (float64x1_t __a, float64x1_t __b) ++{ ++ return __a < __b ? -1ll : 0ll; +} + - static void initialize_aarch64_code_model (void); - - /* Parse the architecture extension string. */ -@@ -4956,6 +5201,7 @@ - - /* Return the method that should be used to access SYMBOL_REF or - LABEL_REF X in context CONTEXT. */ -+ - enum aarch64_symbol_type - aarch64_classify_symbol (rtx x, - enum aarch64_symbol_context context ATTRIBUTE_UNUSED) -@@ -4969,6 +5215,8 @@ - - case AARCH64_CMODEL_TINY_PIC: - case AARCH64_CMODEL_TINY: -+ return SYMBOL_TINY_ABSOLUTE; + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vclt_p8 (poly8x8_t __a, poly8x8_t __b) ++{ ++ return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __b, ++ (int8x8_t) __a); ++} + - case AARCH64_CMODEL_SMALL_PIC: - case AARCH64_CMODEL_SMALL: - return SYMBOL_SMALL_ABSOLUTE; -@@ -4978,71 +5226,47 @@ - } - } - -- gcc_assert (GET_CODE (x) == SYMBOL_REF); -- -- switch (aarch64_cmodel) -+ if (GET_CODE (x) == SYMBOL_REF) - { -- case AARCH64_CMODEL_LARGE: -- return SYMBOL_FORCE_TO_MEM; -- -- case AARCH64_CMODEL_TINY: -- case AARCH64_CMODEL_SMALL: -- -- /* This is needed to get DFmode, TImode constants to be loaded off -- the constant pool. Is it necessary to dump TImode values into -- the constant pool. We don't handle TImode constant loads properly -- yet and hence need to use the constant pool. */ -- if (CONSTANT_POOL_ADDRESS_P (x)) -+ if (aarch64_cmodel == AARCH64_CMODEL_LARGE -+ || CONSTANT_POOL_ADDRESS_P (x)) - return SYMBOL_FORCE_TO_MEM; - - if (aarch64_tls_symbol_p (x)) - return aarch64_classify_tls_symbol (x); - -- if (SYMBOL_REF_WEAK (x)) -- return SYMBOL_FORCE_TO_MEM; -+ switch (aarch64_cmodel) -+ { -+ case AARCH64_CMODEL_TINY: -+ if (SYMBOL_REF_WEAK (x)) -+ return SYMBOL_FORCE_TO_MEM; -+ return SYMBOL_TINY_ABSOLUTE; - -- return SYMBOL_SMALL_ABSOLUTE; -+ case AARCH64_CMODEL_SMALL: -+ if (SYMBOL_REF_WEAK (x)) -+ return SYMBOL_FORCE_TO_MEM; -+ return SYMBOL_SMALL_ABSOLUTE; - -- case AARCH64_CMODEL_TINY_PIC: -- case AARCH64_CMODEL_SMALL_PIC: -+ case AARCH64_CMODEL_TINY_PIC: -+ if (!aarch64_symbol_binds_local_p (x)) -+ return SYMBOL_TINY_GOT; -+ return SYMBOL_TINY_ABSOLUTE; - -- if (CONSTANT_POOL_ADDRESS_P (x)) -- return SYMBOL_FORCE_TO_MEM; -+ case AARCH64_CMODEL_SMALL_PIC: -+ if (!aarch64_symbol_binds_local_p (x)) -+ return SYMBOL_SMALL_GOT; -+ return SYMBOL_SMALL_ABSOLUTE; - -- if (aarch64_tls_symbol_p (x)) -- return aarch64_classify_tls_symbol (x); -+ default: -+ gcc_unreachable (); -+ } -+ } ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vclt_s8 (int8x8_t __a, int8x8_t __b) + { + return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__b, __a); +@@ -19913,38 +19069,56 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vclt_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmgtdi (__b, __a); ++ return __a < __b ? -1ll : 0ll; + } -- if (!aarch64_symbol_binds_local_p (x)) -- return SYMBOL_SMALL_GOT; -- -- return SYMBOL_SMALL_ABSOLUTE; -- -- default: -- gcc_unreachable (); -- } - /* By default push everything into the constant pool. */ - return SYMBOL_FORCE_TO_MEM; + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vclt_u8 (uint8x8_t __a, uint8x8_t __b) + { +- return (uint8x8_t) __builtin_aarch64_cmhiv8qi ((int8x8_t) __b, ++ return (uint8x8_t) __builtin_aarch64_cmgtuv8qi ((int8x8_t) __b, + (int8x8_t) __a); } --/* Return true if X is a symbolic constant that can be used in context -- CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */ -- - bool --aarch64_symbolic_constant_p (rtx x, enum aarch64_symbol_context context, -- enum aarch64_symbol_type *symbol_type) --{ -- rtx offset; -- split_const (x, &x, &offset); -- if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) -- *symbol_type = aarch64_classify_symbol (x, context); -- else -- return false; -- -- /* No checking of offset at this point. */ -- return true; --} -- --bool - aarch64_constant_address_p (rtx x) + __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) + vclt_u16 (uint16x4_t __a, uint16x4_t __b) { - return (CONSTANT_P (x) && memory_address_p (DImode, x)); -@@ -5092,8 +5316,7 @@ - /* This could probably go away because - we now decompose CONST_INTs according to expand_mov_immediate. */ - if ((GET_CODE (x) == CONST_VECTOR -- && aarch64_simd_valid_immediate (x, mode, false, -- NULL, NULL, NULL, NULL, NULL) != -1) -+ && aarch64_simd_valid_immediate (x, mode, false, NULL)) - || CONST_INT_P (x) || aarch64_valid_floating_const (mode, x)) - return !targetm.cannot_force_const_mem (mode, x); +- return (uint16x4_t) __builtin_aarch64_cmhiv4hi ((int16x4_t) __b, ++ return (uint16x4_t) __builtin_aarch64_cmgtuv4hi ((int16x4_t) __b, + (int16x4_t) __a); + } -@@ -5924,32 +6147,57 @@ - return false; + __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) + vclt_u32 (uint32x2_t __a, uint32x2_t __b) + { +- return (uint32x2_t) __builtin_aarch64_cmhiv2si ((int32x2_t) __b, ++ return (uint32x2_t) __builtin_aarch64_cmgtuv2si ((int32x2_t) __b, + (int32x2_t) __a); } --/* Return quad mode as the preferred SIMD mode. */ -+/* Return appropriate SIMD container -+ for MODE within a vector of WIDTH bits. */ - static enum machine_mode --aarch64_preferred_simd_mode (enum machine_mode mode) -+aarch64_simd_container_mode (enum machine_mode mode, unsigned width) + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vclt_u64 (uint64x1_t __a, uint64x1_t __b) { -+ gcc_assert (width == 64 || width == 128); - if (TARGET_SIMD) -- switch (mode) -- { -- case DFmode: -- return V2DFmode; -- case SFmode: -- return V4SFmode; -- case SImode: -- return V4SImode; -- case HImode: -- return V8HImode; -- case QImode: -- return V16QImode; -- case DImode: -- return V2DImode; -- break; -- -- default:; -- } -+ { -+ if (width == 128) -+ switch (mode) -+ { -+ case DFmode: -+ return V2DFmode; -+ case SFmode: -+ return V4SFmode; -+ case SImode: -+ return V4SImode; -+ case HImode: -+ return V8HImode; -+ case QImode: -+ return V16QImode; -+ case DImode: -+ return V2DImode; -+ default: -+ break; -+ } -+ else -+ switch (mode) -+ { -+ case SFmode: -+ return V2SFmode; -+ case SImode: -+ return V2SImode; -+ case HImode: -+ return V4HImode; -+ case QImode: -+ return V8QImode; -+ default: -+ break; -+ } -+ } - return word_mode; +- return (uint64x1_t) __builtin_aarch64_cmhidi ((int64x1_t) __b, +- (int64x1_t) __a); ++ return __a < __b ? -1ll : 0ll; } -+/* Return 128-bit container as the preferred SIMD mode for MODE. */ -+static enum machine_mode -+aarch64_preferred_simd_mode (enum machine_mode mode) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcltq_f32 (float32x4_t __a, float32x4_t __b) +{ -+ return aarch64_simd_container_mode (mode, 128); ++ return (uint32x4_t) __builtin_aarch64_cmgtv4sf (__b, __a); +} + - /* Return the bitmask of possible vector sizes for the vectorizer - to iterate over. */ - static unsigned int -@@ -5999,6 +6247,7 @@ - { V2DFmode, "__builtin_aarch64_simd_df", "13__Float64x2_t" }, - { V16QImode, "__builtin_aarch64_simd_poly8", "12__Poly8x16_t" }, - { V8HImode, "__builtin_aarch64_simd_poly16", "12__Poly16x8_t" }, -+ { V2DImode, "__builtin_aarch64_simd_poly64", "12__Poly64x2_t" }, - { VOIDmode, NULL, NULL } - }; - -@@ -6037,7 +6286,7 @@ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcltq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return (uint64x2_t) __builtin_aarch64_cmgtv2df (__b, __a); ++} ++ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcltq_p8 (poly8x16_t __a, poly8x16_t __b) ++{ ++ return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __b, ++ (int8x16_t) __a); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcltq_s8 (int8x16_t __a, int8x16_t __b) + { + return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__b, __a); +@@ -19971,91 +19145,664 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vcltq_u8 (uint8x16_t __a, uint8x16_t __b) + { +- return (uint8x16_t) __builtin_aarch64_cmhiv16qi ((int8x16_t) __b, ++ return (uint8x16_t) __builtin_aarch64_cmgtuv16qi ((int8x16_t) __b, + (int8x16_t) __a); } - /* Return the equivalent letter for size. */ --static unsigned char -+static char - sizetochar (int size) + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vcltq_u16 (uint16x8_t __a, uint16x8_t __b) { - switch (size) -@@ -6084,15 +6333,10 @@ - return aarch64_float_const_representable_p (x0); +- return (uint16x8_t) __builtin_aarch64_cmhiv8hi ((int16x8_t) __b, ++ return (uint16x8_t) __builtin_aarch64_cmgtuv8hi ((int16x8_t) __b, + (int16x8_t) __a); } --/* TODO: This function returns values similar to those -- returned by neon_valid_immediate in gcc/config/arm/arm.c -- but the API here is different enough that these magic numbers -- are not used. It should be sufficient to return true or false. */ --static int --aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, int inverse, -- rtx *modconst, int *elementwidth, -- unsigned char *elementchar, -- int *mvn, int *shift) -+/* Return true for valid and false for invalid. */ -+bool -+aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse, -+ struct simd_immediate_info *info) + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vcltq_u32 (uint32x4_t __a, uint32x4_t __b) { - #define CHECK(STRIDE, ELSIZE, CLASS, TEST, SHIFT, NEG) \ - matches = 1; \ -@@ -6103,7 +6347,6 @@ - { \ - immtype = (CLASS); \ - elsize = (ELSIZE); \ -- elchar = sizetochar (elsize); \ - eshift = (SHIFT); \ - emvn = (NEG); \ - break; \ -@@ -6112,7 +6355,6 @@ - unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op); - unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode)); - unsigned char bytes[16]; -- unsigned char elchar = 0; - int immtype = -1, matches; - unsigned int invmask = inverse ? 0xff : 0; - int eshift, emvn; -@@ -6119,29 +6361,19 @@ - - if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) - { -- bool simd_imm_zero = aarch64_simd_imm_zero_p (op, mode); -- int elem_width = GET_MODE_BITSIZE (GET_MODE (CONST_VECTOR_ELT (op, 0))); -+ if (! (aarch64_simd_imm_zero_p (op, mode) -+ || aarch64_vect_float_const_representable_p (op))) -+ return false; - -- if (!(simd_imm_zero -- || aarch64_vect_float_const_representable_p (op))) -- return -1; -+ if (info) -+ { -+ info->value = CONST_VECTOR_ELT (op, 0); -+ info->element_width = GET_MODE_BITSIZE (GET_MODE (info->value)); -+ info->mvn = false; -+ info->shift = 0; -+ } - -- if (modconst) -- *modconst = CONST_VECTOR_ELT (op, 0); -- -- if (elementwidth) -- *elementwidth = elem_width; -- -- if (elementchar) -- *elementchar = sizetochar (elem_width); -- -- if (shift) -- *shift = 0; -- -- if (simd_imm_zero) -- return 19; -- else -- return 18; -+ return true; - } - - /* Splat vector constant out into a byte vector. */ -@@ -6215,16 +6447,16 @@ - CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1], 8, 1); - - CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1] -- && bytes[i + 2] == 0 && bytes[i + 3] == 0, 0, 0); -+ && bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0); - - CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1] -- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 0, 1); -+ && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1); - - CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff -- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 0, 0); -+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0); - - CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0 -- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 0, 1); -+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1); - - CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0); - -@@ -6233,31 +6465,20 @@ - } - while (0); - -- /* TODO: Currently the assembler cannot handle types 12 to 15. -- And there is no way to specify cmode through the compiler. -- Disable them till there is support in the assembler. */ -- if (immtype == -1 -- || (immtype >= 12 && immtype <= 15) -- || immtype == 18) -- return -1; -+ if (immtype == -1) -+ return false; - -+ if (info) -+ { -+ info->element_width = elsize; -+ info->mvn = emvn != 0; -+ info->shift = eshift; - -- if (elementwidth) -- *elementwidth = elsize; -+ unsigned HOST_WIDE_INT imm = 0; +- return (uint32x4_t) __builtin_aarch64_cmhiv4si ((int32x4_t) __b, ++ return (uint32x4_t) __builtin_aarch64_cmgtuv4si ((int32x4_t) __b, + (int32x4_t) __a); + } -- if (elementchar) -- *elementchar = elchar; -+ if (immtype >= 12 && immtype <= 15) -+ info->msl = true; + __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) + vcltq_u64 (uint64x2_t __a, uint64x2_t __b) + { +- return (uint64x2_t) __builtin_aarch64_cmhiv2di ((int64x2_t) __b, ++ return (uint64x2_t) __builtin_aarch64_cmgtuv2di ((int64x2_t) __b, + (int64x2_t) __a); + } -- if (mvn) -- *mvn = emvn; -- -- if (shift) -- *shift = eshift; -- -- if (modconst) -- { -- unsigned HOST_WIDE_INT imm = 0; -- - /* Un-invert bytes of recognized vector, if necessary. */ - if (invmask != 0) - for (i = 0; i < idx; i++) -@@ -6272,68 +6493,27 @@ - imm |= (unsigned HOST_WIDE_INT) (bytes[i] ? 0xff : 0) - << (i * BITS_PER_UNIT); ++/* vclt - scalar. */ ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vclts_f32 (float32_t __a, float32_t __b) ++{ ++ return __a < __b ? -1 : 0; ++} ++ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcltd_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmgtdi (__b, __a); ++ return __a < __b ? -1ll : 0ll; + } -- *modconst = GEN_INT (imm); -- } + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcltd_u64 (uint64x1_t __a, uint64x1_t __b) ++{ ++ return __a < __b ? -1ll : 0ll; ++} ++ ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcltd_f64 (float64_t __a, float64_t __b) ++{ ++ return __a < __b ? -1ll : 0ll; ++} ++ ++/* vcltz - vector. */ ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcltz_f32 (float32x2_t __a) ++{ ++ float32x2_t __b = {0.0f, 0.0f}; ++ return (uint32x2_t) __builtin_aarch64_cmltv2sf (__a, __b); ++} ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcltz_f64 (float64x1_t __a) ++{ ++ return __a < 0.0 ? -1ll : 0ll; ++} ++ ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcltz_p8 (poly8x8_t __a) ++{ ++ poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmltv8qi ((int8x8_t) __a, ++ (int8x8_t) __b); ++} ++ ++__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) ++vcltz_s8 (int8x8_t __a) ++{ ++ int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x8_t) __builtin_aarch64_cmltv8qi (__a, __b); ++} ++ ++__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) ++vcltz_s16 (int16x4_t __a) ++{ ++ int16x4_t __b = {0, 0, 0, 0}; ++ return (uint16x4_t) __builtin_aarch64_cmltv4hi (__a, __b); ++} ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcltz_s32 (int32x2_t __a) ++{ ++ int32x2_t __b = {0, 0}; ++ return (uint32x2_t) __builtin_aarch64_cmltv2si (__a, __b); ++} ++ ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcltz_s64 (int64x1_t __a) ++{ ++ return __a < 0ll ? -1ll : 0ll; ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcltzq_f32 (float32x4_t __a) ++{ ++ float32x4_t __b = {0.0f, 0.0f, 0.0f, 0.0f}; ++ return (uint32x4_t) __builtin_aarch64_cmltv4sf (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcltzq_f64 (float64x2_t __a) ++{ ++ float64x2_t __b = {0.0, 0.0}; ++ return (uint64x2_t) __builtin_aarch64_cmltv2df (__a, __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcltzq_p8 (poly8x16_t __a) ++{ ++ poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmltv16qi ((int8x16_t) __a, ++ (int8x16_t) __b); ++} ++ ++__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) ++vcltzq_s8 (int8x16_t __a) ++{ ++ int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint8x16_t) __builtin_aarch64_cmltv16qi (__a, __b); ++} ++ ++__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) ++vcltzq_s16 (int16x8_t __a) ++{ ++ int16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; ++ return (uint16x8_t) __builtin_aarch64_cmltv8hi (__a, __b); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcltzq_s32 (int32x4_t __a) ++{ ++ int32x4_t __b = {0, 0, 0, 0}; ++ return (uint32x4_t) __builtin_aarch64_cmltv4si (__a, __b); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcltzq_s64 (int64x2_t __a) ++{ ++ int64x2_t __b = {0, 0}; ++ return (uint64x2_t) __builtin_aarch64_cmltv2di (__a, __b); ++} ++ ++/* vcltz - scalar. */ ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcltzs_f32 (float32_t __a) ++{ ++ return __a < 0.0f ? -1 : 0; ++} + -+ info->value = GEN_INT (imm); -+ } - else -- { -- unsigned HOST_WIDE_INT imm = 0; -+ { -+ for (i = 0; i < elsize / BITS_PER_UNIT; i++) -+ imm |= (unsigned HOST_WIDE_INT) bytes[i] << (i * BITS_PER_UNIT); - -- for (i = 0; i < elsize / BITS_PER_UNIT; i++) -- imm |= (unsigned HOST_WIDE_INT) bytes[i] << (i * BITS_PER_UNIT); -- - /* Construct 'abcdefgh' because the assembler cannot handle -- generic constants. */ -- gcc_assert (shift != NULL && mvn != NULL); -- if (*mvn) -+ generic constants. */ -+ if (info->mvn) - imm = ~imm; -- imm = (imm >> *shift) & 0xff; -- *modconst = GEN_INT (imm); -- } -+ imm = (imm >> info->shift) & 0xff; -+ info->value = GEN_INT (imm); -+ } - } - -- return immtype; -+ return true; - #undef CHECK - } - --/* Return TRUE if rtx X is legal for use as either a AdvSIMD MOVI instruction -- (or, implicitly, MVNI) immediate. Write back width per element -- to *ELEMENTWIDTH, and a modified constant (whatever should be output -- for a MOVI instruction) in *MODCONST. */ --int --aarch64_simd_immediate_valid_for_move (rtx op, enum machine_mode mode, -- rtx *modconst, int *elementwidth, -- unsigned char *elementchar, -- int *mvn, int *shift) --{ -- rtx tmpconst; -- int tmpwidth; -- unsigned char tmpwidthc; -- int tmpmvn = 0, tmpshift = 0; -- int retval = aarch64_simd_valid_immediate (op, mode, 0, &tmpconst, -- &tmpwidth, &tmpwidthc, -- &tmpmvn, &tmpshift); -- -- if (retval == -1) -- return 0; -- -- if (modconst) -- *modconst = tmpconst; -- -- if (elementwidth) -- *elementwidth = tmpwidth; -- -- if (elementchar) -- *elementchar = tmpwidthc; -- -- if (mvn) -- *mvn = tmpmvn; -- -- if (shift) -- *shift = tmpshift; -- -- return 1; --} -- - static bool - aarch64_const_vec_all_same_int_p (rtx x, - HOST_WIDE_INT minval, -@@ -6395,6 +6575,25 @@ - return true; ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vcltzd_s64 (int64x1_t __a) + { +- return (uint64x1_t) __builtin_aarch64_cmltdi (__a, 0); ++ return __a < 0 ? -1ll : 0ll; } -+bool -+aarch64_mov_operand_p (rtx x, -+ enum aarch64_symbol_context context, -+ enum machine_mode mode) ++__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) ++vcltzd_u64 (int64x1_t __a) +{ -+ if (GET_CODE (x) == HIGH -+ && aarch64_valid_symref (XEXP (x, 0), GET_MODE (XEXP (x, 0)))) -+ return true; ++ return __a < 0 ? -1ll : 0ll; ++} + -+ if (CONST_INT_P (x) && aarch64_move_imm (INTVAL (x), mode)) -+ return true; ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcltzd_f64 (float64_t __a) ++{ ++ return __a < 0.0 ? -1ll : 0ll; ++} + -+ if (GET_CODE (x) == SYMBOL_REF && mode == DImode && CONSTANT_ADDRESS_P (x)) -+ return true; ++/* vcvt (double -> float). */ + -+ return aarch64_classify_symbolic_expression (x, context) -+ == SYMBOL_TINY_ABSOLUTE; ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vcvt_f32_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_float_truncate_lo_v2sf (__a); +} + - /* Return a const_int vector of VAL. */ - rtx - aarch64_simd_gen_const_vector_dup (enum machine_mode mode, int val) -@@ -6409,6 +6608,19 @@ - return gen_rtx_CONST_VECTOR (mode, v); - } - -+/* Check OP is a legal scalar immediate for the MOVI instruction. */ ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vcvt_high_f32_f64 (float32x2_t __a, float64x2_t __b) ++{ ++ return __builtin_aarch64_float_truncate_hi_v4sf (__a, __b); ++} + -+bool -+aarch64_simd_scalar_immediate_valid_for_move (rtx op, enum machine_mode mode) ++/* vcvt (float -> double). */ ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vcvt_f64_f32 (float32x2_t __a) +{ -+ enum machine_mode vmode; + -+ gcc_assert (!VECTOR_MODE_P (mode)); -+ vmode = aarch64_preferred_simd_mode (mode); -+ rtx op_v = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (op)); -+ return aarch64_simd_valid_immediate (op_v, vmode, false, NULL); ++ return __builtin_aarch64_float_extend_lo_v2df (__a); +} + - /* Construct and return a PARALLEL RTX vector. */ - rtx - aarch64_simd_vect_par_cnst_half (enum machine_mode mode, bool high) -@@ -6634,8 +6846,7 @@ - gcc_unreachable (); - - if (const_vec != NULL_RTX -- && aarch64_simd_immediate_valid_for_move (const_vec, mode, NULL, NULL, -- NULL, NULL, NULL)) -+ && aarch64_simd_valid_immediate (const_vec, mode, false, NULL)) - /* Load using MOVI/MVNI. */ - return const_vec; - else if ((const_dup = aarch64_simd_dup_constant (vals)) != NULL_RTX) -@@ -7193,49 +7404,80 @@ - } - - char* --aarch64_output_simd_mov_immediate (rtx *const_vector, -+aarch64_output_simd_mov_immediate (rtx const_vector, - enum machine_mode mode, - unsigned width) - { -- int is_valid; -- unsigned char widthc; -- int lane_width_bits; -+ bool is_valid; - static char templ[40]; -- int shift = 0, mvn = 0; - const char *mnemonic; -+ const char *shift_op; - unsigned int lane_count = 0; -+ char element_char; - -- is_valid = -- aarch64_simd_immediate_valid_for_move (*const_vector, mode, -- const_vector, &lane_width_bits, -- &widthc, &mvn, &shift); -+ struct simd_immediate_info info = { NULL_RTX, 0, 0, false, false }; ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vcvt_high_f64_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_vec_unpacks_hi_v4sf (__a); ++} + -+ /* This will return true to show const_vector is legal for use as either -+ a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will -+ also update INFO to show how the immediate should be generated. */ -+ is_valid = aarch64_simd_valid_immediate (const_vector, mode, false, &info); - gcc_assert (is_valid); - -+ element_char = sizetochar (info.element_width); -+ lane_count = width / info.element_width; ++/* vcvt (int -> float) */ + - mode = GET_MODE_INNER (mode); - if (mode == SFmode || mode == DFmode) - { -- bool zero_p = -- aarch64_float_const_zero_rtx_p (*const_vector); -- gcc_assert (shift == 0); -- mnemonic = zero_p ? "movi" : "fmov"; -+ gcc_assert (info.shift == 0 && ! info.mvn); -+ if (aarch64_float_const_zero_rtx_p (info.value)) -+ info.value = GEN_INT (0); -+ else -+ { -+#define buf_size 20 -+ REAL_VALUE_TYPE r; -+ REAL_VALUE_FROM_CONST_DOUBLE (r, info.value); -+ char float_buf[buf_size] = {'\0'}; -+ real_to_decimal_for_mode (float_buf, &r, buf_size, buf_size, 1, mode); -+#undef buf_size ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vcvtd_f64_s64 (int64_t __a) ++{ ++ return (float64_t) __a; ++} + -+ if (lane_count == 1) -+ snprintf (templ, sizeof (templ), "fmov\t%%d0, %s", float_buf); -+ else -+ snprintf (templ, sizeof (templ), "fmov\t%%0.%d%c, %s", -+ lane_count, element_char, float_buf); -+ return templ; -+ } - } -- else -- mnemonic = mvn ? "mvni" : "movi"; - -- gcc_assert (lane_width_bits != 0); -- lane_count = width / lane_width_bits; -+ mnemonic = info.mvn ? "mvni" : "movi"; -+ shift_op = info.msl ? "msl" : "lsl"; - - if (lane_count == 1) -- snprintf (templ, sizeof (templ), "%s\t%%d0, %%1", mnemonic); -- else if (shift) -- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, %%1, lsl %d", -- mnemonic, lane_count, widthc, shift); -+ snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX, -+ mnemonic, UINTVAL (info.value)); -+ else if (info.shift) -+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX -+ ", %s %d", mnemonic, lane_count, element_char, -+ UINTVAL (info.value), shift_op, info.shift); - else -- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, %%1", -- mnemonic, lane_count, widthc); -+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX, -+ mnemonic, lane_count, element_char, UINTVAL (info.value)); - return templ; - } - -+char* -+aarch64_output_scalar_simd_mov_immediate (rtx immediate, -+ enum machine_mode mode) ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vcvtd_f64_u64 (uint64_t __a) +{ -+ enum machine_mode vmode; ++ return (float64_t) __a; ++} + -+ gcc_assert (!VECTOR_MODE_P (mode)); -+ vmode = aarch64_simd_container_mode (mode, 64); -+ rtx v_op = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (immediate)); -+ return aarch64_output_simd_mov_immediate (v_op, vmode, 64); ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vcvts_f32_s32 (int32_t __a) ++{ ++ return (float32_t) __a; +} + - /* Split operands into moves from op[1] + op[2] into op[0]. */ - - void -@@ -7860,6 +8102,9 @@ - #undef TARGET_EXPAND_BUILTIN_VA_START - #define TARGET_EXPAND_BUILTIN_VA_START aarch64_expand_builtin_va_start - -+#undef TARGET_FOLD_BUILTIN -+#define TARGET_FOLD_BUILTIN aarch64_fold_builtin ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vcvts_f32_u32 (uint32_t __a) ++{ ++ return (float32_t) __a; ++} + - #undef TARGET_FUNCTION_ARG - #define TARGET_FUNCTION_ARG aarch64_function_arg - -@@ -7881,6 +8126,9 @@ - #undef TARGET_FRAME_POINTER_REQUIRED - #define TARGET_FRAME_POINTER_REQUIRED aarch64_frame_pointer_required - -+#undef TARGET_GIMPLE_FOLD_BUILTIN -+#define TARGET_GIMPLE_FOLD_BUILTIN aarch64_gimple_fold_builtin ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vcvt_f32_s32 (int32x2_t __a) ++{ ++ return __builtin_aarch64_floatv2siv2sf (__a); ++} + - #undef TARGET_GIMPLIFY_VA_ARG_EXPR - #define TARGET_GIMPLIFY_VA_ARG_EXPR aarch64_gimplify_va_arg_expr - -@@ -7960,6 +8208,13 @@ - #undef TARGET_ARRAY_MODE_SUPPORTED_P - #define TARGET_ARRAY_MODE_SUPPORTED_P aarch64_array_mode_supported_p - -+#undef TARGET_VECTORIZE_ADD_STMT_COST -+#define TARGET_VECTORIZE_ADD_STMT_COST aarch64_add_stmt_cost ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vcvt_f32_u32 (uint32x2_t __a) ++{ ++ return __builtin_aarch64_floatunsv2siv2sf ((int32x2_t) __a); ++} + -+#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST -+#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \ -+ aarch64_builtin_vectorization_cost ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vcvtq_f32_s32 (int32x4_t __a) ++{ ++ return __builtin_aarch64_floatv4siv4sf (__a); ++} + - #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE - #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE aarch64_preferred_simd_mode - ---- a/src/gcc/config/aarch64/iterators.md -+++ b/src/gcc/config/aarch64/iterators.md -@@ -83,6 +83,9 @@ - ;; Vector Float modes. - (define_mode_iterator VDQF [V2SF V4SF V2DF]) - -+;; Modes suitable to use as the return type of a vcond expression. -+(define_mode_iterator VDQF_COND [V2SF V2SI V4SF V4SI V2DF V2DI]) ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vcvtq_f32_u32 (uint32x4_t __a) ++{ ++ return __builtin_aarch64_floatunsv4siv4sf ((int32x4_t) __a); ++} + - ;; All Float modes. - (define_mode_iterator VALLF [V2SF V4SF V2DF SF DF]) - -@@ -125,9 +128,15 @@ - ;; Vector modes except double int. - (define_mode_iterator VDQIF [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF V2DF]) - -+;; Vector modes for Q and H types. -+(define_mode_iterator VDQQH [V8QI V16QI V4HI V8HI]) ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vcvtq_f64_s64 (int64x2_t __a) ++{ ++ return __builtin_aarch64_floatv2div2df (__a); ++} + - ;; Vector modes for H and S types. - (define_mode_iterator VDQHS [V4HI V8HI V2SI V4SI]) - -+;; Vector modes for Q, H and S types. -+(define_mode_iterator VDQQHS [V8QI V16QI V4HI V8HI V2SI V4SI]) ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vcvtq_f64_u64 (uint64x2_t __a) ++{ ++ return __builtin_aarch64_floatunsv2div2df ((int64x2_t) __a); ++} + - ;; Vector and scalar integer modes for H and S - (define_mode_iterator VSDQ_HSI [V4HI V8HI V2SI V4SI HI SI]) - -@@ -163,10 +172,15 @@ - [ - UNSPEC_ASHIFT_SIGNED ; Used in aarch-simd.md. - UNSPEC_ASHIFT_UNSIGNED ; Used in aarch64-simd.md. -+ UNSPEC_FMAX ; Used in aarch64-simd.md. -+ UNSPEC_FMAXNMV ; Used in aarch64-simd.md. - UNSPEC_FMAXV ; Used in aarch64-simd.md. -+ UNSPEC_FMIN ; Used in aarch64-simd.md. -+ UNSPEC_FMINNMV ; Used in aarch64-simd.md. - UNSPEC_FMINV ; Used in aarch64-simd.md. - UNSPEC_FADDV ; Used in aarch64-simd.md. -- UNSPEC_ADDV ; Used in aarch64-simd.md. -+ UNSPEC_SADDV ; Used in aarch64-simd.md. -+ UNSPEC_UADDV ; Used in aarch64-simd.md. - UNSPEC_SMAXV ; Used in aarch64-simd.md. - UNSPEC_SMINV ; Used in aarch64-simd.md. - UNSPEC_UMAXV ; Used in aarch64-simd.md. -@@ -223,9 +237,6 @@ - UNSPEC_SSHLL ; Used in aarch64-simd.md. - UNSPEC_USHLL ; Used in aarch64-simd.md. - UNSPEC_ADDP ; Used in aarch64-simd.md. -- UNSPEC_FMAX ; Used in aarch64-simd.md. -- UNSPEC_FMIN ; Used in aarch64-simd.md. -- UNSPEC_BSL ; Used in aarch64-simd.md. - UNSPEC_TBL ; Used in vector permute patterns. - UNSPEC_CONCAT ; Used in vector permute patterns. - UNSPEC_ZIP1 ; Used in vector permute patterns. -@@ -234,6 +245,22 @@ - UNSPEC_UZP2 ; Used in vector permute patterns. - UNSPEC_TRN1 ; Used in vector permute patterns. - UNSPEC_TRN2 ; Used in vector permute patterns. -+ UNSPEC_AESE ; Used in aarch64-simd.md. -+ UNSPEC_AESD ; Used in aarch64-simd.md. -+ UNSPEC_AESMC ; Used in aarch64-simd.md. -+ UNSPEC_AESIMC ; Used in aarch64-simd.md. -+ UNSPEC_SHA1C ; Used in aarch64-simd.md. -+ UNSPEC_SHA1M ; Used in aarch64-simd.md. -+ UNSPEC_SHA1P ; Used in aarch64-simd.md. -+ UNSPEC_SHA1H ; Used in aarch64-simd.md. -+ UNSPEC_SHA1SU0 ; Used in aarch64-simd.md. -+ UNSPEC_SHA1SU1 ; Used in aarch64-simd.md. -+ UNSPEC_SHA256H ; Used in aarch64-simd.md. -+ UNSPEC_SHA256H2 ; Used in aarch64-simd.md. -+ UNSPEC_SHA256SU0 ; Used in aarch64-simd.md. -+ UNSPEC_SHA256SU1 ; Used in aarch64-simd.md. -+ UNSPEC_PMULL ; Used in aarch64-simd.md. -+ UNSPEC_PMULL2 ; Used in aarch64-simd.md. - ]) - - ;; ------------------------------------------------------------------- -@@ -244,6 +271,9 @@ - ;; 32-bit version and "%x0" in the 64-bit version. - (define_mode_attr w [(QI "w") (HI "w") (SI "w") (DI "x") (SF "s") (DF "d")]) - -+;; For constraints used in scalar immediate vector moves -+(define_mode_attr hq [(HI "h") (QI "q")]) ++/* vcvt (float -> int) */ ++ ++__extension__ static __inline int64_t __attribute__ ((__always_inline__)) ++vcvtd_s64_f64 (float64_t __a) ++{ ++ return (int64_t) __a; ++} ++ ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcvtd_u64_f64 (float64_t __a) ++{ ++ return (uint64_t) __a; ++} ++ ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vcvts_s32_f32 (float32_t __a) ++{ ++ return (int32_t) __a; ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcvts_u32_f32 (float32_t __a) ++{ ++ return (uint32_t) __a; ++} ++ ++__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) ++vcvt_s32_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_lbtruncv2sfv2si (__a); ++} ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcvt_u32_f32 (float32x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x2_t) __builtin_aarch64_lbtruncuv2sfv2si (__a); ++} ++ ++__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) ++vcvtq_s32_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_lbtruncv4sfv4si (__a); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcvtq_u32_f32 (float32x4_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x4_t) __builtin_aarch64_lbtruncuv4sfv4si (__a); ++} ++ ++__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) ++vcvtq_s64_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_lbtruncv2dfv2di (__a); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcvtq_u64_f64 (float64x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint64x2_t) __builtin_aarch64_lbtruncuv2dfv2di (__a); ++} ++ ++/* vcvta */ ++ ++__extension__ static __inline int64_t __attribute__ ((__always_inline__)) ++vcvtad_s64_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_lrounddfdi (__a); ++} ++ ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcvtad_u64_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_lroundudfdi (__a); ++} ++ ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vcvtas_s32_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_lroundsfsi (__a); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcvtas_u32_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_lroundusfsi (__a); ++} ++ ++__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) ++vcvta_s32_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_lroundv2sfv2si (__a); ++} ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcvta_u32_f32 (float32x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x2_t) __builtin_aarch64_lrounduv2sfv2si (__a); ++} ++ ++__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) ++vcvtaq_s32_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_lroundv4sfv4si (__a); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcvtaq_u32_f32 (float32x4_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x4_t) __builtin_aarch64_lrounduv4sfv4si (__a); ++} ++ ++__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) ++vcvtaq_s64_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_lroundv2dfv2di (__a); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcvtaq_u64_f64 (float64x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint64x2_t) __builtin_aarch64_lrounduv2dfv2di (__a); ++} + - ;; For scalar usage of vector/FP registers - (define_mode_attr v [(QI "b") (HI "h") (SI "s") (DI "d") - (SF "s") (DF "d") -@@ -377,7 +407,8 @@ - ;; Double modes of vector modes (lower case). - (define_mode_attr Vdbl [(V8QI "v16qi") (V4HI "v8hi") - (V2SI "v4si") (V2SF "v4sf") -- (SI "v2si") (DI "v2di")]) -+ (SI "v2si") (DI "v2di") -+ (DF "v2df")]) - - ;; Narrowed modes for VDN. - (define_mode_attr VNARROWD [(V4HI "V8QI") (V2SI "V4HI") -@@ -432,6 +463,15 @@ - (V2SF "s") (V4SF "s") - (V2DF "d")]) - -+;; Corresponding core element mode for each vector mode. This is a -+;; variation on mapping FP modes to GP regs. -+(define_mode_attr vwcore [(V8QI "w") (V16QI "w") -+ (V4HI "w") (V8HI "w") -+ (V2SI "w") (V4SI "w") -+ (DI "x") (V2DI "x") -+ (V2SF "w") (V4SF "w") -+ (V2DF "x")]) ++/* vcvtm */ + - ;; Double vector types for ALLX. - (define_mode_attr Vallxd [(QI "8b") (HI "4h") (SI "2s")]) - -@@ -527,9 +567,14 @@ - ;; Iterator for integer conversions - (define_code_iterator FIXUORS [fix unsigned_fix]) - -+;; Iterator for float conversions -+(define_code_iterator FLOATUORS [float unsigned_float]) ++__extension__ static __inline int64_t __attribute__ ((__always_inline__)) ++vcvtmd_s64_f64 (float64_t __a) ++{ ++ return __builtin_lfloor (__a); ++} + - ;; Code iterator for variants of vector max and min. - (define_code_iterator MAXMIN [smax smin umax umin]) - -+(define_code_iterator FMAXMIN [smax smin]) ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcvtmd_u64_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_lfloorudfdi (__a); ++} + - ;; Code iterator for variants of vector max and min. - (define_code_iterator ADDSUB [plus minus]) - -@@ -548,6 +593,9 @@ - ;; Unsigned comparison operators. - (define_code_iterator UCOMPARISONS [ltu leu geu gtu]) - -+;; Unsigned comparison operators. -+(define_code_iterator FAC_COMPARISONS [lt le ge gt]) ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vcvtms_s32_f32 (float32_t __a) ++{ ++ return __builtin_ifloorf (__a); ++} + - ;; ------------------------------------------------------------------- - ;; Code Attributes - ;; ------------------------------------------------------------------- -@@ -560,6 +608,10 @@ - (zero_extend "zero_extend") - (sign_extract "extv") - (zero_extract "extzv") -+ (fix "fix") -+ (unsigned_fix "fixuns") -+ (float "float") -+ (unsigned_float "floatuns") - (and "and") - (ior "ior") - (xor "xor") -@@ -599,10 +651,14 @@ - (define_code_attr CMP [(lt "LT") (le "LE") (eq "EQ") (ge "GE") (gt "GT") - (ltu "LTU") (leu "LEU") (geu "GEU") (gtu "GTU")]) - -+(define_code_attr fix_trunc_optab [(fix "fix_trunc") -+ (unsigned_fix "fixuns_trunc")]) ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcvtms_u32_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_lfloorusfsi (__a); ++} + - ;; Optab prefix for sign/zero-extending operations - (define_code_attr su_optab [(sign_extend "") (zero_extend "u") - (div "") (udiv "u") - (fix "") (unsigned_fix "u") -+ (float "s") (unsigned_float "u") - (ss_plus "s") (us_plus "u") - (ss_minus "s") (us_minus "u")]) - -@@ -627,7 +683,9 @@ - (define_code_attr su [(sign_extend "s") (zero_extend "u") - (sign_extract "s") (zero_extract "u") - (fix "s") (unsigned_fix "u") -- (div "s") (udiv "u")]) -+ (div "s") (udiv "u") -+ (smax "s") (umax "u") -+ (smin "s") (umin "u")]) - - ;; Emit cbz/cbnz depending on comparison type. - (define_code_attr cbz [(eq "cbz") (ne "cbnz") (lt "cbnz") (ge "cbz")]) -@@ -636,10 +694,10 @@ - (define_code_attr tbz [(eq "tbz") (ne "tbnz") (lt "tbnz") (ge "tbz")]) - - ;; Max/min attributes. --(define_code_attr maxmin [(smax "smax") -- (smin "smin") -- (umax "umax") -- (umin "umin")]) -+(define_code_attr maxmin [(smax "max") -+ (smin "min") -+ (umax "max") -+ (umin "min")]) - - ;; MLA/MLS attributes. - (define_code_attr as [(ss_plus "a") (ss_minus "s")]) -@@ -661,8 +719,11 @@ - (define_int_iterator MAXMINV [UNSPEC_UMAXV UNSPEC_UMINV - UNSPEC_SMAXV UNSPEC_SMINV]) - --(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV]) -+(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV -+ UNSPEC_FMAXNMV UNSPEC_FMINNMV]) - -+(define_int_iterator SUADDV [UNSPEC_SADDV UNSPEC_UADDV]) ++__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) ++vcvtm_s32_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_lfloorv2sfv2si (__a); ++} + - (define_int_iterator HADDSUB [UNSPEC_SHADD UNSPEC_UHADD - UNSPEC_SRHADD UNSPEC_URHADD - UNSPEC_SHSUB UNSPEC_UHSUB -@@ -675,7 +736,7 @@ - (define_int_iterator ADDSUBHN2 [UNSPEC_ADDHN2 UNSPEC_RADDHN2 - UNSPEC_SUBHN2 UNSPEC_RSUBHN2]) - --(define_int_iterator FMAXMIN [UNSPEC_FMAX UNSPEC_FMIN]) -+(define_int_iterator FMAXMIN_UNS [UNSPEC_FMAX UNSPEC_FMIN]) - - (define_int_iterator VQDMULH [UNSPEC_SQDMULH UNSPEC_SQRDMULH]) - -@@ -711,25 +772,46 @@ - UNSPEC_UZP1 UNSPEC_UZP2]) - - (define_int_iterator FRINT [UNSPEC_FRINTZ UNSPEC_FRINTP UNSPEC_FRINTM -- UNSPEC_FRINTI UNSPEC_FRINTX UNSPEC_FRINTA]) -+ UNSPEC_FRINTN UNSPEC_FRINTI UNSPEC_FRINTX -+ UNSPEC_FRINTA]) - - (define_int_iterator FCVT [UNSPEC_FRINTZ UNSPEC_FRINTP UNSPEC_FRINTM -- UNSPEC_FRINTA]) -+ UNSPEC_FRINTA UNSPEC_FRINTN]) - -+(define_int_iterator FRECP [UNSPEC_FRECPE UNSPEC_FRECPX]) ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcvtm_u32_f32 (float32x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x2_t) __builtin_aarch64_lflooruv2sfv2si (__a); ++} + -+(define_int_iterator CRYPTO_AES [UNSPEC_AESE UNSPEC_AESD]) -+(define_int_iterator CRYPTO_AESMC [UNSPEC_AESMC UNSPEC_AESIMC]) ++__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) ++vcvtmq_s32_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_lfloorv4sfv4si (__a); ++} + -+(define_int_iterator CRYPTO_SHA1 [UNSPEC_SHA1C UNSPEC_SHA1M UNSPEC_SHA1P]) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcvtmq_u32_f32 (float32x4_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x4_t) __builtin_aarch64_lflooruv4sfv4si (__a); ++} + -+(define_int_iterator CRYPTO_SHA256 [UNSPEC_SHA256H UNSPEC_SHA256H2]) ++__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) ++vcvtmq_s64_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_lfloorv2dfv2di (__a); ++} + - ;; ------------------------------------------------------------------- - ;; Int Iterators Attributes. - ;; ------------------------------------------------------------------- --(define_int_attr maxminv [(UNSPEC_UMAXV "umax") -- (UNSPEC_UMINV "umin") -- (UNSPEC_SMAXV "smax") -- (UNSPEC_SMINV "smin")]) -+(define_int_attr maxmin_uns [(UNSPEC_UMAXV "umax") -+ (UNSPEC_UMINV "umin") -+ (UNSPEC_SMAXV "smax") -+ (UNSPEC_SMINV "smin") -+ (UNSPEC_FMAX "smax_nan") -+ (UNSPEC_FMAXNMV "smax") -+ (UNSPEC_FMAXV "smax_nan") -+ (UNSPEC_FMIN "smin_nan") -+ (UNSPEC_FMINNMV "smin") -+ (UNSPEC_FMINV "smin_nan")]) - --(define_int_attr fmaxminv [(UNSPEC_FMAXV "max") -- (UNSPEC_FMINV "min")]) -+(define_int_attr maxmin_uns_op [(UNSPEC_UMAXV "umax") -+ (UNSPEC_UMINV "umin") -+ (UNSPEC_SMAXV "smax") -+ (UNSPEC_SMINV "smin") -+ (UNSPEC_FMAX "fmax") -+ (UNSPEC_FMAXNMV "fmaxnm") -+ (UNSPEC_FMAXV "fmax") -+ (UNSPEC_FMIN "fmin") -+ (UNSPEC_FMINNMV "fminnm") -+ (UNSPEC_FMINV "fmin")]) - --(define_int_attr fmaxmin [(UNSPEC_FMAX "fmax") -- (UNSPEC_FMIN "fmin")]) -- - (define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u") - (UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur") - (UNSPEC_SHSUB "s") (UNSPEC_UHSUB "u") -@@ -740,6 +822,7 @@ - (UNSPEC_SUBHN2 "") (UNSPEC_RSUBHN2 "r") - (UNSPEC_SQXTN "s") (UNSPEC_UQXTN "u") - (UNSPEC_USQADD "us") (UNSPEC_SUQADD "su") -+ (UNSPEC_SADDV "s") (UNSPEC_UADDV "u") - (UNSPEC_SSLI "s") (UNSPEC_USLI "u") - (UNSPEC_SSRI "s") (UNSPEC_USRI "u") - (UNSPEC_USRA "u") (UNSPEC_SSRA "s") -@@ -798,15 +881,18 @@ - (UNSPEC_FRINTM "floor") - (UNSPEC_FRINTI "nearbyint") - (UNSPEC_FRINTX "rint") -- (UNSPEC_FRINTA "round")]) -+ (UNSPEC_FRINTA "round") -+ (UNSPEC_FRINTN "frintn")]) - - ;; frint suffix for floating-point rounding instructions. - (define_int_attr frint_suffix [(UNSPEC_FRINTZ "z") (UNSPEC_FRINTP "p") - (UNSPEC_FRINTM "m") (UNSPEC_FRINTI "i") -- (UNSPEC_FRINTX "x") (UNSPEC_FRINTA "a")]) -+ (UNSPEC_FRINTX "x") (UNSPEC_FRINTA "a") -+ (UNSPEC_FRINTN "n")]) - - (define_int_attr fcvt_pattern [(UNSPEC_FRINTZ "btrunc") (UNSPEC_FRINTA "round") -- (UNSPEC_FRINTP "ceil") (UNSPEC_FRINTM "floor")]) -+ (UNSPEC_FRINTP "ceil") (UNSPEC_FRINTM "floor") -+ (UNSPEC_FRINTN "frintn")]) - - (define_int_attr perm_insn [(UNSPEC_ZIP1 "zip") (UNSPEC_ZIP2 "zip") - (UNSPEC_TRN1 "trn") (UNSPEC_TRN2 "trn") -@@ -815,3 +901,13 @@ - (define_int_attr perm_hilo [(UNSPEC_ZIP1 "1") (UNSPEC_ZIP2 "2") - (UNSPEC_TRN1 "1") (UNSPEC_TRN2 "2") - (UNSPEC_UZP1 "1") (UNSPEC_UZP2 "2")]) ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcvtmq_u64_f64 (float64x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint64x2_t) __builtin_aarch64_lflooruv2dfv2di (__a); ++} + -+(define_int_attr frecp_suffix [(UNSPEC_FRECPE "e") (UNSPEC_FRECPX "x")]) ++/* vcvtn */ + -+(define_int_attr aes_op [(UNSPEC_AESE "e") (UNSPEC_AESD "d")]) -+(define_int_attr aesmc_op [(UNSPEC_AESMC "mc") (UNSPEC_AESIMC "imc")]) ++__extension__ static __inline int64_t __attribute__ ((__always_inline__)) ++vcvtnd_s64_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_lfrintndfdi (__a); ++} ++ ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcvtnd_u64_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_lfrintnudfdi (__a); ++} + -+(define_int_attr sha1_op [(UNSPEC_SHA1C "c") (UNSPEC_SHA1P "p") -+ (UNSPEC_SHA1M "m")]) ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vcvtns_s32_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_lfrintnsfsi (__a); ++} + -+(define_int_attr sha256_op [(UNSPEC_SHA256H "") (UNSPEC_SHA256H2 "2")]) ---- a/src/gcc/config/aarch64/aarch64.h -+++ b/src/gcc/config/aarch64/aarch64.h -@@ -49,6 +49,8 @@ - break; \ - } \ - \ -+ if (TARGET_CRYPTO) \ -+ builtin_define ("__ARM_FEATURE_CRYPTO"); \ - } while (0) - - -@@ -151,6 +153,7 @@ - #define AARCH64_FL_FP (1 << 1) /* Has FP. */ - #define AARCH64_FL_CRYPTO (1 << 2) /* Has crypto. */ - #define AARCH64_FL_SLOWMUL (1 << 3) /* A slow multiply core. */ -+#define AARCH64_FL_CRC (1 << 4) /* Has CRC. */ - - /* Has FP and SIMD. */ - #define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD) -@@ -163,6 +166,7 @@ - - /* Macros to test ISA flags. */ - extern unsigned long aarch64_isa_flags; -+#define AARCH64_ISA_CRC (aarch64_isa_flags & AARCH64_FL_CRC) - #define AARCH64_ISA_CRYPTO (aarch64_isa_flags & AARCH64_FL_CRYPTO) - #define AARCH64_ISA_FP (aarch64_isa_flags & AARCH64_FL_FP) - #define AARCH64_ISA_SIMD (aarch64_isa_flags & AARCH64_FL_SIMD) -@@ -171,6 +175,8 @@ - extern unsigned long aarch64_tune_flags; - #define AARCH64_TUNE_SLOWMUL (aarch64_tune_flags & AARCH64_FL_SLOWMUL) - -+/* Crypto is an optional feature. */ -+#define TARGET_CRYPTO AARCH64_ISA_CRYPTO - - /* Standard register usage. */ - -@@ -434,7 +440,7 @@ - #define INDEX_REG_CLASS CORE_REGS - #define BASE_REG_CLASS POINTER_REGS - --/* Register pairs used to eliminate unneeded registers that point intoi -+/* Register pairs used to eliminate unneeded registers that point into - the stack frame. */ - #define ELIMINABLE_REGS \ - { \ -@@ -475,7 +481,7 @@ - /* Stack layout; function entry, exit and calling. */ - #define STACK_GROWS_DOWNWARD 1 - --#define FRAME_GROWS_DOWNWARD 0 -+#define FRAME_GROWS_DOWNWARD 1 - - #define STARTING_FRAME_OFFSET 0 - -@@ -521,12 +527,6 @@ - #endif - - --/* Which ABI to use. */ --enum arm_abi_type --{ -- ARM_ABI_AAPCS64 --}; -- - enum arm_pcs - { - ARM_PCS_AAPCS64, /* Base standard AAPCS for 64 bit. */ -@@ -534,11 +534,7 @@ - }; - - --extern enum arm_abi_type arm_abi; - extern enum arm_pcs arm_pcs_variant; --#ifndef ARM_DEFAULT_ABI --#define ARM_DEFAULT_ABI ARM_ABI_AAPCS64 --#endif - - #ifndef ARM_DEFAULT_PCS - #define ARM_DEFAULT_PCS ARM_PCS_AAPCS64 -@@ -709,6 +705,8 @@ - - #define SELECT_CC_MODE(OP, X, Y) aarch64_select_cc_mode (OP, X, Y) - -+#define REVERSIBLE_CC_MODE(MODE) 1 ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcvtns_u32_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_lfrintnusfsi (__a); ++} + - #define REVERSE_CONDITION(CODE, MODE) \ - (((MODE) == CCFPmode || (MODE) == CCFPEmode) \ - ? reverse_condition_maybe_unordered (CODE) \ -@@ -758,9 +756,23 @@ - #define PRINT_OPERAND_ADDRESS(STREAM, X) \ - aarch64_print_operand_address (STREAM, X) - --#define FUNCTION_PROFILER(STREAM, LABELNO) \ -- aarch64_function_profiler (STREAM, LABELNO) -+#define MCOUNT_NAME "_mcount" - -+#define NO_PROFILE_COUNTERS 1 ++__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) ++vcvtn_s32_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_lfrintnv2sfv2si (__a); ++} + -+/* Emit rtl for profiling. Output assembler code to FILE -+ to call "_mcount" for profiling a function entry. */ -+#define PROFILE_HOOK(LABEL) \ -+{ \ -+ rtx fun,lr; \ -+ lr = get_hard_reg_initial_val (Pmode, LR_REGNUM); \ -+ fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \ -+ emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lr, Pmode); \ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcvtn_u32_f32 (float32x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x2_t) __builtin_aarch64_lfrintnuv2sfv2si (__a); +} + -+/* All the work done in PROFILE_HOOK, but still required. */ -+#define FUNCTION_PROFILER(STREAM, LABELNO) do { } while (0) ++__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) ++vcvtnq_s32_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_lfrintnv4sfv4si (__a); ++} + - /* For some reason, the Linux headers think they know how to define - these macros. They don't!!! */ - #undef ASM_APP_ON ---- a/src/gcc/config/arm/arm1020e.md -+++ b/src/gcc/config/arm/arm1020e.md -@@ -66,13 +66,14 @@ - ;; ALU operations with no shifted operand - (define_insn_reservation "1020alu_op" 1 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "type" "alu_reg,simple_alu_imm")) -+ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ -+ mov_imm,mov_reg,mvn_imm,mvn_reg")) - "1020a_e,1020a_m,1020a_w") - - ;; ALU operations with a shift-by-constant operand - (define_insn_reservation "1020alu_shift_op" 1 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "type" "simple_alu_shift,alu_shift")) -+ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) - "1020a_e,1020a_m,1020a_w") - - ;; ALU operations with a shift-by-register operand -@@ -81,7 +82,7 @@ - ;; the execute stage. - (define_insn_reservation "1020alu_shift_reg_op" 2 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "type" "alu_shift_reg")) -+ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) - "1020a_e*2,1020a_m,1020a_w") - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@@ -96,7 +97,7 @@ - ;; until after the memory stage. - (define_insn_reservation "1020mult1" 2 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "insn" "smulxy,smulwy")) -+ (eq_attr "type" "smulxy,smulwy")) - "1020a_e,1020a_m,1020a_w") - - ;; The "smlaxy" and "smlawx" instructions require two iterations through -@@ -104,7 +105,7 @@ - ;; the execute stage. - (define_insn_reservation "1020mult2" 2 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "insn" "smlaxy,smlalxy,smlawx")) -+ (eq_attr "type" "smlaxy,smlalxy,smlawx")) - "1020a_e*2,1020a_m,1020a_w") - - ;; The "smlalxy", "mul", and "mla" instructions require two iterations -@@ -112,7 +113,7 @@ - ;; the memory stage. - (define_insn_reservation "1020mult3" 3 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "insn" "smlalxy,mul,mla")) -+ (eq_attr "type" "smlalxy,mul,mla")) - "1020a_e*2,1020a_m,1020a_w") - - ;; The "muls" and "mlas" instructions loop in the execute stage for -@@ -120,7 +121,7 @@ - ;; available after three iterations. - (define_insn_reservation "1020mult4" 3 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "insn" "muls,mlas")) -+ (eq_attr "type" "muls,mlas")) - "1020a_e*4,1020a_m,1020a_w") - - ;; Long multiply instructions that produce two registers of -@@ -135,7 +136,7 @@ - ;; available after the memory cycle. - (define_insn_reservation "1020mult5" 4 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "insn" "umull,umlal,smull,smlal")) -+ (eq_attr "type" "umull,umlal,smull,smlal")) - "1020a_e*3,1020a_m,1020a_w") - - ;; The "umulls", "umlals", "smulls", and "smlals" instructions loop in -@@ -143,7 +144,7 @@ - ;; The value result is available after four iterations. - (define_insn_reservation "1020mult6" 4 - (and (eq_attr "tune" "arm1020e,arm1022e") -- (eq_attr "insn" "umulls,umlals,smulls,smlals")) -+ (eq_attr "type" "umulls,umlals,smulls,smlals")) - "1020a_e*5,1020a_m,1020a_w") - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ---- a/src/gcc/config/arm/cortex-a15.md -+++ b/src/gcc/config/arm/cortex-a15.md -@@ -61,7 +61,9 @@ - ;; Simple ALU without shift - (define_insn_reservation "cortex_a15_alu" 2 - (and (eq_attr "tune" "cortexa15") -- (and (eq_attr "type" "alu_reg,simple_alu_imm") -+ (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ -+ mov_imm,mov_reg,\ -+ mvn_imm,mvn_reg") - (eq_attr "neon_type" "none"))) - "ca15_issue1,(ca15_sx1,ca15_sx1_alu)|(ca15_sx2,ca15_sx2_alu)") - -@@ -68,7 +70,7 @@ - ;; ALU ops with immediate shift - (define_insn_reservation "cortex_a15_alu_shift" 3 - (and (eq_attr "tune" "cortexa15") -- (and (eq_attr "type" "simple_alu_shift,alu_shift") -+ (and (eq_attr "type" "extend,arlo_shift,,mov_shift,mvn_shift") - (eq_attr "neon_type" "none"))) - "ca15_issue1,(ca15_sx1,ca15_sx1+ca15_sx1_shf,ca15_sx1_alu)\ - |(ca15_sx2,ca15_sx2+ca15_sx2_shf,ca15_sx2_alu)") -@@ -76,7 +78,7 @@ - ;; ALU ops with register controlled shift - (define_insn_reservation "cortex_a15_alu_shift_reg" 3 - (and (eq_attr "tune" "cortexa15") -- (and (eq_attr "type" "alu_shift_reg") -+ (and (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg") - (eq_attr "neon_type" "none"))) - "(ca15_issue2,ca15_sx1+ca15_sx2,ca15_sx1_shf,ca15_sx2_alu)\ - |(ca15_issue1,(ca15_issue1+ca15_sx2,ca15_sx1+ca15_sx2_shf)\ -@@ -87,28 +89,26 @@ - ;; 32-bit multiplies - (define_insn_reservation "cortex_a15_mult32" 3 - (and (eq_attr "tune" "cortexa15") -- (and (eq_attr "type" "mult") -- (and (eq_attr "neon_type" "none") -- (eq_attr "mul64" "no")))) -+ (and (eq_attr "mul32" "yes") -+ (eq_attr "neon_type" "none"))) - "ca15_issue1,ca15_mx") - - ;; 64-bit multiplies - (define_insn_reservation "cortex_a15_mult64" 4 - (and (eq_attr "tune" "cortexa15") -- (and (eq_attr "type" "mult") -- (and (eq_attr "neon_type" "none") -- (eq_attr "mul64" "yes")))) -+ (and (eq_attr "mul64" "yes") -+ (eq_attr "neon_type" "none"))) - "ca15_issue1,ca15_mx*2") - - ;; Integer divide - (define_insn_reservation "cortex_a15_udiv" 9 - (and (eq_attr "tune" "cortexa15") -- (eq_attr "insn" "udiv")) -+ (eq_attr "type" "udiv")) - "ca15_issue1,ca15_mx") - - (define_insn_reservation "cortex_a15_sdiv" 10 - (and (eq_attr "tune" "cortexa15") -- (eq_attr "insn" "sdiv")) -+ (eq_attr "type" "sdiv")) - "ca15_issue1,ca15_mx") - - ;; Block all issue pipes for a cycle ---- a/src/gcc/config/arm/arm-tables.opt -+++ b/src/gcc/config/arm/arm-tables.opt -@@ -250,6 +250,9 @@ - Enum(processor_type) String(cortex-a15) Value(cortexa15) - - EnumValue -+Enum(processor_type) String(cortex-a53) Value(cortexa53) ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcvtnq_u32_f32 (float32x4_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x4_t) __builtin_aarch64_lfrintnuv4sfv4si (__a); ++} + -+EnumValue - Enum(processor_type) String(cortex-r4) Value(cortexr4) - - EnumValue -@@ -259,6 +262,9 @@ - Enum(processor_type) String(cortex-r5) Value(cortexr5) - - EnumValue -+Enum(processor_type) String(cortex-r7) Value(cortexr7) ++__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) ++vcvtnq_s64_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_lfrintnv2dfv2di (__a); ++} + -+EnumValue - Enum(processor_type) String(cortex-m4) Value(cortexm4) - - EnumValue -@@ -353,11 +359,14 @@ - Enum(arm_arch) String(armv8-a) Value(23) - - EnumValue --Enum(arm_arch) String(iwmmxt) Value(24) -+Enum(arm_arch) String(armv8-a+crc) Value(24) - - EnumValue --Enum(arm_arch) String(iwmmxt2) Value(25) -+Enum(arm_arch) String(iwmmxt) Value(25) - -+EnumValue -+Enum(arm_arch) String(iwmmxt2) Value(26) ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcvtnq_u64_f64 (float64x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint64x2_t) __builtin_aarch64_lfrintnuv2dfv2di (__a); ++} + - Enum - Name(arm_fpu) Type(int) - Known ARM FPUs (for use with the -mfpu= option): ---- a/src/gcc/config/arm/arm1026ejs.md -+++ b/src/gcc/config/arm/arm1026ejs.md -@@ -66,13 +66,14 @@ - ;; ALU operations with no shifted operand - (define_insn_reservation "alu_op" 1 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "type" "alu_reg,simple_alu_imm")) -+ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ -+ mov_imm,mov_reg,mvn_imm,mvn_reg")) - "a_e,a_m,a_w") - - ;; ALU operations with a shift-by-constant operand - (define_insn_reservation "alu_shift_op" 1 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "type" "simple_alu_shift,alu_shift")) -+ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) - "a_e,a_m,a_w") - - ;; ALU operations with a shift-by-register operand -@@ -81,7 +82,7 @@ - ;; the execute stage. - (define_insn_reservation "alu_shift_reg_op" 2 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "type" "alu_shift_reg")) -+ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) - "a_e*2,a_m,a_w") - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@@ -96,7 +97,7 @@ - ;; until after the memory stage. - (define_insn_reservation "mult1" 2 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "insn" "smulxy,smulwy")) -+ (eq_attr "type" "smulxy,smulwy")) - "a_e,a_m,a_w") - - ;; The "smlaxy" and "smlawx" instructions require two iterations through -@@ -104,7 +105,7 @@ - ;; the execute stage. - (define_insn_reservation "mult2" 2 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "insn" "smlaxy,smlalxy,smlawx")) -+ (eq_attr "type" "smlaxy,smlalxy,smlawx")) - "a_e*2,a_m,a_w") - - ;; The "smlalxy", "mul", and "mla" instructions require two iterations -@@ -112,7 +113,7 @@ - ;; the memory stage. - (define_insn_reservation "mult3" 3 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "insn" "smlalxy,mul,mla")) -+ (eq_attr "type" "smlalxy,mul,mla")) - "a_e*2,a_m,a_w") - - ;; The "muls" and "mlas" instructions loop in the execute stage for -@@ -120,7 +121,7 @@ - ;; available after three iterations. - (define_insn_reservation "mult4" 3 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "insn" "muls,mlas")) -+ (eq_attr "type" "muls,mlas")) - "a_e*4,a_m,a_w") - - ;; Long multiply instructions that produce two registers of -@@ -135,7 +136,7 @@ - ;; available after the memory cycle. - (define_insn_reservation "mult5" 4 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "insn" "umull,umlal,smull,smlal")) -+ (eq_attr "type" "umull,umlal,smull,smlal")) - "a_e*3,a_m,a_w") - - ;; The "umulls", "umlals", "smulls", and "smlals" instructions loop in -@@ -143,7 +144,7 @@ - ;; The value result is available after four iterations. - (define_insn_reservation "mult6" 4 - (and (eq_attr "tune" "arm1026ejs") -- (eq_attr "insn" "umulls,umlals,smulls,smlals")) -+ (eq_attr "type" "umulls,umlals,smulls,smlals")) - "a_e*5,a_m,a_w") - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ---- a/src/gcc/config/arm/linux-elf.h -+++ b/src/gcc/config/arm/linux-elf.h -@@ -44,9 +44,9 @@ - - #define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p" - -+/* We do not have any MULTILIB_OPTIONS specified, so there are no -+ MULTILIB_DEFAULTS. */ - #undef MULTILIB_DEFAULTS --#define MULTILIB_DEFAULTS \ -- { "marm", "mlittle-endian", "mfloat-abi=hard", "mno-thumb-interwork" } - - /* Now we define the strings used to build the spec file. */ - #undef LIB_SPEC ---- a/src/gcc/config/arm/arm1136jfs.md -+++ b/src/gcc/config/arm/arm1136jfs.md -@@ -75,13 +75,14 @@ - ;; ALU operations with no shifted operand - (define_insn_reservation "11_alu_op" 2 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "type" "alu_reg,simple_alu_imm")) -+ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ -+ mov_imm,mov_reg,mvn_imm,mvn_reg")) - "e_1,e_2,e_3,e_wb") - - ;; ALU operations with a shift-by-constant operand - (define_insn_reservation "11_alu_shift_op" 2 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "type" "simple_alu_shift,alu_shift")) -+ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) - "e_1,e_2,e_3,e_wb") - - ;; ALU operations with a shift-by-register operand -@@ -90,7 +91,7 @@ - ;; the shift stage. - (define_insn_reservation "11_alu_shift_reg_op" 3 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "type" "alu_shift_reg")) -+ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) - "e_1*2,e_2,e_3,e_wb") - - ;; alu_ops can start sooner, if there is no shifter dependency -@@ -129,13 +130,13 @@ - ;; Multiply and multiply-accumulate results are available after four stages. - (define_insn_reservation "11_mult1" 4 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "insn" "mul,mla")) -+ (eq_attr "type" "mul,mla")) - "e_1*2,e_2,e_3,e_wb") - - ;; The *S variants set the condition flags, which requires three more cycles. - (define_insn_reservation "11_mult2" 4 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "insn" "muls,mlas")) -+ (eq_attr "type" "muls,mlas")) - "e_1*2,e_2,e_3,e_wb") - - (define_bypass 3 "11_mult1,11_mult2" -@@ -160,13 +161,13 @@ - ;; the two multiply-accumulate instructions. - (define_insn_reservation "11_mult3" 5 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "insn" "smull,umull,smlal,umlal")) -+ (eq_attr "type" "smull,umull,smlal,umlal")) - "e_1*3,e_2,e_3,e_wb*2") - - ;; The *S variants set the condition flags, which requires three more cycles. - (define_insn_reservation "11_mult4" 5 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "insn" "smulls,umulls,smlals,umlals")) -+ (eq_attr "type" "smulls,umulls,smlals,umlals")) - "e_1*3,e_2,e_3,e_wb*2") - - (define_bypass 4 "11_mult3,11_mult4" -@@ -190,7 +191,8 @@ - ;; cycles. - (define_insn_reservation "11_mult5" 3 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "insn" "smulxy,smlaxy,smulwy,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx")) -+ (eq_attr "type" "smulxy,smlaxy,smulwy,smlawy,smuad,smuadx,smlad,smladx,\ -+ smusd,smusdx,smlsd,smlsdx")) - "e_1,e_2,e_3,e_wb") - - (define_bypass 2 "11_mult5" -@@ -211,7 +213,7 @@ - ;; The same idea, then the 32-bit result is added to a 64-bit quantity. - (define_insn_reservation "11_mult6" 4 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "insn" "smlalxy")) -+ (eq_attr "type" "smlalxy")) - "e_1*2,e_2,e_3,e_wb*2") - - ;; Signed 32x32 multiply, then the most significant 32 bits are extracted -@@ -218,7 +220,7 @@ - ;; and are available after the memory stage. - (define_insn_reservation "11_mult7" 4 - (and (eq_attr "tune" "arm1136js,arm1136jfs") -- (eq_attr "insn" "smmul,smmulr")) -+ (eq_attr "type" "smmul,smmulr")) - "e_1*2,e_2,e_3,e_wb") - - (define_bypass 3 "11_mult6,11_mult7" ---- a/src/gcc/config/arm/marvell-pj4.md -+++ b/src/gcc/config/arm/marvell-pj4.md -@@ -41,41 +41,39 @@ - - (define_insn_reservation "pj4_alu_e1" 1 - (and (eq_attr "tune" "marvell_pj4") -- (eq_attr "type" "simple_alu_imm,alu_reg") -- (not (eq_attr "conds" "set")) -- (eq_attr "insn" "mov,mvn")) -+ (eq_attr "type" "mov_imm,mov_reg,mvn_imm,mvn_reg") -+ (not (eq_attr "conds" "set"))) - "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") - - (define_insn_reservation "pj4_alu_e1_conds" 4 - (and (eq_attr "tune" "marvell_pj4") -- (eq_attr "type" "simple_alu_imm,alu_reg") -- (eq_attr "conds" "set") -- (eq_attr "insn" "mov,mvn")) -+ (eq_attr "type" "mov_imm,mov_reg,mvn_imm,mvn_reg") -+ (eq_attr "conds" "set")) - "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") - - (define_insn_reservation "pj4_alu" 1 - (and (eq_attr "tune" "marvell_pj4") -- (eq_attr "type" "simple_alu_imm,alu_reg") -- (not (eq_attr "conds" "set")) -- (not (eq_attr "insn" "mov,mvn"))) -+ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") -+ (not (eq_attr "conds" "set"))) - "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") - - (define_insn_reservation "pj4_alu_conds" 4 - (and (eq_attr "tune" "marvell_pj4") -- (eq_attr "type" "simple_alu_imm,alu_reg") -- (eq_attr "conds" "set") -- (not (eq_attr "insn" "mov,mvn"))) -+ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") -+ (eq_attr "conds" "set")) - "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") - - (define_insn_reservation "pj4_shift" 1 - (and (eq_attr "tune" "marvell_pj4") -- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift") -+ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ -+ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg") - (not (eq_attr "conds" "set")) - (eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") - - (define_insn_reservation "pj4_shift_conds" 4 - (and (eq_attr "tune" "marvell_pj4") -- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift") -+ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ -+ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg") - (eq_attr "conds" "set") - (eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") - -@@ -82,13 +80,15 @@ - (define_insn_reservation "pj4_alu_shift" 1 - (and (eq_attr "tune" "marvell_pj4") - (not (eq_attr "conds" "set")) -- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift")) -+ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ -+ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")) - "pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)") - - (define_insn_reservation "pj4_alu_shift_conds" 4 - (and (eq_attr "tune" "marvell_pj4") - (eq_attr "conds" "set") -- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift")) -+ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ -+ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")) - "pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)") - - (define_bypass 2 "pj4_alu_shift,pj4_shift" -@@ -95,10 +95,14 @@ - "pj4_ir_mul,pj4_ir_div,pj4_core_to_vfp") ++/* vcvtp */ ++ ++__extension__ static __inline int64_t __attribute__ ((__always_inline__)) ++vcvtpd_s64_f64 (float64_t __a) ++{ ++ return __builtin_lceil (__a); ++} ++ ++__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) ++vcvtpd_u64_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_lceiludfdi (__a); ++} ++ ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vcvtps_s32_f32 (float32_t __a) ++{ ++ return __builtin_iceilf (__a); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vcvtps_u32_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_lceilusfsi (__a); ++} ++ ++__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) ++vcvtp_s32_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_lceilv2sfv2si (__a); ++} ++ ++__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) ++vcvtp_u32_f32 (float32x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x2_t) __builtin_aarch64_lceiluv2sfv2si (__a); ++} ++ ++__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) ++vcvtpq_s32_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_lceilv4sfv4si (__a); ++} ++ ++__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) ++vcvtpq_u32_f32 (float32x4_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint32x4_t) __builtin_aarch64_lceiluv4sfv4si (__a); ++} ++ ++__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) ++vcvtpq_s64_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_lceilv2dfv2di (__a); ++} ++ ++__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) ++vcvtpq_u64_f64 (float64x2_t __a) ++{ ++ /* TODO: This cast should go away when builtins have ++ their correct types. */ ++ return (uint64x2_t) __builtin_aarch64_lceiluv2dfv2di (__a); ++} ++ + /* vdup */ - (define_insn_reservation "pj4_ir_mul" 3 -- (and (eq_attr "tune" "marvell_pj4") (eq_attr "type" "mult")) "pj4_is,pj4_mul,nothing*2,pj4_cp") -+ (and (eq_attr "tune" "marvell_pj4") -+ (ior (eq_attr "mul32" "yes") -+ (eq_attr "mul64" "yes"))) -+ "pj4_is,pj4_mul,nothing*2,pj4_cp") + __extension__ static __inline int8x1_t __attribute__ ((__always_inline__)) + vdupb_lane_s8 (int8x16_t a, int const b) + { +- return __builtin_aarch64_dup_laneqi (a, b); ++ return __aarch64_vgetq_lane_s8 (a, b); + } - (define_insn_reservation "pj4_ir_div" 20 -- (and (eq_attr "tune" "marvell_pj4") (eq_attr "insn" "udiv,sdiv")) "pj4_is,pj4_div*19,pj4_cp") -+ (and (eq_attr "tune" "marvell_pj4") -+ (eq_attr "type" "udiv,sdiv")) "pj4_is,pj4_div*19,pj4_cp") + __extension__ static __inline uint8x1_t __attribute__ ((__always_inline__)) + vdupb_lane_u8 (uint8x16_t a, int const b) + { +- return (uint8x1_t) __builtin_aarch64_dup_laneqi ((int8x16_t) a, b); ++ return __aarch64_vgetq_lane_u8 (a, b); + } - ;; Branches and calls. + __extension__ static __inline int16x1_t __attribute__ ((__always_inline__)) + vduph_lane_s16 (int16x8_t a, int const b) + { +- return __builtin_aarch64_dup_lanehi (a, b); ++ return __aarch64_vgetq_lane_s16 (a, b); + } ---- a/src/gcc/config/arm/thumb2.md -+++ b/src/gcc/config/arm/thumb2.md -@@ -60,105 +60,230 @@ - "TARGET_THUMB2" - "bic%?\\t%0, %1, %2%S4" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "shift" "2") -- (set_attr "type" "alu_shift")] -+ (set_attr "type" "arlo_shift")] - ) + __extension__ static __inline uint16x1_t __attribute__ ((__always_inline__)) + vduph_lane_u16 (uint16x8_t a, int const b) + { +- return (uint16x1_t) __builtin_aarch64_dup_lanehi ((int16x8_t) a, b); ++ return __aarch64_vgetq_lane_u16 (a, b); + } --(define_insn "*thumb2_smaxsi3" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") -- (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") -- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) -+;; We use the '0' constraint for operand 1 because reload should -+;; be smart enough to generate an appropriate move for the r/r/r case. -+(define_insn_and_split "*thumb2_smaxsi3" -+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") -+ (smax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") -+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) - (clobber (reg:CC CC_REGNUM))] -- "TARGET_THUMB2" -- "@ -- cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2 -- cmp\\t%1, %2\;it\\tge\;movge\\t%0, %1 -- cmp\\t%1, %2\;ite\\tge\;movge\\t%0, %1\;movlt\\t%0, %2" -+ "TARGET_THUMB2" -+ "#" -+ ; cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2 -+ "TARGET_THUMB2 && reload_completed" -+ [(set (reg:CC CC_REGNUM) -+ (compare:CC (match_dup 1) (match_dup 2))) -+ (cond_exec (lt:SI (reg:CC CC_REGNUM) (const_int 0)) -+ (set (match_dup 0) -+ (match_dup 2)))] -+ "" - [(set_attr "conds" "clob") -- (set_attr "length" "10,10,14")] -+ (set_attr "enabled_for_depr_it" "yes,yes,no") -+ (set_attr "length" "6,6,10")] - ) + __extension__ static __inline int32x1_t __attribute__ ((__always_inline__)) + vdups_lane_s32 (int32x4_t a, int const b) + { +- return __builtin_aarch64_dup_lanesi (a, b); ++ return __aarch64_vgetq_lane_s32 (a, b); + } --(define_insn "*thumb2_sminsi3" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") -- (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") -- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) -+(define_insn_and_split "*thumb2_sminsi3" -+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") -+ (smin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") -+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" -- "@ -- cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2 -- cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %1 -- cmp\\t%1, %2\;ite\\tlt\;movlt\\t%0, %1\;movge\\t%0, %2" -+ "#" -+ ; cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2 -+ "TARGET_THUMB2 && reload_completed" -+ [(set (reg:CC CC_REGNUM) -+ (compare:CC (match_dup 1) (match_dup 2))) -+ (cond_exec (ge:SI (reg:CC CC_REGNUM) (const_int 0)) -+ (set (match_dup 0) -+ (match_dup 2)))] -+ "" - [(set_attr "conds" "clob") -- (set_attr "length" "10,10,14")] -+ (set_attr "enabled_for_depr_it" "yes,yes,no") -+ (set_attr "length" "6,6,10")] - ) + __extension__ static __inline uint32x1_t __attribute__ ((__always_inline__)) + vdups_lane_u32 (uint32x4_t a, int const b) + { +- return (uint32x1_t) __builtin_aarch64_dup_lanesi ((int32x4_t) a, b); ++ return __aarch64_vgetq_lane_u32 (a, b); + } --(define_insn "*thumb32_umaxsi3" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") -- (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") -- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) -- (clobber (reg:CC CC_REGNUM))] -+(define_insn_and_split "*thumb32_umaxsi3" -+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") -+ (umax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") -+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) -+ (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" -- "@ -- cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2 -- cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %1 -- cmp\\t%1, %2\;ite\\tcs\;movcs\\t%0, %1\;movcc\\t%0, %2" -+ "#" -+ ; cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2 -+ "TARGET_THUMB2 && reload_completed" -+ [(set (reg:CC CC_REGNUM) -+ (compare:CC (match_dup 1) (match_dup 2))) -+ (cond_exec (ltu:SI (reg:CC CC_REGNUM) (const_int 0)) -+ (set (match_dup 0) -+ (match_dup 2)))] -+ "" - [(set_attr "conds" "clob") -- (set_attr "length" "10,10,14")] -+ (set_attr "length" "6,6,10") -+ (set_attr "enabled_for_depr_it" "yes,yes,no")] - ) + __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) + vdupd_lane_s64 (int64x2_t a, int const b) + { +- return __builtin_aarch64_dup_lanedi (a, b); ++ return __aarch64_vgetq_lane_s64 (a, b); + } --(define_insn "*thumb2_uminsi3" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") -- (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") -- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) -+(define_insn_and_split "*thumb2_uminsi3" -+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") -+ (umin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") -+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" -- "@ -- cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2 -- cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %1 -- cmp\\t%1, %2\;ite\\tcc\;movcc\\t%0, %1\;movcs\\t%0, %2" -+ "#" -+ ; cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2 -+ "TARGET_THUMB2 && reload_completed" -+ [(set (reg:CC CC_REGNUM) -+ (compare:CC (match_dup 1) (match_dup 2))) -+ (cond_exec (geu:SI (reg:CC CC_REGNUM) (const_int 0)) -+ (set (match_dup 0) -+ (match_dup 2)))] -+ "" - [(set_attr "conds" "clob") -- (set_attr "length" "10,10,14")] -+ (set_attr "length" "6,6,10") -+ (set_attr "enabled_for_depr_it" "yes,yes,no")] - ) + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vdupd_lane_u64 (uint64x2_t a, int const b) + { +- return (uint64x1_t) __builtin_aarch64_dup_lanedi ((int64x2_t) a, b); ++ return __aarch64_vgetq_lane_u64 (a, b); + } - ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands. --(define_insn "*thumb2_negdi2" -+(define_insn_and_split "*thumb2_negdi2" - [(set (match_operand:DI 0 "s_register_operand" "=&r,r") - (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" -- "negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1" -+ "#" ; negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1 -+ "&& reload_completed" -+ [(parallel [(set (reg:CC CC_REGNUM) -+ (compare:CC (const_int 0) (match_dup 1))) -+ (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) -+ (set (match_dup 2) (minus:SI (minus:SI (match_dup 3) -+ (ashift:SI (match_dup 3) -+ (const_int 1))) -+ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] -+ { -+ operands[2] = gen_highpart (SImode, operands[0]); -+ operands[0] = gen_lowpart (SImode, operands[0]); -+ operands[3] = gen_highpart (SImode, operands[1]); -+ operands[1] = gen_lowpart (SImode, operands[1]); -+ } - [(set_attr "conds" "clob") - (set_attr "length" "8")] - ) + /* vld1 */ +@@ -21088,7 +20835,7 @@ + __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) + vmax_f32 (float32x2_t __a, float32x2_t __b) + { +- return __builtin_aarch64_fmaxv2sf (__a, __b); ++ return __builtin_aarch64_smax_nanv2sf (__a, __b); + } --(define_insn "*thumb2_abssi2" -- [(set (match_operand:SI 0 "s_register_operand" "=r,&r") -- (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) -+(define_insn_and_split "*thumb2_abssi2" -+ [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r") -+ (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" -- "@ -- cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0 -- eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31" -- [(set_attr "conds" "clob,*") -+ "#" -+ ; eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31 -+ ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0 -+ ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0 -+ "&& reload_completed" -+ [(const_int 0)] -+ { -+ if (REGNO(operands[0]) == REGNO(operands[1])) -+ { -+ rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) +@@ -21133,13 +20880,13 @@ + __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) + vmaxq_f32 (float32x4_t __a, float32x4_t __b) + { +- return __builtin_aarch64_fmaxv4sf (__a, __b); ++ return __builtin_aarch64_smax_nanv4sf (__a, __b); + } + + __extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) + vmaxq_f64 (float64x2_t __a, float64x2_t __b) + { +- return __builtin_aarch64_fmaxv2df (__a, __b); ++ return __builtin_aarch64_smax_nanv2df (__a, __b); + } + + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) +@@ -21181,12 +20928,150 @@ + (int32x4_t) __b); + } + +-/* vmin */ ++/* vmaxnm */ + + __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vmaxnm_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return __builtin_aarch64_smaxv2sf (__a, __b); ++} + -+ emit_insn (gen_rtx_SET (VOIDmode, -+ cc_reg, -+ gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, -+ (gen_rtx_LT (SImode, -+ cc_reg, -+ const0_rtx)), -+ (gen_rtx_SET (VOIDmode, -+ operands[0], -+ (gen_rtx_MINUS (SImode, -+ const0_rtx, -+ operands[1])))))); -+ } -+ else -+ { -+ emit_insn (gen_rtx_SET (VOIDmode, -+ operands[0], -+ gen_rtx_XOR (SImode, -+ gen_rtx_ASHIFTRT (SImode, -+ operands[1], -+ GEN_INT (31)), -+ operands[1]))); -+ emit_insn (gen_rtx_SET (VOIDmode, -+ operands[0], -+ gen_rtx_MINUS (SImode, -+ operands[0], -+ gen_rtx_ASHIFTRT (SImode, -+ operands[1], -+ GEN_INT (31))))); -+ } -+ DONE; -+ } -+ [(set_attr "conds" "*,clob,clob") - (set_attr "shift" "1") -- (set_attr "predicable" "no, yes") -+ (set_attr "predicable" "yes,no,no") -+ (set_attr "predicable_short_it" "no") -+ (set_attr "enabled_for_depr_it" "yes,yes,no") - (set_attr "ce_count" "2") -- (set_attr "length" "10,8")] -+ (set_attr "length" "8,6,10")] - ) ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vmaxnmq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return __builtin_aarch64_smaxv4sf (__a, __b); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vmaxnmq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return __builtin_aarch64_smaxv2df (__a, __b); ++} ++ ++/* vmaxv */ ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vmaxv_f32 (float32x2_t __a) ++{ ++ return vget_lane_f32 (__builtin_aarch64_reduc_smax_nan_v2sf (__a), 0); ++} ++ ++__extension__ static __inline int8_t __attribute__ ((__always_inline__)) ++vmaxv_s8 (int8x8_t __a) ++{ ++ return vget_lane_s8 (__builtin_aarch64_reduc_smax_v8qi (__a), 0); ++} ++ ++__extension__ static __inline int16_t __attribute__ ((__always_inline__)) ++vmaxv_s16 (int16x4_t __a) ++{ ++ return vget_lane_s16 (__builtin_aarch64_reduc_smax_v4hi (__a), 0); ++} ++ ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vmaxv_s32 (int32x2_t __a) ++{ ++ return vget_lane_s32 (__builtin_aarch64_reduc_smax_v2si (__a), 0); ++} ++ ++__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) ++vmaxv_u8 (uint8x8_t __a) ++{ ++ return vget_lane_u8 ((uint8x8_t) ++ __builtin_aarch64_reduc_umax_v8qi ((int8x8_t) __a), 0); ++} ++ ++__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) ++vmaxv_u16 (uint16x4_t __a) ++{ ++ return vget_lane_u16 ((uint16x4_t) ++ __builtin_aarch64_reduc_umax_v4hi ((int16x4_t) __a), 0); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vmaxv_u32 (uint32x2_t __a) ++{ ++ return vget_lane_u32 ((uint32x2_t) ++ __builtin_aarch64_reduc_umax_v2si ((int32x2_t) __a), 0); ++} ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vmaxvq_f32 (float32x4_t __a) ++{ ++ return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_nan_v4sf (__a), 0); ++} ++ ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vmaxvq_f64 (float64x2_t __a) ++{ ++ return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_nan_v2df (__a), 0); ++} ++ ++__extension__ static __inline int8_t __attribute__ ((__always_inline__)) ++vmaxvq_s8 (int8x16_t __a) ++{ ++ return vgetq_lane_s8 (__builtin_aarch64_reduc_smax_v16qi (__a), 0); ++} ++ ++__extension__ static __inline int16_t __attribute__ ((__always_inline__)) ++vmaxvq_s16 (int16x8_t __a) ++{ ++ return vgetq_lane_s16 (__builtin_aarch64_reduc_smax_v8hi (__a), 0); ++} ++ ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vmaxvq_s32 (int32x4_t __a) ++{ ++ return vgetq_lane_s32 (__builtin_aarch64_reduc_smax_v4si (__a), 0); ++} ++ ++__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) ++vmaxvq_u8 (uint8x16_t __a) ++{ ++ return vgetq_lane_u8 ((uint8x16_t) ++ __builtin_aarch64_reduc_umax_v16qi ((int8x16_t) __a), 0); ++} ++ ++__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) ++vmaxvq_u16 (uint16x8_t __a) ++{ ++ return vgetq_lane_u16 ((uint16x8_t) ++ __builtin_aarch64_reduc_umax_v8hi ((int16x8_t) __a), 0); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vmaxvq_u32 (uint32x4_t __a) ++{ ++ return vgetq_lane_u32 ((uint32x4_t) ++ __builtin_aarch64_reduc_umax_v4si ((int32x4_t) __a), 0); ++} ++ ++/* vmaxnmv */ ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vmaxnmv_f32 (float32x2_t __a) ++{ ++ return vget_lane_f32 (__builtin_aarch64_reduc_smax_v2sf (__a), 0); ++} ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vmaxnmvq_f32 (float32x4_t __a) ++{ ++ return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_v4sf (__a), 0); ++} ++ ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vmaxnmvq_f64 (float64x2_t __a) ++{ ++ return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_v2df (__a), 0); ++} ++ ++/* vmin */ ++ ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) + vmin_f32 (float32x2_t __a, float32x2_t __b) + { +- return __builtin_aarch64_fminv2sf (__a, __b); ++ return __builtin_aarch64_smin_nanv2sf (__a, __b); + } --(define_insn "*thumb2_neg_abssi2" -- [(set (match_operand:SI 0 "s_register_operand" "=r,&r") -- (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) -+(define_insn_and_split "*thumb2_neg_abssi2" -+ [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r") -+ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" -- "@ -- cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0 -- eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31" -- [(set_attr "conds" "clob,*") -+ "#" -+ ; eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31 -+ ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0 -+ ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0 -+ "&& reload_completed" -+ [(const_int 0)] -+ { -+ if (REGNO(operands[0]) == REGNO(operands[1])) -+ { -+ rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) +@@ -21231,13 +21116,13 @@ + __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) + vminq_f32 (float32x4_t __a, float32x4_t __b) + { +- return __builtin_aarch64_fminv4sf (__a, __b); ++ return __builtin_aarch64_smin_nanv4sf (__a, __b); + } + + __extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) + vminq_f64 (float64x2_t __a, float64x2_t __b) + { +- return __builtin_aarch64_fminv2df (__a, __b); ++ return __builtin_aarch64_smin_nanv2df (__a, __b); + } + + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) +@@ -21279,6 +21164,144 @@ + (int32x4_t) __b); + } + ++/* vminnm */ + -+ emit_insn (gen_rtx_SET (VOIDmode, -+ cc_reg, -+ gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, -+ (gen_rtx_GT (SImode, -+ cc_reg, -+ const0_rtx)), -+ (gen_rtx_SET (VOIDmode, -+ operands[0], -+ (gen_rtx_MINUS (SImode, -+ const0_rtx, -+ operands[1])))))); -+ } -+ else -+ { -+ emit_insn (gen_rtx_SET (VOIDmode, -+ operands[0], -+ gen_rtx_XOR (SImode, -+ gen_rtx_ASHIFTRT (SImode, -+ operands[1], -+ GEN_INT (31)), -+ operands[1]))); -+ emit_insn (gen_rtx_SET (VOIDmode, -+ operands[0], -+ gen_rtx_MINUS (SImode, -+ gen_rtx_ASHIFTRT (SImode, -+ operands[1], -+ GEN_INT (31)), -+ operands[0]))); -+ } -+ DONE; -+ } -+ [(set_attr "conds" "*,clob,clob") - (set_attr "shift" "1") -- (set_attr "predicable" "no, yes") -+ (set_attr "predicable" "yes,no,no") -+ (set_attr "enabled_for_depr_it" "yes,yes,no") -+ (set_attr "predicable_short_it" "no") - (set_attr "ce_count" "2") -- (set_attr "length" "10,8")] -+ (set_attr "length" "8,6,10")] - ) ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vminnm_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return __builtin_aarch64_sminv2sf (__a, __b); ++} ++ ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vminnmq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return __builtin_aarch64_sminv4sf (__a, __b); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vminnmq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return __builtin_aarch64_sminv2df (__a, __b); ++} ++ ++/* vminv */ ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vminv_f32 (float32x2_t __a) ++{ ++ return vget_lane_f32 (__builtin_aarch64_reduc_smin_nan_v2sf (__a), 0); ++} ++ ++__extension__ static __inline int8_t __attribute__ ((__always_inline__)) ++vminv_s8 (int8x8_t __a) ++{ ++ return vget_lane_s8 (__builtin_aarch64_reduc_smin_v8qi (__a), 0); ++} ++ ++__extension__ static __inline int16_t __attribute__ ((__always_inline__)) ++vminv_s16 (int16x4_t __a) ++{ ++ return vget_lane_s16 (__builtin_aarch64_reduc_smin_v4hi (__a), 0); ++} ++ ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vminv_s32 (int32x2_t __a) ++{ ++ return vget_lane_s32 (__builtin_aarch64_reduc_smin_v2si (__a), 0); ++} ++ ++__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) ++vminv_u8 (uint8x8_t __a) ++{ ++ return vget_lane_u8 ((uint8x8_t) ++ __builtin_aarch64_reduc_umin_v8qi ((int8x8_t) __a), 0); ++} ++ ++__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) ++vminv_u16 (uint16x4_t __a) ++{ ++ return vget_lane_u16 ((uint16x4_t) ++ __builtin_aarch64_reduc_umin_v4hi ((int16x4_t) __a), 0); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vminv_u32 (uint32x2_t __a) ++{ ++ return vget_lane_u32 ((uint32x2_t) ++ __builtin_aarch64_reduc_umin_v2si ((int32x2_t) __a), 0); ++} ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vminvq_f32 (float32x4_t __a) ++{ ++ return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_nan_v4sf (__a), 0); ++} ++ ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vminvq_f64 (float64x2_t __a) ++{ ++ return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_nan_v2df (__a), 0); ++} ++ ++__extension__ static __inline int8_t __attribute__ ((__always_inline__)) ++vminvq_s8 (int8x16_t __a) ++{ ++ return vgetq_lane_s8 (__builtin_aarch64_reduc_smin_v16qi (__a), 0); ++} ++ ++__extension__ static __inline int16_t __attribute__ ((__always_inline__)) ++vminvq_s16 (int16x8_t __a) ++{ ++ return vgetq_lane_s16 (__builtin_aarch64_reduc_smin_v8hi (__a), 0); ++} ++ ++__extension__ static __inline int32_t __attribute__ ((__always_inline__)) ++vminvq_s32 (int32x4_t __a) ++{ ++ return vgetq_lane_s32 (__builtin_aarch64_reduc_smin_v4si (__a), 0); ++} ++ ++__extension__ static __inline uint8_t __attribute__ ((__always_inline__)) ++vminvq_u8 (uint8x16_t __a) ++{ ++ return vgetq_lane_u8 ((uint8x16_t) ++ __builtin_aarch64_reduc_umin_v16qi ((int8x16_t) __a), 0); ++} ++ ++__extension__ static __inline uint16_t __attribute__ ((__always_inline__)) ++vminvq_u16 (uint16x8_t __a) ++{ ++ return vgetq_lane_u16 ((uint16x8_t) ++ __builtin_aarch64_reduc_umin_v8hi ((int16x8_t) __a), 0); ++} ++ ++__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) ++vminvq_u32 (uint32x4_t __a) ++{ ++ return vgetq_lane_u32 ((uint32x4_t) ++ __builtin_aarch64_reduc_umin_v4si ((int32x4_t) __a), 0); ++} ++ ++/* vminnmv */ ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vminnmv_f32 (float32x2_t __a) ++{ ++ return vget_lane_f32 (__builtin_aarch64_reduc_smin_v2sf (__a), 0); ++} ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vminnmvq_f32 (float32x4_t __a) ++{ ++ return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_v4sf (__a), 0); ++} ++ ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vminnmvq_f64 (float64x2_t __a) ++{ ++ return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_v2df (__a), 0); ++} ++ + /* vmla */ - ;; We have two alternatives here for memory loads (and similarly for stores) -@@ -167,8 +292,8 @@ - ;; regs. The high register alternatives are not taken into account when - ;; choosing register preferences in order to reflect their expense. - (define_insn "*thumb2_movsi_insn" -- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l ,*hk,m,*m") -- (match_operand:SI 1 "general_operand" "rk ,I,K,j,mi,*mi,l,*hk"))] -+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,l ,*hk,m,*m") -+ (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk"))] - "TARGET_THUMB2 && ! TARGET_IWMMXT - && !(TARGET_HARD_FLOAT && TARGET_VFP) - && ( register_operand (operands[0], SImode) -@@ -176,6 +301,7 @@ - "@ - mov%?\\t%0, %1 - mov%?\\t%0, %1 -+ mov%?\\t%0, %1 - mvn%?\\t%0, #%B1 - movw%?\\t%0, %1 - ldr%?\\t%0, %1 -@@ -182,10 +308,12 @@ - ldr%?\\t%0, %1 - str%?\\t%1, %0 - str%?\\t%1, %0" -- [(set_attr "type" "*,*,simple_alu_imm,*,load1,load1,store1,store1") -+ [(set_attr "type" "*,arlo_imm,arlo_imm,arlo_imm,*,load1,load1,store1,store1") -+ (set_attr "length" "2,4,2,4,4,4,4,4,4") - (set_attr "predicable" "yes") -- (set_attr "pool_range" "*,*,*,*,1018,4094,*,*") -- (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")] -+ (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no") -+ (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*") -+ (set_attr "neg_pool_range" "*,*,*,*,*,0,0,*,*")] - ) + __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +@@ -21430,7 +21453,7 @@ + __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) + vqdmlal_lane_s16 (int32x4_t __a, int16x4_t __b, int16x4_t __c, int const __d) + { +- int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (INT64_C (0))); ++ int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (__AARCH64_INT64_C (0))); + return __builtin_aarch64_sqdmlal_lanev4hi (__a, __b, __tmp, __d); + } - (define_insn "tls_load_dot_plus_four" -@@ -223,6 +351,21 @@ - (set_attr "neg_pool_range" "*,*,*,250")] - ) +@@ -21481,7 +21504,7 @@ + __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) + vqdmlal_lane_s32 (int64x2_t __a, int32x2_t __b, int32x2_t __c, int const __d) + { +- int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (INT64_C (0))); ++ int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (__AARCH64_INT64_C (0))); + return __builtin_aarch64_sqdmlal_lanev2si (__a, __b, __tmp, __d); + } -+(define_insn "*thumb2_storewb_pairsi" -+ [(set (match_operand:SI 0 "register_operand" "=&kr") -+ (plus:SI (match_operand:SI 1 "register_operand" "0") -+ (match_operand:SI 2 "const_int_operand" "n"))) -+ (set (mem:SI (plus:SI (match_dup 0) (match_dup 2))) -+ (match_operand:SI 3 "register_operand" "r")) -+ (set (mem:SI (plus:SI (match_dup 0) -+ (match_operand:SI 5 "const_int_operand" "n"))) -+ (match_operand:SI 4 "register_operand" "r"))] -+ "TARGET_THUMB2 -+ && INTVAL (operands[5]) == INTVAL (operands[2]) + 4" -+ "strd\\t%3, %4, [%0, %2]!" -+ [(set_attr "type" "store2")] -+) -+ - (define_insn "*thumb2_cmpsi_neg_shiftsi" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 0 "s_register_operand" "r") -@@ -233,57 +376,170 @@ - "cmn%?\\t%0, %1%S3" - [(set_attr "conds" "set") - (set_attr "shift" "1") -- (set_attr "type" "alu_shift")] -+ (set_attr "type" "arlo_shift")] - ) +@@ -21558,7 +21581,7 @@ + __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) + vqdmlsl_lane_s16 (int32x4_t __a, int16x4_t __b, int16x4_t __c, int const __d) + { +- int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (INT64_C (0))); ++ int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (__AARCH64_INT64_C (0))); + return __builtin_aarch64_sqdmlsl_lanev4hi (__a, __b, __tmp, __d); + } --(define_insn "*thumb2_mov_scc" -- [(set (match_operand:SI 0 "s_register_operand" "=r") -+(define_insn_and_split "*thumb2_mov_scc" -+ [(set (match_operand:SI 0 "s_register_operand" "=l,r") - (match_operator:SI 1 "arm_comparison_operator" - [(match_operand 2 "cc_register" "") (const_int 0)]))] - "TARGET_THUMB2" -- "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1" -+ "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1" -+ "TARGET_THUMB2" -+ [(set (match_dup 0) -+ (if_then_else:SI (match_dup 1) -+ (const_int 1) -+ (const_int 0)))] -+ "" - [(set_attr "conds" "use") -- (set_attr "length" "10")] -+ (set_attr "enabled_for_depr_it" "yes,no") -+ (set_attr "length" "8,10")] - ) +@@ -21609,7 +21632,7 @@ + __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) + vqdmlsl_lane_s32 (int64x2_t __a, int32x2_t __b, int32x2_t __c, int const __d) + { +- int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (INT64_C (0))); ++ int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (__AARCH64_INT64_C (0))); + return __builtin_aarch64_sqdmlsl_lanev2si (__a, __b, __tmp, __d); + } --(define_insn "*thumb2_mov_negscc" -+(define_insn_and_split "*thumb2_mov_negscc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (neg:SI (match_operator:SI 1 "arm_comparison_operator" - [(match_operand 2 "cc_register" "") (const_int 0)])))] -+ "TARGET_THUMB2 && !arm_restrict_it" -+ "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" - "TARGET_THUMB2" -- "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" -+ [(set (match_dup 0) -+ (if_then_else:SI (match_dup 1) -+ (match_dup 3) -+ (const_int 0)))] -+ { -+ operands[3] = GEN_INT (~0); -+ } - [(set_attr "conds" "use") - (set_attr "length" "10")] - ) +@@ -21734,7 +21757,7 @@ + __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) + vqdmull_lane_s16 (int16x4_t __a, int16x4_t __b, int const __c) + { +- int16x8_t __tmp = vcombine_s16 (__b, vcreate_s16 (INT64_C (0))); ++ int16x8_t __tmp = vcombine_s16 (__b, vcreate_s16 (__AARCH64_INT64_C (0))); + return __builtin_aarch64_sqdmull_lanev4hi (__a, __tmp, __c); + } --(define_insn "*thumb2_mov_notscc" -+(define_insn_and_split "*thumb2_mov_negscc_strict_it" -+ [(set (match_operand:SI 0 "low_register_operand" "=l") -+ (neg:SI (match_operator:SI 1 "arm_comparison_operator" -+ [(match_operand 2 "cc_register" "") (const_int 0)])))] -+ "TARGET_THUMB2 && arm_restrict_it" -+ "#" ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\" -+ "&& reload_completed" -+ [(set (match_dup 0) -+ (match_dup 3)) -+ (cond_exec (match_dup 4) -+ (set (match_dup 0) -+ (const_int 0)))] -+ { -+ operands[3] = GEN_INT (~0); -+ enum machine_mode mode = GET_MODE (operands[2]); -+ enum rtx_code rc = GET_CODE (operands[1]); +@@ -21783,7 +21806,7 @@ + __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) + vqdmull_lane_s32 (int32x2_t __a, int32x2_t __b, int const __c) + { +- int32x4_t __tmp = vcombine_s32 (__b, vcreate_s32 (INT64_C (0))); ++ int32x4_t __tmp = vcombine_s32 (__b, vcreate_s32 (__AARCH64_INT64_C (0))); + return __builtin_aarch64_sqdmull_lanev2si (__a, __tmp, __c); + } + +@@ -22795,6 +22818,223 @@ + return (uint64x1_t) __builtin_aarch64_uqsubdi (__a, __b); + } + ++/* vrecpe */ + -+ if (mode == CCFPmode || mode == CCFPEmode) -+ rc = reverse_condition_maybe_unordered (rc); -+ else -+ rc = reverse_condition (rc); -+ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vrecpes_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_frecpesf (__a); ++} + -+ } -+ [(set_attr "conds" "use") -+ (set_attr "length" "8")] -+) ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vrecped_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_frecpedf (__a); ++} + -+(define_insn_and_split "*thumb2_mov_notscc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (not:SI (match_operator:SI 1 "arm_comparison_operator" - [(match_operand 2 "cc_register" "") (const_int 0)])))] -+ "TARGET_THUMB2 && !arm_restrict_it" -+ "#" ; "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1" - "TARGET_THUMB2" -- "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1" -+ [(set (match_dup 0) -+ (if_then_else:SI (match_dup 1) -+ (match_dup 3) -+ (match_dup 4)))] -+ { -+ operands[3] = GEN_INT (~1); -+ operands[4] = GEN_INT (~0); -+ } - [(set_attr "conds" "use") - (set_attr "length" "10")] - ) - --(define_insn "*thumb2_movsicc_insn" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") -+(define_insn_and_split "*thumb2_mov_notscc_strict_it" -+ [(set (match_operand:SI 0 "low_register_operand" "=l") -+ (not:SI (match_operator:SI 1 "arm_comparison_operator" -+ [(match_operand 2 "cc_register" "") (const_int 0)])))] -+ "TARGET_THUMB2 && arm_restrict_it" -+ "#" ; "mvn %0, #0 ; it%d1 ; lsl%d1 %0, %0, #1" -+ "&& reload_completed" -+ [(set (match_dup 0) -+ (match_dup 3)) -+ (cond_exec (match_dup 4) -+ (set (match_dup 0) -+ (ashift:SI (match_dup 0) -+ (const_int 1))))] -+ { -+ operands[3] = GEN_INT (~0); -+ operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]), -+ VOIDmode, operands[2], const0_rtx); -+ } -+ [(set_attr "conds" "use") -+ (set_attr "length" "8")] -+) ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrecpe_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_frecpev2sf (__a); ++} + -+(define_insn_and_split "*thumb2_movsicc_insn" -+ [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r,r,r,r,r,r,r,r") - (if_then_else:SI - (match_operator 3 "arm_comparison_operator" - [(match_operand 4 "cc_register" "") (const_int 0)]) -- (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") -- (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] -+ (match_operand:SI 1 "arm_not_operand" "0 ,lPy,0 ,0,rI,K,rI,rI,K ,K,r") -+ (match_operand:SI 2 "arm_not_operand" "lPy,0 ,rI,K,0 ,0,rI,K ,rI,K,r")))] - "TARGET_THUMB2" - "@ - it\\t%D3\;mov%D3\\t%0, %2 -+ it\\t%d3\;mov%d3\\t%0, %1 -+ it\\t%D3\;mov%D3\\t%0, %2 - it\\t%D3\;mvn%D3\\t%0, #%B2 - it\\t%d3\;mov%d3\\t%0, %1 - it\\t%d3\;mvn%d3\\t%0, #%B1 -- ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 -- ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 -- ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 -- ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" -- [(set_attr "length" "6,6,6,6,10,10,10,10") -+ # -+ # -+ # -+ # -+ #" -+ ; alt 6: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 -+ ; alt 7: ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 -+ ; alt 8: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 -+ ; alt 9: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2 -+ ; alt 10: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 -+ "&& reload_completed" -+ [(const_int 0)] -+ { -+ enum rtx_code rev_code; -+ enum machine_mode mode; -+ rtx rev_cond; ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrecpeq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_frecpev4sf (__a); ++} + -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, -+ operands[3], -+ gen_rtx_SET (VOIDmode, -+ operands[0], -+ operands[1]))); -+ rev_code = GET_CODE (operands[3]); -+ mode = GET_MODE (operands[4]); -+ if (mode == CCFPmode || mode == CCFPEmode) -+ rev_code = reverse_condition_maybe_unordered (rev_code); -+ else -+ rev_code = reverse_condition (rev_code); ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrecpeq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_frecpev2df (__a); ++} + -+ rev_cond = gen_rtx_fmt_ee (rev_code, -+ VOIDmode, -+ gen_rtx_REG (mode, CC_REGNUM), -+ const0_rtx); -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, -+ rev_cond, -+ gen_rtx_SET (VOIDmode, -+ operands[0], -+ operands[2]))); -+ DONE; -+ } -+ [(set_attr "length" "4,4,6,6,6,6,10,10,10,10,6") -+ (set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,yes") - (set_attr "conds" "use")] - ) - -@@ -333,28 +589,74 @@ - ;; addresses will have the thumb bit set correctly. - - --(define_insn "*thumb2_and_scc" -- [(set (match_operand:SI 0 "s_register_operand" "=r") -+(define_insn_and_split "*thumb2_and_scc" -+ [(set (match_operand:SI 0 "s_register_operand" "=Ts") - (and:SI (match_operator:SI 1 "arm_comparison_operator" -- [(match_operand 3 "cc_register" "") (const_int 0)]) -- (match_operand:SI 2 "s_register_operand" "r")))] -+ [(match_operand 2 "cc_register" "") (const_int 0)]) -+ (match_operand:SI 3 "s_register_operand" "r")))] - "TARGET_THUMB2" -- "ite\\t%D1\;mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1" -+ "#" ; "and\\t%0, %3, #1\;it\\t%D1\;mov%D1\\t%0, #0" -+ "&& reload_completed" -+ [(set (match_dup 0) -+ (and:SI (match_dup 3) (const_int 1))) -+ (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))] -+ { -+ enum machine_mode mode = GET_MODE (operands[2]); -+ enum rtx_code rc = GET_CODE (operands[1]); ++/* vrecps */ + -+ if (mode == CCFPmode || mode == CCFPEmode) -+ rc = reverse_condition_maybe_unordered (rc); -+ else -+ rc = reverse_condition (rc); -+ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); -+ } - [(set_attr "conds" "use") -- (set_attr "length" "10")] -+ (set (attr "length") (if_then_else (match_test "arm_restrict_it") -+ (const_int 8) -+ (const_int 10)))] - ) - --(define_insn "*thumb2_ior_scc" -+(define_insn_and_split "*thumb2_ior_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") -+ (ior:SI (match_operator:SI 1 "arm_comparison_operator" -+ [(match_operand 2 "cc_register" "") (const_int 0)]) -+ (match_operand:SI 3 "s_register_operand" "0,?r")))] -+ "TARGET_THUMB2 && !arm_restrict_it" -+ "@ -+ it\\t%d1\;orr%d1\\t%0, %3, #1 -+ #" -+ ; alt 1: ite\\t%D1\;mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1 -+ "&& reload_completed -+ && REGNO (operands [0]) != REGNO (operands[3])" -+ [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3))) -+ (cond_exec (match_dup 4) (set (match_dup 0) -+ (ior:SI (match_dup 3) (const_int 1))))] -+ { -+ enum machine_mode mode = GET_MODE (operands[2]); -+ enum rtx_code rc = GET_CODE (operands[1]); ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vrecpss_f32 (float32_t __a, float32_t __b) ++{ ++ return __builtin_aarch64_frecpssf (__a, __b); ++} ++ ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vrecpsd_f64 (float64_t __a, float64_t __b) ++{ ++ return __builtin_aarch64_frecpsdf (__a, __b); ++} ++ ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrecps_f32 (float32x2_t __a, float32x2_t __b) ++{ ++ return __builtin_aarch64_frecpsv2sf (__a, __b); ++} ++ ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrecpsq_f32 (float32x4_t __a, float32x4_t __b) ++{ ++ return __builtin_aarch64_frecpsv4sf (__a, __b); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrecpsq_f64 (float64x2_t __a, float64x2_t __b) ++{ ++ return __builtin_aarch64_frecpsv2df (__a, __b); ++} ++ ++/* vrecpx */ ++ ++__extension__ static __inline float32_t __attribute__ ((__always_inline__)) ++vrecpxs_f32 (float32_t __a) ++{ ++ return __builtin_aarch64_frecpxsf (__a); ++} ++ ++__extension__ static __inline float64_t __attribute__ ((__always_inline__)) ++vrecpxd_f64 (float64_t __a) ++{ ++ return __builtin_aarch64_frecpxdf (__a); ++} ++ ++/* vrnd */ ++ ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrnd_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_btruncv2sf (__a); ++} ++ ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrndq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_btruncv4sf (__a); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrndq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_btruncv2df (__a); ++} ++ ++/* vrnda */ ++ ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrnda_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_roundv2sf (__a); ++} ++ ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrndaq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_roundv4sf (__a); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrndaq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_roundv2df (__a); ++} ++ ++/* vrndi */ ++ ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrndi_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_nearbyintv2sf (__a); ++} ++ ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrndiq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_nearbyintv4sf (__a); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrndiq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_nearbyintv2df (__a); ++} ++ ++/* vrndm */ ++ ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrndm_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_floorv2sf (__a); ++} ++ ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrndmq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_floorv4sf (__a); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrndmq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_floorv2df (__a); ++} ++ ++/* vrndn */ ++ ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrndn_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_frintnv2sf (__a); ++} ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrndnq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_frintnv4sf (__a); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrndnq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_frintnv2df (__a); ++} ++ ++/* vrndp */ + -+ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); -+ if (mode == CCFPmode || mode == CCFPEmode) -+ rc = reverse_condition_maybe_unordered (rc); -+ else -+ rc = reverse_condition (rc); -+ operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); -+ } -+ [(set_attr "conds" "use") -+ (set_attr "length" "6,10")] -+) ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrndp_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_ceilv2sf (__a); ++} + -+(define_insn "*thumb2_ior_scc_strict_it" -+ [(set (match_operand:SI 0 "s_register_operand" "=l,l") - (ior:SI (match_operator:SI 2 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) -- (match_operand:SI 1 "s_register_operand" "0,?r")))] -- "TARGET_THUMB2" -+ (match_operand:SI 1 "s_register_operand" "0,?l")))] -+ "TARGET_THUMB2 && arm_restrict_it" - "@ -- it\\t%d2\;orr%d2\\t%0, %1, #1 -- ite\\t%D2\;mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1" -+ it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1 -+ mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1" - [(set_attr "conds" "use") -- (set_attr "length" "6,10")] -+ (set_attr "length" "8")] - ) - - (define_insn "*thumb2_cond_move" -@@ -384,13 +686,20 @@ - output_asm_insn (\"it\\t%D4\", operands); - break; - case 2: -- output_asm_insn (\"ite\\t%D4\", operands); -+ if (arm_restrict_it) -+ output_asm_insn (\"it\\t%D4\", operands); -+ else -+ output_asm_insn (\"ite\\t%D4\", operands); - break; - default: - abort(); - } - if (which_alternative != 0) -- output_asm_insn (\"mov%D4\\t%0, %1\", operands); -+ { -+ output_asm_insn (\"mov%D4\\t%0, %1\", operands); -+ if (arm_restrict_it && which_alternative == 2) -+ output_asm_insn (\"it\\t%d4\", operands); -+ } - if (which_alternative != 1) - output_asm_insn (\"mov%d4\\t%0, %2\", operands); - return \"\"; -@@ -407,7 +716,7 @@ - (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) - (match_operand:SI 1 "s_register_operand" "0,?r")])) - (clobber (reg:CC CC_REGNUM))] -- "TARGET_THUMB2" -+ "TARGET_THUMB2 && !arm_restrict_it" - "* - if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) - return \"%i5\\t%0, %1, %2, lsr #31\"; -@@ -436,9 +745,78 @@ - (set_attr "length" "14")] - ) - -+(define_insn_and_split "*thumb2_cond_arith_strict_it" -+ [(set (match_operand:SI 0 "s_register_operand" "=l") -+ (match_operator:SI 5 "shiftable_operator_strict_it" -+ [(match_operator:SI 4 "arm_comparison_operator" -+ [(match_operand:SI 2 "s_register_operand" "r") -+ (match_operand:SI 3 "arm_rhs_operand" "rI")]) -+ (match_operand:SI 1 "s_register_operand" "0")])) -+ (clobber (reg:CC CC_REGNUM))] -+ "TARGET_THUMB2 && arm_restrict_it" -+ "#" -+ "&& reload_completed" -+ [(const_int 0)] -+ { -+ if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) -+ { -+ /* %i5 %0, %1, %2, lsr #31 */ -+ rtx shifted_op = gen_rtx_LSHIFTRT (SImode, operands[2], GEN_INT (31)); -+ rtx op = NULL_RTX; ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrndpq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_ceilv4sf (__a); ++} + -+ switch (GET_CODE (operands[5])) -+ { -+ case AND: -+ op = gen_rtx_AND (SImode, shifted_op, operands[1]); -+ break; -+ case PLUS: -+ op = gen_rtx_PLUS (SImode, shifted_op, operands[1]); -+ break; -+ default: gcc_unreachable (); -+ } -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], op)); -+ DONE; -+ } ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrndpq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_ceilv2df (__a); ++} + -+ /* "cmp %2, %3" */ -+ emit_insn (gen_rtx_SET (VOIDmode, -+ gen_rtx_REG (CCmode, CC_REGNUM), -+ gen_rtx_COMPARE (CCmode, operands[2], operands[3]))); ++/* vrndx */ + -+ if (GET_CODE (operands[5]) == AND) -+ { -+ /* %i5 %0, %1, #1 -+ it%D4 -+ mov%D4 %0, #0 */ -+ enum rtx_code rc = reverse_condition (GET_CODE (operands[4])); -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_rtx_AND (SImode, operands[1], GEN_INT (1)))); -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, -+ gen_rtx_fmt_ee (rc, VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx), -+ gen_rtx_SET (VOIDmode, operands[0], const0_rtx))); -+ DONE; -+ } -+ else -+ { -+ /* it\\t%d4 -+ %i5%d4\\t%0, %1, #1 */ -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, gen_rtx_fmt_ee (GET_CODE (operands[4]), -+ VOIDmode, -+ gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx), -+ gen_rtx_SET(VOIDmode, operands[0], -+ gen_rtx_PLUS (SImode, -+ operands[1], -+ GEN_INT (1))))); -+ DONE; -+ } -+ FAIL; -+ } -+ [(set_attr "conds" "clob") -+ (set_attr "length" "12")] -+) ++__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) ++vrndx_f32 (float32x2_t __a) ++{ ++ return __builtin_aarch64_rintv2sf (__a); ++} + - (define_insn "*thumb2_cond_sub" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r") -- (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") -+ [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") -+ (minus:SI (match_operand:SI 1 "s_register_operand" "0,?Ts") - (match_operator:SI 4 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) -@@ -448,8 +826,16 @@ - output_asm_insn (\"cmp\\t%2, %3\", operands); - if (which_alternative != 0) - { -- output_asm_insn (\"ite\\t%D4\", operands); -- output_asm_insn (\"mov%D4\\t%0, %1\", operands); -+ if (arm_restrict_it) -+ { -+ output_asm_insn (\"mov\\t%0, %1\", operands); -+ output_asm_insn (\"it\\t%d4\", operands); -+ } -+ else -+ { -+ output_asm_insn (\"ite\\t%D4\", operands); -+ output_asm_insn (\"mov%D4\\t%0, %1\", operands); -+ } - } - else - output_asm_insn (\"it\\t%d4\", operands); -@@ -459,37 +845,82 @@ - (set_attr "length" "10,14")] - ) ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vrndxq_f32 (float32x4_t __a) ++{ ++ return __builtin_aarch64_rintv4sf (__a); ++} ++ ++__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) ++vrndxq_f64 (float64x2_t __a) ++{ ++ return __builtin_aarch64_rintv2df (__a); ++} ++ + /* vrshl */ --(define_insn "*thumb2_negscc" -- [(set (match_operand:SI 0 "s_register_operand" "=r") -+(define_insn_and_split "*thumb2_negscc" -+ [(set (match_operand:SI 0 "s_register_operand" "=Ts") - (neg:SI (match_operator 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_rhs_operand" "rI")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" -- "* -- if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) -- return \"asr\\t%0, %1, #31\"; -+ "#" -+ "&& reload_completed" -+ [(const_int 0)] -+ { -+ rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) +@@ -23138,109 +23378,109 @@ + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) + vshl_n_s8 (int8x8_t __a, const int __b) + { +- return (int8x8_t) __builtin_aarch64_sshl_nv8qi (__a, __b); ++ return (int8x8_t) __builtin_aarch64_ashlv8qi (__a, __b); + } -- if (GET_CODE (operands[3]) == NE) -- return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\"; -+ if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) -+ { -+ /* Emit asr\\t%0, %1, #31 */ -+ emit_insn (gen_rtx_SET (VOIDmode, -+ operands[0], -+ gen_rtx_ASHIFTRT (SImode, -+ operands[1], -+ GEN_INT (31)))); -+ DONE; -+ } -+ else if (GET_CODE (operands[3]) == NE && !arm_restrict_it) -+ { -+ /* Emit subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0 */ -+ if (CONST_INT_P (operands[2])) -+ emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2], -+ GEN_INT (- INTVAL (operands[2])))); -+ else -+ emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2])); + __extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) + vshl_n_s16 (int16x4_t __a, const int __b) + { +- return (int16x4_t) __builtin_aarch64_sshl_nv4hi (__a, __b); ++ return (int16x4_t) __builtin_aarch64_ashlv4hi (__a, __b); + } -- output_asm_insn (\"cmp\\t%1, %2\", operands); -- output_asm_insn (\"ite\\t%D3\", operands); -- output_asm_insn (\"mov%D3\\t%0, #0\", operands); -- return \"mvn%d3\\t%0, #0\"; -- " -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, -+ gen_rtx_NE (SImode, -+ cc_reg, -+ const0_rtx), -+ gen_rtx_SET (SImode, -+ operands[0], -+ GEN_INT (~0)))); -+ DONE; -+ } -+ else -+ { -+ /* Emit: cmp\\t%1, %2\;mvn\\t%0, #0\;it\\t%D3\;mov%D3\\t%0, #0\;*/ -+ enum rtx_code rc = reverse_condition (GET_CODE (operands[3])); -+ enum machine_mode mode = SELECT_CC_MODE (rc, operands[1], operands[2]); -+ rtx tmp1 = gen_rtx_REG (mode, CC_REGNUM); -+ -+ emit_insn (gen_rtx_SET (VOIDmode, -+ cc_reg, -+ gen_rtx_COMPARE (CCmode, operands[1], operands[2]))); -+ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], GEN_INT (~0))); -+ -+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, -+ gen_rtx_fmt_ee (rc, -+ VOIDmode, -+ tmp1, -+ const0_rtx), -+ gen_rtx_SET (VOIDmode, operands[0], const0_rtx))); -+ DONE; -+ } -+ FAIL; -+ } - [(set_attr "conds" "clob") - (set_attr "length" "14")] - ) + __extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) + vshl_n_s32 (int32x2_t __a, const int __b) + { +- return (int32x2_t) __builtin_aarch64_sshl_nv2si (__a, __b); ++ return (int32x2_t) __builtin_aarch64_ashlv2si (__a, __b); + } - (define_insn "*thumb2_movcond" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") -+ [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand:SI 3 "s_register_operand" "r,r,r") - (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) -- (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") -- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) -+ (match_operand:SI 1 "arm_rhs_operand" "0,TsI,?TsI") -+ (match_operand:SI 2 "arm_rhs_operand" "TsI,0,TsI"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" - "* -@@ -544,12 +975,18 @@ - output_asm_insn (\"it\\t%d5\", operands); - break; - case 2: -- output_asm_insn (\"ite\\t%d5\", operands); -+ if (arm_restrict_it) -+ { -+ output_asm_insn (\"mov\\t%0, %1\", operands); -+ output_asm_insn (\"it\\t%D5\", operands); -+ } -+ else -+ output_asm_insn (\"ite\\t%d5\", operands); - break; - default: - abort(); - } -- if (which_alternative != 0) -+ if (which_alternative != 0 && !(arm_restrict_it && which_alternative == 2)) - output_asm_insn (\"mov%d5\\t%0, %1\", operands); - if (which_alternative != 1) - output_asm_insn (\"mov%D5\\t%0, %2\", operands); -@@ -570,8 +1007,9 @@ - "@ - sxtb%?\\t%0, %1 - ldr%(sb%)\\t%0, %1" -- [(set_attr "type" "simple_alu_shift,load_byte") -+ [(set_attr "type" "extend,load_byte") - (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "pool_range" "*,4094") - (set_attr "neg_pool_range" "*,250")] - ) -@@ -583,8 +1021,9 @@ - "@ - uxth%?\\t%0, %1 - ldr%(h%)\\t%0, %1" -- [(set_attr "type" "simple_alu_shift,load_byte") -+ [(set_attr "type" "extend,load_byte") - (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "pool_range" "*,4094") - (set_attr "neg_pool_range" "*,250")] - ) -@@ -596,8 +1035,9 @@ - "@ - uxtb%(%)\\t%0, %1 - ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2" -- [(set_attr "type" "simple_alu_shift,load_byte") -+ [(set_attr "type" "extend,load_byte") - (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "pool_range" "*,4094") - (set_attr "neg_pool_range" "*,250")] - ) -@@ -688,8 +1128,8 @@ - (set_attr "shift" "1") - (set_attr "length" "2") - (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") -- (const_string "alu_shift") -- (const_string "alu_shift_reg")))] -+ (const_string "arlo_shift") -+ (const_string "arlo_shift_reg")))] - ) + __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) + vshl_n_s64 (int64x1_t __a, const int __b) + { +- return (int64x1_t) __builtin_aarch64_sshl_ndi (__a, __b); ++ return (int64x1_t) __builtin_aarch64_ashldi (__a, __b); + } + + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vshl_n_u8 (uint8x8_t __a, const int __b) + { +- return (uint8x8_t) __builtin_aarch64_ushl_nv8qi ((int8x8_t) __a, __b); ++ return (uint8x8_t) __builtin_aarch64_ashlv8qi ((int8x8_t) __a, __b); + } + + __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) + vshl_n_u16 (uint16x4_t __a, const int __b) + { +- return (uint16x4_t) __builtin_aarch64_ushl_nv4hi ((int16x4_t) __a, __b); ++ return (uint16x4_t) __builtin_aarch64_ashlv4hi ((int16x4_t) __a, __b); + } + + __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) + vshl_n_u32 (uint32x2_t __a, const int __b) + { +- return (uint32x2_t) __builtin_aarch64_ushl_nv2si ((int32x2_t) __a, __b); ++ return (uint32x2_t) __builtin_aarch64_ashlv2si ((int32x2_t) __a, __b); + } + + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vshl_n_u64 (uint64x1_t __a, const int __b) + { +- return (uint64x1_t) __builtin_aarch64_ushl_ndi ((int64x1_t) __a, __b); ++ return (uint64x1_t) __builtin_aarch64_ashldi ((int64x1_t) __a, __b); + } + + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) + vshlq_n_s8 (int8x16_t __a, const int __b) + { +- return (int8x16_t) __builtin_aarch64_sshl_nv16qi (__a, __b); ++ return (int8x16_t) __builtin_aarch64_ashlv16qi (__a, __b); + } + + __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) + vshlq_n_s16 (int16x8_t __a, const int __b) + { +- return (int16x8_t) __builtin_aarch64_sshl_nv8hi (__a, __b); ++ return (int16x8_t) __builtin_aarch64_ashlv8hi (__a, __b); + } + + __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) + vshlq_n_s32 (int32x4_t __a, const int __b) + { +- return (int32x4_t) __builtin_aarch64_sshl_nv4si (__a, __b); ++ return (int32x4_t) __builtin_aarch64_ashlv4si (__a, __b); + } + + __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) + vshlq_n_s64 (int64x2_t __a, const int __b) + { +- return (int64x2_t) __builtin_aarch64_sshl_nv2di (__a, __b); ++ return (int64x2_t) __builtin_aarch64_ashlv2di (__a, __b); + } + + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vshlq_n_u8 (uint8x16_t __a, const int __b) + { +- return (uint8x16_t) __builtin_aarch64_ushl_nv16qi ((int8x16_t) __a, __b); ++ return (uint8x16_t) __builtin_aarch64_ashlv16qi ((int8x16_t) __a, __b); + } + + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vshlq_n_u16 (uint16x8_t __a, const int __b) + { +- return (uint16x8_t) __builtin_aarch64_ushl_nv8hi ((int16x8_t) __a, __b); ++ return (uint16x8_t) __builtin_aarch64_ashlv8hi ((int16x8_t) __a, __b); + } + + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vshlq_n_u32 (uint32x4_t __a, const int __b) + { +- return (uint32x4_t) __builtin_aarch64_ushl_nv4si ((int32x4_t) __a, __b); ++ return (uint32x4_t) __builtin_aarch64_ashlv4si ((int32x4_t) __a, __b); + } + + __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) + vshlq_n_u64 (uint64x2_t __a, const int __b) + { +- return (uint64x2_t) __builtin_aarch64_ushl_nv2di ((int64x2_t) __a, __b); ++ return (uint64x2_t) __builtin_aarch64_ashlv2di ((int64x2_t) __a, __b); + } + + __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) + vshld_n_s64 (int64x1_t __a, const int __b) + { +- return (int64x1_t) __builtin_aarch64_sshl_ndi (__a, __b); ++ return (int64x1_t) __builtin_aarch64_ashldi (__a, __b); + } + + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vshld_n_u64 (uint64x1_t __a, const int __b) + { +- return (uint64x1_t) __builtin_aarch64_ushl_ndi (__a, __b); ++ return (uint64x1_t) __builtin_aarch64_ashldi (__a, __b); + } + + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) +@@ -23428,109 +23668,109 @@ + __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) + vshr_n_s8 (int8x8_t __a, const int __b) + { +- return (int8x8_t) __builtin_aarch64_sshr_nv8qi (__a, __b); ++ return (int8x8_t) __builtin_aarch64_ashrv8qi (__a, __b); + } + + __extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) + vshr_n_s16 (int16x4_t __a, const int __b) + { +- return (int16x4_t) __builtin_aarch64_sshr_nv4hi (__a, __b); ++ return (int16x4_t) __builtin_aarch64_ashrv4hi (__a, __b); + } + + __extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) + vshr_n_s32 (int32x2_t __a, const int __b) + { +- return (int32x2_t) __builtin_aarch64_sshr_nv2si (__a, __b); ++ return (int32x2_t) __builtin_aarch64_ashrv2si (__a, __b); + } + + __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) + vshr_n_s64 (int64x1_t __a, const int __b) + { +- return (int64x1_t) __builtin_aarch64_sshr_ndi (__a, __b); ++ return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b); + } + + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) + vshr_n_u8 (uint8x8_t __a, const int __b) + { +- return (uint8x8_t) __builtin_aarch64_ushr_nv8qi ((int8x8_t) __a, __b); ++ return (uint8x8_t) __builtin_aarch64_lshrv8qi ((int8x8_t) __a, __b); + } + + __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) + vshr_n_u16 (uint16x4_t __a, const int __b) + { +- return (uint16x4_t) __builtin_aarch64_ushr_nv4hi ((int16x4_t) __a, __b); ++ return (uint16x4_t) __builtin_aarch64_lshrv4hi ((int16x4_t) __a, __b); + } - (define_insn "*thumb2_mov_shortim" -@@ -811,7 +1251,7 @@ - " - [(set_attr "conds" "set") - (set_attr "length" "2,2,4,4") -- (set_attr "type" "simple_alu_imm,*,simple_alu_imm,*")] -+ (set_attr "type" "arlo_imm,*,arlo_imm,*")] - ) + __extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) + vshr_n_u32 (uint32x2_t __a, const int __b) + { +- return (uint32x2_t) __builtin_aarch64_ushr_nv2si ((int32x2_t) __a, __b); ++ return (uint32x2_t) __builtin_aarch64_lshrv2si ((int32x2_t) __a, __b); + } - (define_insn "*thumb2_mulsi_short" -@@ -823,7 +1263,7 @@ - "mul%!\\t%0, %2, %0" - [(set_attr "predicable" "yes") - (set_attr "length" "2") -- (set_attr "insn" "muls")]) -+ (set_attr "type" "muls")]) + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vshr_n_u64 (uint64x1_t __a, const int __b) + { +- return (uint64x1_t) __builtin_aarch64_ushr_ndi ((int64x1_t) __a, __b); ++ return (uint64x1_t) __builtin_aarch64_lshrdi ((int64x1_t) __a, __b); + } - (define_insn "*thumb2_mulsi_short_compare0" - [(set (reg:CC_NOOV CC_REGNUM) -@@ -836,7 +1276,7 @@ - "TARGET_THUMB2 && optimize_size" - "muls\\t%0, %2, %0" - [(set_attr "length" "2") -- (set_attr "insn" "muls")]) -+ (set_attr "type" "muls")]) + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) + vshrq_n_s8 (int8x16_t __a, const int __b) + { +- return (int8x16_t) __builtin_aarch64_sshr_nv16qi (__a, __b); ++ return (int8x16_t) __builtin_aarch64_ashrv16qi (__a, __b); + } - (define_insn "*thumb2_mulsi_short_compare0_scratch" - [(set (reg:CC_NOOV CC_REGNUM) -@@ -848,7 +1288,7 @@ - "TARGET_THUMB2 && optimize_size" - "muls\\t%0, %2, %0" - [(set_attr "length" "2") -- (set_attr "insn" "muls")]) -+ (set_attr "type" "muls")]) + __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) + vshrq_n_s16 (int16x8_t __a, const int __b) + { +- return (int16x8_t) __builtin_aarch64_sshr_nv8hi (__a, __b); ++ return (int16x8_t) __builtin_aarch64_ashrv8hi (__a, __b); + } - (define_insn "*thumb2_cbz" - [(set (pc) (if_then_else -@@ -922,7 +1362,8 @@ - (match_operand:SI 1 "s_register_operand" "r")))] - "TARGET_THUMB2" - "orn%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")] -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")] - ) + __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) + vshrq_n_s32 (int32x4_t __a, const int __b) + { +- return (int32x4_t) __builtin_aarch64_sshr_nv4si (__a, __b); ++ return (int32x4_t) __builtin_aarch64_ashrv4si (__a, __b); + } - (define_insn "*orsi_not_shiftsi_si" -@@ -934,8 +1375,9 @@ - "TARGET_THUMB2" - "orn%?\\t%0, %1, %2%S4" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "shift" "2") -- (set_attr "type" "alu_shift")] -+ (set_attr "type" "arlo_shift")] - ) + __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) + vshrq_n_s64 (int64x2_t __a, const int __b) + { +- return (int64x2_t) __builtin_aarch64_sshr_nv2di (__a, __b); ++ return (int64x2_t) __builtin_aarch64_ashrv2di (__a, __b); + } - (define_peephole2 ---- a/src/gcc/config/arm/arm.c -+++ b/src/gcc/config/arm/arm.c -@@ -173,6 +173,7 @@ - static tree arm_builtin_decl (unsigned, bool); - static void emit_constant_insn (rtx cond, rtx pattern); - static rtx emit_set_insn (rtx, rtx); -+static rtx emit_multi_reg_push (unsigned long); - static int arm_arg_partial_bytes (cumulative_args_t, enum machine_mode, - tree, bool); - static rtx arm_function_arg (cumulative_args_t, enum machine_mode, -@@ -280,6 +281,7 @@ + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) + vshrq_n_u8 (uint8x16_t __a, const int __b) + { +- return (uint8x16_t) __builtin_aarch64_ushr_nv16qi ((int8x16_t) __a, __b); ++ return (uint8x16_t) __builtin_aarch64_lshrv16qi ((int8x16_t) __a, __b); + } - static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, - bool op0_preserve_value); -+static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); - - /* Table of machine attributes. */ - static const struct attribute_spec arm_attribute_table[] = -@@ -620,6 +622,13 @@ - #undef TARGET_CLASS_LIKELY_SPILLED_P - #define TARGET_CLASS_LIKELY_SPILLED_P arm_class_likely_spilled_p + __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) + vshrq_n_u16 (uint16x8_t __a, const int __b) + { +- return (uint16x8_t) __builtin_aarch64_ushr_nv8hi ((int16x8_t) __a, __b); ++ return (uint16x8_t) __builtin_aarch64_lshrv8hi ((int16x8_t) __a, __b); + } -+#undef TARGET_VECTORIZE_BUILTINS -+#define TARGET_VECTORIZE_BUILTINS -+ -+#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION -+#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ -+ arm_builtin_vectorized_function -+ - #undef TARGET_VECTOR_ALIGNMENT - #define TARGET_VECTOR_ALIGNMENT arm_vector_alignment + __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) + vshrq_n_u32 (uint32x4_t __a, const int __b) + { +- return (uint32x4_t) __builtin_aarch64_ushr_nv4si ((int32x4_t) __a, __b); ++ return (uint32x4_t) __builtin_aarch64_lshrv4si ((int32x4_t) __a, __b); + } -@@ -649,6 +658,13 @@ - #define TARGET_CANONICALIZE_COMPARISON \ - arm_canonicalize_comparison + __extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) + vshrq_n_u64 (uint64x2_t __a, const int __b) + { +- return (uint64x2_t) __builtin_aarch64_ushr_nv2di ((int64x2_t) __a, __b); ++ return (uint64x2_t) __builtin_aarch64_lshrv2di ((int64x2_t) __a, __b); + } -+#undef TARGET_ASAN_SHADOW_OFFSET -+#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset -+ -+#undef MAX_INSN_PER_IT_BLOCK -+#define MAX_INSN_PER_IT_BLOCK (arm_restrict_it ? 1 : 4) -+ -+ - struct gcc_target targetm = TARGET_INITIALIZER; - - /* Obstack for minipool constant handling. */ -@@ -710,6 +726,7 @@ - #define FL_ARCH7 (1 << 22) /* Architecture 7. */ - #define FL_ARM_DIV (1 << 23) /* Hardware divide (ARM mode). */ - #define FL_ARCH8 (1 << 24) /* Architecture 8. */ -+#define FL_CRC32 (1 << 25) /* ARMv8 CRC32 instructions. */ - - #define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */ - #define FL_IWMMXT2 (1 << 30) /* "Intel Wireless MMX2 technology". */ -@@ -839,6 +856,10 @@ - int arm_arch_arm_hwdiv; - int arm_arch_thumb_hwdiv; + __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) + vshrd_n_s64 (int64x1_t __a, const int __b) + { +- return (int64x1_t) __builtin_aarch64_sshr_ndi (__a, __b); ++ return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b); + } -+/* Nonzero if we should use Neon to handle 64-bits operations rather -+ than core registers. */ -+int prefer_neon_for_64bits = 0; -+ - /* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, - we must report the mode of the memory reference from - TARGET_PRINT_OPERAND to TARGET_PRINT_OPERAND_ADDRESS. */ -@@ -868,6 +889,9 @@ - /* The number of bits used in arm_condexec_mask. */ - int arm_condexec_masklen = 0; + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vshrd_n_u64 (uint64x1_t __a, const int __b) + { +- return (uint64x1_t) __builtin_aarch64_ushr_ndi (__a, __b); ++ return (uint64x1_t) __builtin_aarch64_lshrdi (__a, __b); + } -+/* Nonzero if chip supports the ARMv8 CRC instructions. */ -+int arm_arch_crc = 0; -+ - /* The condition codes of the ARM, and the inverse function. */ - static const char * const arm_condition_codes[] = + /* vsli */ +@@ -24153,8 +24393,8 @@ + { + __builtin_aarch64_simd_oi __o; + int64x2x2_t temp; +- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0))); +- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0))); ++ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[1], 1); + __builtin_aarch64_st2di ((__builtin_aarch64_simd_di *) __a, __o); +@@ -24165,8 +24405,8 @@ + { + __builtin_aarch64_simd_oi __o; + uint64x2x2_t temp; +- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0))); +- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0))); ++ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[1], 1); + __builtin_aarch64_st2di ((__builtin_aarch64_simd_di *) __a, __o); +@@ -24177,8 +24417,8 @@ + { + __builtin_aarch64_simd_oi __o; + float64x2x2_t temp; +- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0))); +- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0))); ++ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv2df (__o, (float64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv2df (__o, (float64x2_t) temp.val[1], 1); + __builtin_aarch64_st2df ((__builtin_aarch64_simd_df *) __a, __o); +@@ -24189,8 +24429,8 @@ + { + __builtin_aarch64_simd_oi __o; + int8x16x2_t temp; +- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0))); +- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0))); ++ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1); + __builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o); +@@ -24201,8 +24441,8 @@ + { + __builtin_aarch64_simd_oi __o; + poly8x16x2_t temp; +- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0))); +- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0))); ++ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1); + __builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o); +@@ -24213,8 +24453,8 @@ + { + __builtin_aarch64_simd_oi __o; + int16x8x2_t temp; +- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0))); +- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0))); ++ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1); + __builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o); +@@ -24225,8 +24465,8 @@ + { + __builtin_aarch64_simd_oi __o; + poly16x8x2_t temp; +- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0))); +- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0))); ++ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1); + __builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o); +@@ -24237,8 +24477,8 @@ + { + __builtin_aarch64_simd_oi __o; + int32x4x2_t temp; +- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0))); +- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0))); ++ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[1], 1); + __builtin_aarch64_st2v2si ((__builtin_aarch64_simd_si *) __a, __o); +@@ -24249,8 +24489,8 @@ + { + __builtin_aarch64_simd_oi __o; + uint8x16x2_t temp; +- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0))); +- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0))); ++ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1); + __builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o); +@@ -24261,8 +24501,8 @@ + { + __builtin_aarch64_simd_oi __o; + uint16x8x2_t temp; +- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0))); +- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0))); ++ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1); + __builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o); +@@ -24273,8 +24513,8 @@ + { + __builtin_aarch64_simd_oi __o; + uint32x4x2_t temp; +- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0))); +- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0))); ++ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[1], 1); + __builtin_aarch64_st2v2si ((__builtin_aarch64_simd_si *) __a, __o); +@@ -24285,8 +24525,8 @@ + { + __builtin_aarch64_simd_oi __o; + float32x4x2_t temp; +- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0))); +- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0))); ++ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregoiv4sf (__o, (float32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregoiv4sf (__o, (float32x4_t) temp.val[1], 1); + __builtin_aarch64_st2v2sf ((__builtin_aarch64_simd_sf *) __a, __o); +@@ -24405,9 +24645,9 @@ + { + __builtin_aarch64_simd_ci __o; + int64x2x3_t temp; +- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0))); +- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0))); +- temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (INT64_C (0))); ++ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[2], 2); +@@ -24419,9 +24659,9 @@ + { + __builtin_aarch64_simd_ci __o; + uint64x2x3_t temp; +- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0))); +- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0))); +- temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (UINT64_C (0))); ++ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[2], 2); +@@ -24433,9 +24673,9 @@ + { + __builtin_aarch64_simd_ci __o; + float64x2x3_t temp; +- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0))); +- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0))); +- temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (UINT64_C (0))); ++ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[2], 2); +@@ -24447,9 +24687,9 @@ + { + __builtin_aarch64_simd_ci __o; + int8x16x3_t temp; +- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0))); +- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0))); +- temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (INT64_C (0))); ++ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2); +@@ -24461,9 +24701,9 @@ + { + __builtin_aarch64_simd_ci __o; + poly8x16x3_t temp; +- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0))); +- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0))); +- temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (UINT64_C (0))); ++ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2); +@@ -24475,9 +24715,9 @@ + { + __builtin_aarch64_simd_ci __o; + int16x8x3_t temp; +- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0))); +- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0))); +- temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (INT64_C (0))); ++ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2); +@@ -24489,9 +24729,9 @@ + { + __builtin_aarch64_simd_ci __o; + poly16x8x3_t temp; +- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0))); +- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0))); +- temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (UINT64_C (0))); ++ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2); +@@ -24503,9 +24743,9 @@ + { + __builtin_aarch64_simd_ci __o; + int32x4x3_t temp; +- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0))); +- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0))); +- temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (INT64_C (0))); ++ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[2], 2); +@@ -24517,9 +24757,9 @@ + { + __builtin_aarch64_simd_ci __o; + uint8x16x3_t temp; +- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0))); +- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0))); +- temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (UINT64_C (0))); ++ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2); +@@ -24531,9 +24771,9 @@ + { + __builtin_aarch64_simd_ci __o; + uint16x8x3_t temp; +- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0))); +- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0))); +- temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (UINT64_C (0))); ++ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2); +@@ -24545,9 +24785,9 @@ + { + __builtin_aarch64_simd_ci __o; + uint32x4x3_t temp; +- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0))); +- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0))); +- temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (UINT64_C (0))); ++ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[2], 2); +@@ -24559,9 +24799,9 @@ + { + __builtin_aarch64_simd_ci __o; + float32x4x3_t temp; +- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0))); +- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0))); +- temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (UINT64_C (0))); ++ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[2], 2); +@@ -24693,10 +24933,10 @@ + { + __builtin_aarch64_simd_xi __o; + int64x2x4_t temp; +- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0))); +- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0))); +- temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (INT64_C (0))); +- temp.val[3] = vcombine_s64 (val.val[3], vcreate_s64 (INT64_C (0))); ++ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (__AARCH64_INT64_C (0))); ++ temp.val[3] = vcombine_s64 (val.val[3], vcreate_s64 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[2], 2); +@@ -24709,10 +24949,10 @@ + { + __builtin_aarch64_simd_xi __o; + uint64x2x4_t temp; +- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0))); +- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0))); +- temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (UINT64_C (0))); +- temp.val[3] = vcombine_u64 (val.val[3], vcreate_u64 (UINT64_C (0))); ++ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_u64 (val.val[3], vcreate_u64 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[2], 2); +@@ -24725,10 +24965,10 @@ + { + __builtin_aarch64_simd_xi __o; + float64x2x4_t temp; +- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0))); +- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0))); +- temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (UINT64_C (0))); +- temp.val[3] = vcombine_f64 (val.val[3], vcreate_f64 (UINT64_C (0))); ++ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_f64 (val.val[3], vcreate_f64 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[2], 2); +@@ -24741,10 +24981,10 @@ + { + __builtin_aarch64_simd_xi __o; + int8x16x4_t temp; +- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0))); +- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0))); +- temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (INT64_C (0))); +- temp.val[3] = vcombine_s8 (val.val[3], vcreate_s8 (INT64_C (0))); ++ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (__AARCH64_INT64_C (0))); ++ temp.val[3] = vcombine_s8 (val.val[3], vcreate_s8 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2); +@@ -24757,10 +24997,10 @@ + { + __builtin_aarch64_simd_xi __o; + poly8x16x4_t temp; +- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0))); +- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0))); +- temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (UINT64_C (0))); +- temp.val[3] = vcombine_p8 (val.val[3], vcreate_p8 (UINT64_C (0))); ++ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_p8 (val.val[3], vcreate_p8 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2); +@@ -24773,10 +25013,10 @@ { -@@ -936,6 +960,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - const struct tune_params arm_fastmul_tune = -@@ -950,6 +975,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - /* StrongARM has early execution of branches, so a sequence that is worth -@@ -967,6 +993,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - const struct tune_params arm_xscale_tune = -@@ -981,6 +1008,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - const struct tune_params arm_9e_tune = -@@ -995,6 +1023,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - const struct tune_params arm_v6t2_tune = -@@ -1009,6 +1038,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - /* Generic Cortex tuning. Use more specific tunings if appropriate. */ -@@ -1024,6 +1054,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - const struct tune_params arm_cortex_a15_tune = -@@ -1031,7 +1062,7 @@ - arm_9e_rtx_costs, - NULL, - 1, /* Constant limit. */ -- 5, /* Max cond insns. */ -+ 2, /* Max cond insns. */ - ARM_PREFETCH_NOT_BENEFICIAL, - false, /* Prefer constant pool. */ - arm_default_branch_cost, -@@ -1038,6 +1069,7 @@ - true, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - /* Branches can be dual-issued on Cortex-A5, so conditional execution is -@@ -1055,6 +1087,7 @@ - false, /* Prefer LDRD/STRD. */ - {false, false}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - const struct tune_params arm_cortex_a9_tune = -@@ -1069,6 +1102,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - /* The arm_v6m_tune is duplicated from arm_cortex_tune, rather than -@@ -1085,6 +1119,7 @@ - false, /* Prefer LDRD/STRD. */ - {false, false}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - const struct tune_params arm_fa726te_tune = -@@ -1099,6 +1134,7 @@ - false, /* Prefer LDRD/STRD. */ - {true, true}, /* Prefer non short circuit. */ - &arm_default_vec_cost, /* Vectorizer costs. */ -+ false /* Prefer Neon for 64-bits bitops. */ - }; - - -@@ -1842,7 +1878,13 @@ - arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0; - arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0; - arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0; -+ arm_arch_crc = (insn_flags & FL_CRC32) != 0; -+ if (arm_restrict_it == 2) -+ arm_restrict_it = arm_arch8 && TARGET_THUMB2; - -+ if (!TARGET_THUMB2) -+ arm_restrict_it = 0; -+ - /* If we are not using the default (ARM mode) section anchor offset - ranges, then set the correct ranges now. */ - if (TARGET_THUMB1) -@@ -2129,11 +2171,25 @@ - global_options.x_param_values, - global_options_set.x_param_values); - -+ /* Use Neon to perform 64-bits operations rather than core -+ registers. */ -+ prefer_neon_for_64bits = current_tune->prefer_neon_for_64bits; -+ if (use_neon_for_64bits == 1) -+ prefer_neon_for_64bits = true; -+ - /* Use the alternative scheduling-pressure algorithm by default. */ - maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2, - global_options.x_param_values, - global_options_set.x_param_values); - -+ /* Disable shrink-wrap when optimizing function for size, since it tends to -+ generate additional returns. */ -+ if (optimize_function_for_size_p (cfun) && TARGET_THUMB2) -+ flag_shrink_wrap = false; -+ /* TBD: Dwarf info for apcs frame is not handled yet. */ -+ if (TARGET_APCS_FRAME) -+ flag_shrink_wrap = false; -+ - /* Register global variables with the garbage collector. */ - arm_add_gc_roots (); - } -@@ -2382,6 +2438,10 @@ - if (IS_INTERRUPT (func_type) && (frame_pointer_needed || TARGET_THUMB)) - return 0; - -+ if (TARGET_LDRD && current_tune->prefer_ldrd_strd -+ && !optimize_function_for_size_p (cfun)) -+ return 0; -+ - offsets = arm_get_frame_offsets (); - stack_adjust = offsets->outgoing_args - offsets->saved_regs; - -@@ -2479,6 +2539,18 @@ - return 1; - } - -+/* Return TRUE if we should try to use a simple_return insn, i.e. perform -+ shrink-wrapping if possible. This is the case if we need to emit a -+ prologue, which we can test by looking at the offsets. */ -+bool -+use_simple_return_p (void) -+{ -+ arm_stack_offsets *offsets; -+ -+ offsets = arm_get_frame_offsets (); -+ return offsets->outgoing_args != 0; -+} -+ - /* Return TRUE if int I is a valid immediate ARM constant. */ - - int -@@ -2617,6 +2689,11 @@ - - switch (code) - { -+ case AND: -+ case IOR: -+ case XOR: -+ return (const_ok_for_op (hi_val, code) || hi_val == 0xFFFFFFFF) -+ && (const_ok_for_op (lo_val, code) || lo_val == 0xFFFFFFFF); - case PLUS: - return arm_not_operand (hi, SImode) && arm_add_operand (lo, SImode); - -@@ -5337,9 +5414,8 @@ - if (cfun->machine->sibcall_blocked) - return false; - -- /* Never tailcall something for which we have no decl, or if we -- are generating code for Thumb-1. */ -- if (decl == NULL || TARGET_THUMB1) -+ /* Never tailcall something if we are generating code for Thumb-1. */ -+ if (TARGET_THUMB1) - return false; - - /* The PIC register is live on entry to VxWorks PLT entries, so we -@@ -5349,13 +5425,14 @@ - - /* Cannot tail-call to long calls, since these are out of range of - a branch instruction. */ -- if (arm_is_long_call_p (decl)) -+ if (decl && arm_is_long_call_p (decl)) - return false; - - /* If we are interworking and the function is not declared static - then we can't tail-call it unless we know that it exists in this - compilation unit (since it might be a Thumb routine). */ -- if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl)) -+ if (TARGET_INTERWORK && decl && TREE_PUBLIC (decl) -+ && !TREE_ASM_WRITTEN (decl)) - return false; - - func_type = arm_current_func_type (); -@@ -5387,6 +5464,7 @@ - sibling calls. */ - if (TARGET_AAPCS_BASED - && arm_abi == ARM_ABI_AAPCS -+ && decl - && DECL_WEAK (decl)) - return false; - -@@ -8592,7 +8670,12 @@ - instruction we depend on is another ALU instruction, then we may - have to account for an additional stall. */ - if (shift_opnum != 0 -- && (attr_type == TYPE_ALU_SHIFT || attr_type == TYPE_ALU_SHIFT_REG)) -+ && (attr_type == TYPE_ARLO_SHIFT -+ || attr_type == TYPE_ARLO_SHIFT_REG -+ || attr_type == TYPE_MOV_SHIFT -+ || attr_type == TYPE_MVN_SHIFT -+ || attr_type == TYPE_MOV_SHIFT_REG -+ || attr_type == TYPE_MVN_SHIFT_REG)) - { - rtx shifted_operand; - int opno; -@@ -8873,12 +8956,12 @@ - if (recog_memoized (insn) < 0) - return false; - -- if (get_attr_insn (insn) == INSN_MOV) -- return false; -- - switch (get_attr_type (insn)) - { -- case TYPE_ALU_REG: -+ case TYPE_ARLO_REG: -+ case TYPE_MVN_REG: -+ case TYPE_SHIFT: -+ case TYPE_SHIFT_REG: - case TYPE_LOAD_BYTE: - case TYPE_LOAD1: - case TYPE_STORE1: -@@ -8919,13 +9002,15 @@ - return false; - } - -- if (get_attr_insn (insn) == INSN_MOV) -- return true; -- - switch (get_attr_type (insn)) - { -- case TYPE_SIMPLE_ALU_IMM: -- case TYPE_SIMPLE_ALU_SHIFT: -+ case TYPE_ARLO_IMM: -+ case TYPE_EXTEND: -+ case TYPE_MVN_IMM: -+ case TYPE_MOV_IMM: -+ case TYPE_MOV_REG: -+ case TYPE_MOV_SHIFT: -+ case TYPE_MOV_SHIFT_REG: - case TYPE_BRANCH: - case TYPE_CALL: - return true; -@@ -9084,6 +9169,12 @@ - return cost; - } - -+int -+arm_max_conditional_execute (void) -+{ -+ return max_insns_skipped; -+} -+ - static int - arm_default_branch_cost (bool speed_p, bool predictable_p ATTRIBUTE_UNUSED) + __builtin_aarch64_simd_xi __o; + int16x8x4_t temp; +- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0))); +- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0))); +- temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (INT64_C (0))); +- temp.val[3] = vcombine_s16 (val.val[3], vcreate_s16 (INT64_C (0))); ++ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (__AARCH64_INT64_C (0))); ++ temp.val[3] = vcombine_s16 (val.val[3], vcreate_s16 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2); +@@ -24789,10 +25029,10 @@ { -@@ -11839,6 +11930,142 @@ - return 1; + __builtin_aarch64_simd_xi __o; + poly16x8x4_t temp; +- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0))); +- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0))); +- temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (UINT64_C (0))); +- temp.val[3] = vcombine_p16 (val.val[3], vcreate_p16 (UINT64_C (0))); ++ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_p16 (val.val[3], vcreate_p16 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2); +@@ -24805,10 +25045,10 @@ + { + __builtin_aarch64_simd_xi __o; + int32x4x4_t temp; +- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0))); +- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0))); +- temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (INT64_C (0))); +- temp.val[3] = vcombine_s32 (val.val[3], vcreate_s32 (INT64_C (0))); ++ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0))); ++ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0))); ++ temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (__AARCH64_INT64_C (0))); ++ temp.val[3] = vcombine_s32 (val.val[3], vcreate_s32 (__AARCH64_INT64_C (0))); + __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[2], 2); +@@ -24821,10 +25061,10 @@ + { + __builtin_aarch64_simd_xi __o; + uint8x16x4_t temp; +- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0))); +- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0))); +- temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (UINT64_C (0))); +- temp.val[3] = vcombine_u8 (val.val[3], vcreate_u8 (UINT64_C (0))); ++ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_u8 (val.val[3], vcreate_u8 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2); +@@ -24837,10 +25077,10 @@ + { + __builtin_aarch64_simd_xi __o; + uint16x8x4_t temp; +- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0))); +- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0))); +- temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (UINT64_C (0))); +- temp.val[3] = vcombine_u16 (val.val[3], vcreate_u16 (UINT64_C (0))); ++ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_u16 (val.val[3], vcreate_u16 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2); +@@ -24853,10 +25093,10 @@ + { + __builtin_aarch64_simd_xi __o; + uint32x4x4_t temp; +- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0))); +- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0))); +- temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (UINT64_C (0))); +- temp.val[3] = vcombine_u32 (val.val[3], vcreate_u32 (UINT64_C (0))); ++ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_u32 (val.val[3], vcreate_u32 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[2], 2); +@@ -24869,10 +25109,10 @@ + { + __builtin_aarch64_simd_xi __o; + float32x4x4_t temp; +- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0))); +- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0))); +- temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (UINT64_C (0))); +- temp.val[3] = vcombine_f32 (val.val[3], vcreate_f32 (UINT64_C (0))); ++ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0))); ++ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0))); ++ temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (__AARCH64_UINT64_C (0))); ++ temp.val[3] = vcombine_f32 (val.val[3], vcreate_f32 (__AARCH64_UINT64_C (0))); + __o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[0], 0); + __o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[1], 1); + __o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[2], 2); +@@ -25159,7 +25399,7 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vtst_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmtstdi (__a, __b); ++ return (__a & __b) ? -1ll : 0ll; } -+/* Helper for gen_movmem_ldrd_strd. Increase the address of memory rtx -+by mode size. */ -+inline static rtx -+next_consecutive_mem (rtx mem) -+{ -+ enum machine_mode mode = GET_MODE (mem); -+ HOST_WIDE_INT offset = GET_MODE_SIZE (mode); -+ rtx addr = plus_constant (Pmode, XEXP (mem, 0), offset); -+ -+ return adjust_automodify_address (mem, mode, addr, offset); -+} -+ -+/* Copy using LDRD/STRD instructions whenever possible. -+ Returns true upon success. */ -+bool -+gen_movmem_ldrd_strd (rtx *operands) -+{ -+ unsigned HOST_WIDE_INT len; -+ HOST_WIDE_INT align; -+ rtx src, dst, base; -+ rtx reg0; -+ bool src_aligned, dst_aligned; -+ bool src_volatile, dst_volatile; -+ -+ gcc_assert (CONST_INT_P (operands[2])); -+ gcc_assert (CONST_INT_P (operands[3])); -+ -+ len = UINTVAL (operands[2]); -+ if (len > 64) -+ return false; -+ -+ /* Maximum alignment we can assume for both src and dst buffers. */ -+ align = INTVAL (operands[3]); -+ -+ if ((!unaligned_access) && (len >= 4) && ((align & 3) != 0)) -+ return false; -+ -+ /* Place src and dst addresses in registers -+ and update the corresponding mem rtx. */ -+ dst = operands[0]; -+ dst_volatile = MEM_VOLATILE_P (dst); -+ dst_aligned = MEM_ALIGN (dst) >= BITS_PER_WORD; -+ base = copy_to_mode_reg (SImode, XEXP (dst, 0)); -+ dst = adjust_automodify_address (dst, VOIDmode, base, 0); -+ -+ src = operands[1]; -+ src_volatile = MEM_VOLATILE_P (src); -+ src_aligned = MEM_ALIGN (src) >= BITS_PER_WORD; -+ base = copy_to_mode_reg (SImode, XEXP (src, 0)); -+ src = adjust_automodify_address (src, VOIDmode, base, 0); -+ -+ if (!unaligned_access && !(src_aligned && dst_aligned)) -+ return false; -+ -+ if (src_volatile || dst_volatile) -+ return false; -+ -+ /* If we cannot generate any LDRD/STRD, try to generate LDM/STM. */ -+ if (!(dst_aligned || src_aligned)) -+ return arm_gen_movmemqi (operands); -+ -+ src = adjust_address (src, DImode, 0); -+ dst = adjust_address (dst, DImode, 0); -+ while (len >= 8) -+ { -+ len -= 8; -+ reg0 = gen_reg_rtx (DImode); -+ if (src_aligned) -+ emit_move_insn (reg0, src); -+ else -+ emit_insn (gen_unaligned_loaddi (reg0, src)); -+ -+ if (dst_aligned) -+ emit_move_insn (dst, reg0); -+ else -+ emit_insn (gen_unaligned_storedi (dst, reg0)); -+ -+ src = next_consecutive_mem (src); -+ dst = next_consecutive_mem (dst); -+ } -+ -+ gcc_assert (len < 8); -+ if (len >= 4) -+ { -+ /* More than a word but less than a double-word to copy. Copy a word. */ -+ reg0 = gen_reg_rtx (SImode); -+ src = adjust_address (src, SImode, 0); -+ dst = adjust_address (dst, SImode, 0); -+ if (src_aligned) -+ emit_move_insn (reg0, src); -+ else -+ emit_insn (gen_unaligned_loadsi (reg0, src)); -+ -+ if (dst_aligned) -+ emit_move_insn (dst, reg0); -+ else -+ emit_insn (gen_unaligned_storesi (dst, reg0)); -+ -+ src = next_consecutive_mem (src); -+ dst = next_consecutive_mem (dst); -+ len -= 4; -+ } -+ -+ if (len == 0) -+ return true; -+ -+ /* Copy the remaining bytes. */ -+ if (len >= 2) -+ { -+ dst = adjust_address (dst, HImode, 0); -+ src = adjust_address (src, HImode, 0); -+ reg0 = gen_reg_rtx (SImode); -+ if (src_aligned) -+ emit_insn (gen_zero_extendhisi2 (reg0, src)); -+ else -+ emit_insn (gen_unaligned_loadhiu (reg0, src)); -+ -+ if (dst_aligned) -+ emit_insn (gen_movhi (dst, gen_lowpart(HImode, reg0))); -+ else -+ emit_insn (gen_unaligned_storehi (dst, gen_lowpart (HImode, reg0))); -+ -+ src = next_consecutive_mem (src); -+ dst = next_consecutive_mem (dst); -+ if (len == 2) -+ return true; -+ } -+ -+ dst = adjust_address (dst, QImode, 0); -+ src = adjust_address (src, QImode, 0); -+ reg0 = gen_reg_rtx (QImode); -+ emit_move_insn (reg0, src); -+ emit_move_insn (dst, reg0); -+ return true; -+} -+ - /* Select a dominance comparison mode if possible for a test of the general - form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms. - COND_OR == DOM_CC_X_AND_Y => (X && Y) -@@ -12639,6 +12866,277 @@ - return true; + __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) +@@ -25186,8 +25426,7 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vtst_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmtstdi ((int64x1_t) __a, +- (int64x1_t) __b); ++ return (__a & __b) ? -1ll : 0ll; } -+/* Helper for gen_operands_ldrd_strd. Returns true iff the memory -+ operand ADDR is an immediate offset from the base register and is -+ not volatile, in which case it sets BASE and OFFSET -+ accordingly. */ -+bool -+mem_ok_for_ldrd_strd (rtx addr, rtx *base, rtx *offset) -+{ -+ /* TODO: Handle more general memory operand patterns, such as -+ PRE_DEC and PRE_INC. */ -+ -+ /* Convert a subreg of mem into mem itself. */ -+ if (GET_CODE (addr) == SUBREG) -+ addr = alter_subreg (&addr, true); -+ -+ gcc_assert (MEM_P (addr)); -+ -+ /* Don't modify volatile memory accesses. */ -+ if (MEM_VOLATILE_P (addr)) -+ return false; -+ -+ *offset = const0_rtx; -+ -+ addr = XEXP (addr, 0); -+ if (REG_P (addr)) -+ { -+ *base = addr; -+ return true; -+ } -+ else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS) -+ { -+ *base = XEXP (addr, 0); -+ *offset = XEXP (addr, 1); -+ return (REG_P (*base) && CONST_INT_P (*offset)); -+ } -+ -+ return false; -+} + __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) +@@ -25245,14 +25484,13 @@ + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vtstd_s64 (int64x1_t __a, int64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmtstdi (__a, __b); ++ return (__a & __b) ? -1ll : 0ll; + } + + __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) + vtstd_u64 (uint64x1_t __a, uint64x1_t __b) + { +- return (uint64x1_t) __builtin_aarch64_cmtstdi ((int64x1_t) __a, +- (int64x1_t) __b); ++ return (__a & __b) ? -1ll : 0ll; + } + + /* vuqadd */ +@@ -25371,4 +25609,31 @@ + + /* End of optimal implementations in approved order. */ + ++#undef __aarch64_vget_lane_any ++#undef __aarch64_vget_lane_f32 ++#undef __aarch64_vget_lane_f64 ++#undef __aarch64_vget_lane_p8 ++#undef __aarch64_vget_lane_p16 ++#undef __aarch64_vget_lane_s8 ++#undef __aarch64_vget_lane_s16 ++#undef __aarch64_vget_lane_s32 ++#undef __aarch64_vget_lane_s64 ++#undef __aarch64_vget_lane_u8 ++#undef __aarch64_vget_lane_u16 ++#undef __aarch64_vget_lane_u32 ++#undef __aarch64_vget_lane_u64 + -+#define SWAP_RTX(x,y) do { rtx tmp = x; x = y; y = tmp; } while (0) ++#undef __aarch64_vgetq_lane_f32 ++#undef __aarch64_vgetq_lane_f64 ++#undef __aarch64_vgetq_lane_p8 ++#undef __aarch64_vgetq_lane_p16 ++#undef __aarch64_vgetq_lane_s8 ++#undef __aarch64_vgetq_lane_s16 ++#undef __aarch64_vgetq_lane_s32 ++#undef __aarch64_vgetq_lane_s64 ++#undef __aarch64_vgetq_lane_u8 ++#undef __aarch64_vgetq_lane_u16 ++#undef __aarch64_vgetq_lane_u32 ++#undef __aarch64_vgetq_lane_u64 + -+/* Called from a peephole2 to replace two word-size accesses with a -+ single LDRD/STRD instruction. Returns true iff we can generate a -+ new instruction sequence. That is, both accesses use the same base -+ register and the gap between constant offsets is 4. This function -+ may reorder its operands to match ldrd/strd RTL templates. -+ OPERANDS are the operands found by the peephole matcher; -+ OPERANDS[0,1] are register operands, and OPERANDS[2,3] are the -+ corresponding memory operands. LOAD indicaates whether the access -+ is load or store. CONST_STORE indicates a store of constant -+ integer values held in OPERANDS[4,5] and assumes that the pattern -+ is of length 4 insn, for the purpose of checking dead registers. -+ COMMUTE indicates that register operands may be reordered. */ -+bool -+gen_operands_ldrd_strd (rtx *operands, bool load, -+ bool const_store, bool commute) + #endif +--- a/src/gcc/config/aarch64/aarch64.md ++++ b/src/gcc/config/aarch64/aarch64.md +@@ -68,14 +68,19 @@ + (define_c_enum "unspec" [ + UNSPEC_CASESI + UNSPEC_CLS ++ UNSPEC_FRECPE ++ UNSPEC_FRECPS ++ UNSPEC_FRECPX + UNSPEC_FRINTA + UNSPEC_FRINTI + UNSPEC_FRINTM ++ UNSPEC_FRINTN + UNSPEC_FRINTP + UNSPEC_FRINTX + UNSPEC_FRINTZ + UNSPEC_GOTSMALLPIC + UNSPEC_GOTSMALLTLS ++ UNSPEC_GOTTINYPIC + UNSPEC_LD2 + UNSPEC_LD3 + UNSPEC_LD4 +@@ -230,6 +235,9 @@ + fmovf2i,\ + fmovi2f,\ + fmul,\ ++ frecpe,\ ++ frecps,\ ++ frecpx,\ + frint,\ + fsqrt,\ + load_acq,\ +@@ -763,19 +771,41 @@ + ) + + (define_insn "*mov_aarch64" +- [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,r,m, r,*w") +- (match_operand:SHORT 1 "general_operand" " r,M,m,rZ,*w,r"))] ++ [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w") ++ (match_operand:SHORT 1 "general_operand" " r,M,D,m, m,rZ,*w,*w, r,*w"))] + "(register_operand (operands[0], mode) + || aarch64_reg_or_zero (operands[1], mode))" +- "@ +- mov\\t%w0, %w1 +- mov\\t%w0, %1 +- ldr\\t%w0, %1 +- str\\t%w1, %0 +- umov\\t%w0, %1.[0] +- dup\\t%0., %w1" +- [(set_attr "v8type" "move,alu,load1,store1,*,*") +- (set_attr "simd_type" "*,*,*,*,simd_movgp,simd_dupgp") +{ -+ int nops = 2; -+ HOST_WIDE_INT offsets[2], offset; -+ rtx base = NULL_RTX; -+ rtx cur_base, cur_offset, tmp; -+ int i, gap; -+ HARD_REG_SET regset; -+ -+ gcc_assert (!const_store || !load); -+ /* Check that the memory references are immediate offsets from the -+ same base register. Extract the base register, the destination -+ registers, and the corresponding memory offsets. */ -+ for (i = 0; i < nops; i++) -+ { -+ if (!mem_ok_for_ldrd_strd (operands[nops+i], &cur_base, &cur_offset)) -+ return false; -+ -+ if (i == 0) -+ base = cur_base; -+ else if (REGNO (base) != REGNO (cur_base)) -+ return false; -+ -+ offsets[i] = INTVAL (cur_offset); -+ if (GET_CODE (operands[i]) == SUBREG) -+ { -+ tmp = SUBREG_REG (operands[i]); -+ gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp)); -+ operands[i] = tmp; -+ } -+ } -+ -+ /* Make sure there is no dependency between the individual loads. */ -+ if (load && REGNO (operands[0]) == REGNO (base)) -+ return false; /* RAW */ ++ switch (which_alternative) ++ { ++ case 0: ++ return "mov\t%w0, %w1"; ++ case 1: ++ return "mov\t%w0, %1"; ++ case 2: ++ return aarch64_output_scalar_simd_mov_immediate (operands[1], ++ mode); ++ case 3: ++ return "ldr\t%w0, %1"; ++ case 4: ++ return "ldr\t%0, %1"; ++ case 5: ++ return "str\t%w1, %0"; ++ case 6: ++ return "str\t%1, %0"; ++ case 7: ++ return "umov\t%w0, %1.[0]"; ++ case 8: ++ return "dup\t%0., %w1"; ++ case 9: ++ return "dup\t%0, %1.[0]"; ++ default: ++ gcc_unreachable (); ++ } ++} ++ [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*") ++ (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup") ++ (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes") + (set_attr "mode" "") + (set_attr "simd_mode" "")] + ) +@@ -797,26 +827,28 @@ + ) + + (define_insn "*movsi_aarch64" +- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w") +- (match_operand:SI 1 "aarch64_mov_operand" " r,M,m,rZ,rZ,*w,*w"))] ++ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,*w,m, m,*w, r,*w") ++ (match_operand:SI 1 "aarch64_mov_operand" " r,M,m, m,rZ,*w,rZ,*w,*w"))] + "(register_operand (operands[0], SImode) + || aarch64_reg_or_zero (operands[1], SImode))" + "@ + mov\\t%w0, %w1 + mov\\t%w0, %1 + ldr\\t%w0, %1 ++ ldr\\t%s0, %1 + str\\t%w1, %0 ++ str\\t%s1, %0 + fmov\\t%s0, %w1 + fmov\\t%w0, %s1 + fmov\\t%s0, %s1" +- [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov") ++ [(set_attr "v8type" "move,alu,load1,load1,store1,store1,fmov,fmov,fmov") + (set_attr "mode" "SI") +- (set_attr "fp" "*,*,*,*,yes,yes,yes")] ++ (set_attr "fp" "*,*,*,yes,*,yes,yes,yes,yes")] + ) + + (define_insn "*movdi_aarch64" +- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r, r, *w, r,*w,w") +- (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))] ++ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w") ++ (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))] + "(register_operand (operands[0], DImode) + || aarch64_reg_or_zero (operands[1], DImode))" + "@ +@@ -825,17 +857,19 @@ + mov\\t%x0, %1 + mov\\t%x0, %1 + ldr\\t%x0, %1 ++ ldr\\t%d0, %1 + str\\t%x1, %0 ++ str\\t%d1, %0 + adr\\t%x0, %a1 + adrp\\t%x0, %A1 + fmov\\t%d0, %x1 + fmov\\t%x0, %d1 + fmov\\t%d0, %d1 + movi\\t%d0, %1" +- [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov") ++ [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov") + (set_attr "mode" "DI") +- (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,*") +- (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,yes")] ++ (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*") ++ (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")] + ) + + (define_insn "insv_imm" +@@ -843,9 +877,8 @@ + (const_int 16) + (match_operand:GPI 1 "const_int_operand" "n")) + (match_operand:GPI 2 "const_int_operand" "n"))] +- "INTVAL (operands[1]) < GET_MODE_BITSIZE (mode) +- && INTVAL (operands[1]) % 16 == 0 +- && UINTVAL (operands[2]) <= 0xffff" ++ "UINTVAL (operands[1]) < GET_MODE_BITSIZE (mode) ++ && UINTVAL (operands[1]) % 16 == 0" + "movk\\t%0, %X2, lsl %1" + [(set_attr "v8type" "movk") + (set_attr "mode" "")] +@@ -982,9 +1015,9 @@ + || register_operand (operands[1], TFmode))" + "@ + orr\\t%0.16b, %1.16b, %1.16b +- mov\\t%0, %1\;mov\\t%H0, %H1 +- fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1 +- fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1] ++ # ++ # ++ # + movi\\t%0.2d, #0 + fmov\\t%s0, wzr + ldr\\t%q0, %1 +@@ -998,6 +1031,17 @@ + (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")] + ) + ++(define_split ++ [(set (match_operand:TF 0 "register_operand" "") ++ (match_operand:TF 1 "aarch64_reg_or_imm" ""))] ++ "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])" ++ [(const_int 0)] ++ { ++ aarch64_split_128bit_move (operands[0], operands[1]); ++ DONE; ++ } ++) + -+ if (load && REGNO (operands[0]) == REGNO (operands[1])) -+ return false; /* WAW */ + ;; Operands 1 and 3 are tied together by the final condition; so we allow + ;; fairly lax checking on the second memory operation. + (define_insn "load_pair" +@@ -1150,13 +1194,14 @@ + ) + + (define_insn "*zero_extend2_aarch64" +- [(set (match_operand:GPI 0 "register_operand" "=r,r") +- (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))] ++ [(set (match_operand:GPI 0 "register_operand" "=r,r,*w") ++ (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))] + "" + "@ + uxt\t%0, %w1 +- ldr\t%w0, %1" +- [(set_attr "v8type" "extend,load1") ++ ldr\t%w0, %1 ++ ldr\t%0, %1" ++ [(set_attr "v8type" "extend,load1,load1") + (set_attr "mode" "")] + ) + +@@ -1287,6 +1332,112 @@ + (set_attr "mode" "SI")] + ) + ++(define_insn "*adds_mul_imm_" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (plus:GPI (mult:GPI ++ (match_operand:GPI 1 "register_operand" "r") ++ (match_operand:QI 2 "aarch64_pwr_2_" "n")) ++ (match_operand:GPI 3 "register_operand" "rk")) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (plus:GPI (mult:GPI (match_dup 1) (match_dup 2)) ++ (match_dup 3)))] ++ "" ++ "adds\\t%0, %3, %1, lsl %p2" ++ [(set_attr "v8type" "alus_shift") ++ (set_attr "mode" "")] ++) + -+ /* If the same input register is used in both stores -+ when storing different constants, try to find a free register. -+ For example, the code -+ mov r0, 0 -+ str r0, [r2] -+ mov r0, 1 -+ str r0, [r2, #4] -+ can be transformed into -+ mov r1, 0 -+ strd r1, r0, [r2] -+ in Thumb mode assuming that r1 is free. */ -+ if (const_store -+ && REGNO (operands[0]) == REGNO (operands[1]) -+ && INTVAL (operands[4]) != INTVAL (operands[5])) -+ { -+ if (TARGET_THUMB2) -+ { -+ CLEAR_HARD_REG_SET (regset); -+ tmp = peep2_find_free_register (0, 4, "r", SImode, ®set); -+ if (tmp == NULL_RTX) -+ return false; ++(define_insn "*subs_mul_imm_" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (minus:GPI (match_operand:GPI 1 "register_operand" "rk") ++ (mult:GPI ++ (match_operand:GPI 2 "register_operand" "r") ++ (match_operand:QI 3 "aarch64_pwr_2_" "n"))) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (minus:GPI (match_dup 1) ++ (mult:GPI (match_dup 2) (match_dup 3))))] ++ "" ++ "subs\\t%0, %1, %2, lsl %p3" ++ [(set_attr "v8type" "alus_shift") ++ (set_attr "mode" "")] ++) + -+ /* Use the new register in the first load to ensure that -+ if the original input register is not dead after peephole, -+ then it will have the correct constant value. */ -+ operands[0] = tmp; -+ } -+ else if (TARGET_ARM) -+ { -+ return false; -+ int regno = REGNO (operands[0]); -+ if (!peep2_reg_dead_p (4, operands[0])) -+ { -+ /* When the input register is even and is not dead after the -+ pattern, it has to hold the second constant but we cannot -+ form a legal STRD in ARM mode with this register as the second -+ register. */ -+ if (regno % 2 == 0) -+ return false; ++(define_insn "*adds__" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (plus:GPI ++ (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r")) ++ (match_operand:GPI 2 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))] ++ "" ++ "adds\\t%0, %2, %1, xt" ++ [(set_attr "v8type" "alus_ext") ++ (set_attr "mode" "")] ++) + -+ /* Is regno-1 free? */ -+ SET_HARD_REG_SET (regset); -+ CLEAR_HARD_REG_BIT(regset, regno - 1); -+ tmp = peep2_find_free_register (0, 4, "r", SImode, ®set); -+ if (tmp == NULL_RTX) -+ return false; ++(define_insn "*subs__" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (minus:GPI (match_operand:GPI 1 "register_operand" "r") ++ (ANY_EXTEND:GPI ++ (match_operand:ALLX 2 "register_operand" "r"))) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))] ++ "" ++ "subs\\t%0, %1, %2, xt" ++ [(set_attr "v8type" "alus_ext") ++ (set_attr "mode" "")] ++) + -+ operands[0] = tmp; -+ } -+ else -+ { -+ /* Find a DImode register. */ -+ CLEAR_HARD_REG_SET (regset); -+ tmp = peep2_find_free_register (0, 4, "r", DImode, ®set); -+ if (tmp != NULL_RTX) -+ { -+ operands[0] = simplify_gen_subreg (SImode, tmp, DImode, 0); -+ operands[1] = simplify_gen_subreg (SImode, tmp, DImode, 4); -+ } -+ else -+ { -+ /* Can we use the input register to form a DI register? */ -+ SET_HARD_REG_SET (regset); -+ CLEAR_HARD_REG_BIT(regset, -+ regno % 2 == 0 ? regno + 1 : regno - 1); -+ tmp = peep2_find_free_register (0, 4, "r", SImode, ®set); -+ if (tmp == NULL_RTX) -+ return false; -+ operands[regno % 2 == 1 ? 0 : 1] = tmp; -+ } -+ } ++(define_insn "*adds__multp2" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (plus:GPI (ANY_EXTRACT:GPI ++ (mult:GPI (match_operand:GPI 1 "register_operand" "r") ++ (match_operand 2 "aarch64_pwr_imm3" "Up3")) ++ (match_operand 3 "const_int_operand" "n") ++ (const_int 0)) ++ (match_operand:GPI 4 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2)) ++ (match_dup 3) ++ (const_int 0)) ++ (match_dup 4)))] ++ "aarch64_is_extend_from_extract (mode, operands[2], operands[3])" ++ "adds\\t%0, %4, %1, xt%e3 %p2" ++ [(set_attr "v8type" "alus_ext") ++ (set_attr "mode" "")] ++) + -+ gcc_assert (operands[0] != NULL_RTX); -+ gcc_assert (operands[1] != NULL_RTX); -+ gcc_assert (REGNO (operands[0]) % 2 == 0); -+ gcc_assert (REGNO (operands[1]) == REGNO (operands[0]) + 1); -+ } -+ } ++(define_insn "*subs__multp2" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (minus:GPI (match_operand:GPI 4 "register_operand" "r") ++ (ANY_EXTRACT:GPI ++ (mult:GPI (match_operand:GPI 1 "register_operand" "r") ++ (match_operand 2 "aarch64_pwr_imm3" "Up3")) ++ (match_operand 3 "const_int_operand" "n") ++ (const_int 0))) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI ++ (mult:GPI (match_dup 1) (match_dup 2)) ++ (match_dup 3) ++ (const_int 0))))] ++ "aarch64_is_extend_from_extract (mode, operands[2], operands[3])" ++ "subs\\t%0, %4, %1, xt%e3 %p2" ++ [(set_attr "v8type" "alus_ext") ++ (set_attr "mode" "")] ++) + -+ /* Make sure the instructions are ordered with lower memory access first. */ -+ if (offsets[0] > offsets[1]) -+ { -+ gap = offsets[0] - offsets[1]; -+ offset = offsets[1]; + (define_insn "*add3nr_compare0" + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ +@@ -1302,12 +1453,12 @@ + ) + + (define_insn "*compare_neg" +- [(set (reg:CC CC_REGNUM) +- (compare:CC +- (match_operand:GPI 0 "register_operand" "r") +- (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))] ++ [(set (reg:CC_SWP CC_REGNUM) ++ (compare:CC_SWP ++ (neg:GPI (match_operand:GPI 0 "register_operand" "r")) ++ (match_operand:GPI 1 "register_operand" "r")))] + "" +- "cmn\\t%0, %1" ++ "cmn\\t%1, %0" + [(set_attr "v8type" "alus") + (set_attr "mode" "")] + ) +@@ -1791,6 +1942,34 @@ + (set_attr "mode" "SI")] + ) + ++(define_insn "*sub3_carryin" ++ [(set ++ (match_operand:GPI 0 "register_operand" "=r") ++ (minus:GPI (minus:GPI ++ (match_operand:GPI 1 "register_operand" "r") ++ (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))) ++ (match_operand:GPI 2 "register_operand" "r")))] ++ "" ++ "sbc\\t%0, %1, %2" ++ [(set_attr "v8type" "adc") ++ (set_attr "mode" "")] ++) + -+ /* Swap the instructions such that lower memory is accessed first. */ -+ SWAP_RTX (operands[0], operands[1]); -+ SWAP_RTX (operands[2], operands[3]); -+ if (const_store) -+ SWAP_RTX (operands[4], operands[5]); -+ } -+ else -+ { -+ gap = offsets[1] - offsets[0]; -+ offset = offsets[0]; -+ } ++;; zero_extend version of the above ++(define_insn "*subsi3_carryin_uxtw" ++ [(set ++ (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI ++ (minus:SI (minus:SI ++ (match_operand:SI 1 "register_operand" "r") ++ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))) ++ (match_operand:SI 2 "register_operand" "r"))))] ++ "" ++ "sbc\\t%w0, %w1, %w2" ++ [(set_attr "v8type" "adc") ++ (set_attr "mode" "SI")] ++) + -+ /* Make sure accesses are to consecutive memory locations. */ -+ if (gap != 4) -+ return false; + (define_insn "*sub_uxt_multp2" + [(set (match_operand:GPI 0 "register_operand" "=rk") + (minus:GPI (match_operand:GPI 4 "register_operand" "r") +@@ -1825,6 +2004,38 @@ + (set_attr "mode" "SI")] + ) + ++(define_insn_and_split "absdi2" ++ [(set (match_operand:DI 0 "register_operand" "=r,w") ++ (abs:DI (match_operand:DI 1 "register_operand" "r,w"))) ++ (clobber (match_scratch:DI 2 "=&r,X"))] ++ "" ++ "@ ++ # ++ abs\\t%d0, %d1" ++ "reload_completed ++ && GP_REGNUM_P (REGNO (operands[0])) ++ && GP_REGNUM_P (REGNO (operands[1]))" ++ [(const_int 0)] ++ { ++ emit_insn (gen_rtx_SET (VOIDmode, operands[2], ++ gen_rtx_XOR (DImode, ++ gen_rtx_ASHIFTRT (DImode, ++ operands[1], ++ GEN_INT (63)), ++ operands[1]))); ++ emit_insn (gen_rtx_SET (VOIDmode, ++ operands[0], ++ gen_rtx_MINUS (DImode, ++ operands[2], ++ gen_rtx_ASHIFTRT (DImode, ++ operands[1], ++ GEN_INT (63))))); ++ DONE; ++ } ++ [(set_attr "v8type" "alu") ++ (set_attr "mode" "DI")] ++) + -+ /* Make sure we generate legal instructions. */ -+ if (operands_ok_ldrd_strd (operands[0], operands[1], base, offset, -+ false, load)) -+ return true; + (define_insn "neg2" + [(set (match_operand:GPI 0 "register_operand" "=r") + (neg:GPI (match_operand:GPI 1 "register_operand" "r")))] +@@ -1844,6 +2055,27 @@ + (set_attr "mode" "SI")] + ) + ++(define_insn "*ngc" ++ [(set (match_operand:GPI 0 "register_operand" "=r") ++ (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))) ++ (match_operand:GPI 1 "register_operand" "r")))] ++ "" ++ "ngc\\t%0, %1" ++ [(set_attr "v8type" "adc") ++ (set_attr "mode" "")] ++) + -+ /* In Thumb state, where registers are almost unconstrained, there -+ is little hope to fix it. */ -+ if (TARGET_THUMB2) -+ return false; ++(define_insn "*ngcsi_uxtw" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI ++ (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))) ++ (match_operand:SI 1 "register_operand" "r"))))] ++ "" ++ "ngc\\t%w0, %w1" ++ [(set_attr "v8type" "adc") ++ (set_attr "mode" "SI")] ++) + -+ if (load && commute) -+ { -+ /* Try reordering registers. */ -+ SWAP_RTX (operands[0], operands[1]); -+ if (operands_ok_ldrd_strd (operands[0], operands[1], base, offset, -+ false, load)) -+ return true; -+ } + (define_insn "*neg2_compare0" + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r")) +@@ -1869,6 +2101,21 @@ + (set_attr "mode" "SI")] + ) + ++(define_insn "*neg_3_compare0" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (neg:GPI (ASHIFT:GPI ++ (match_operand:GPI 1 "register_operand" "r") ++ (match_operand:QI 2 "aarch64_shift_imm_" "n"))) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))] ++ "" ++ "negs\\t%0, %1, %2" ++ [(set_attr "v8type" "alus_shift") ++ (set_attr "mode" "")] ++) + -+ if (const_store) -+ { -+ /* If input registers are dead after this pattern, they can be -+ reordered or replaced by other registers that are free in the -+ current pattern. */ -+ if (!peep2_reg_dead_p (4, operands[0]) -+ || !peep2_reg_dead_p (4, operands[1])) -+ return false; + (define_insn "*neg__2" + [(set (match_operand:GPI 0 "register_operand" "=r") + (neg:GPI (ASHIFT:GPI +@@ -2158,6 +2405,18 @@ + (set_attr "mode" "")] + ) + ++(define_insn "*cmp_swp__shft_" ++ [(set (reg:CC_SWP CC_REGNUM) ++ (compare:CC_SWP (ashift:GPI ++ (ANY_EXTEND:GPI ++ (match_operand:ALLX 0 "register_operand" "r")) ++ (match_operand 1 "aarch64_imm3" "Ui3")) ++ (match_operand:GPI 2 "register_operand" "r")))] ++ "" ++ "cmp\\t%2, %0, xt %1" ++ [(set_attr "v8type" "alus_ext") ++ (set_attr "mode" "")] ++) + + ;; ------------------------------------------------------------------- + ;; Store-flag and conditional select insns +@@ -2211,7 +2470,7 @@ + (set_attr "mode" "SI")] + ) + +-(define_insn "*cstore_neg" ++(define_insn "cstore_neg" + [(set (match_operand:ALLI 0 "register_operand" "=r") + (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)])))] +@@ -2434,6 +2693,69 @@ + [(set_attr "v8type" "logic,logic_imm") + (set_attr "mode" "SI")]) + ++(define_insn "*and3_compare0" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:GPI (match_operand:GPI 1 "register_operand" "%r,r") ++ (match_operand:GPI 2 "aarch64_logical_operand" "r,")) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r,r") ++ (and:GPI (match_dup 1) (match_dup 2)))] ++ "" ++ "ands\\t%0, %1, %2" ++ [(set_attr "v8type" "logics,logics_imm") ++ (set_attr "mode" "")] ++) + -+ /* Try to reorder the input registers. */ -+ /* For example, the code -+ mov r0, 0 -+ mov r1, 1 -+ str r1, [r2] -+ str r0, [r2, #4] -+ can be transformed into -+ mov r1, 0 -+ mov r0, 1 -+ strd r0, [r2] -+ */ -+ if (operands_ok_ldrd_strd (operands[1], operands[0], base, offset, -+ false, false)) -+ { -+ SWAP_RTX (operands[0], operands[1]); -+ return true; -+ } ++;; zero_extend version of above ++(define_insn "*andsi3_compare0_uxtw" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:SI (match_operand:SI 1 "register_operand" "%r,r") ++ (match_operand:SI 2 "aarch64_logical_operand" "r,K")) ++ (const_int 0))) ++ (set (match_operand:DI 0 "register_operand" "=r,r") ++ (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] ++ "" ++ "ands\\t%w0, %w1, %w2" ++ [(set_attr "v8type" "logics,logics_imm") ++ (set_attr "mode" "SI")] ++) + -+ /* Try to find a free DI register. */ -+ CLEAR_HARD_REG_SET (regset); -+ add_to_hard_reg_set (®set, SImode, REGNO (operands[0])); -+ add_to_hard_reg_set (®set, SImode, REGNO (operands[1])); -+ while (true) -+ { -+ tmp = peep2_find_free_register (0, 4, "r", DImode, ®set); -+ if (tmp == NULL_RTX) -+ return false; ++(define_insn "*and_3_compare0" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:GPI (SHIFT:GPI ++ (match_operand:GPI 1 "register_operand" "r") ++ (match_operand:QI 2 "aarch64_shift_imm_" "n")) ++ (match_operand:GPI 3 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))] ++ "" ++ "ands\\t%0, %3, %1, %2" ++ [(set_attr "v8type" "logics_shift") ++ (set_attr "mode" "")] ++) + -+ /* DREG must be an even-numbered register in DImode. -+ Split it into SI registers. */ -+ operands[0] = simplify_gen_subreg (SImode, tmp, DImode, 0); -+ operands[1] = simplify_gen_subreg (SImode, tmp, DImode, 4); -+ gcc_assert (operands[0] != NULL_RTX); -+ gcc_assert (operands[1] != NULL_RTX); -+ gcc_assert (REGNO (operands[0]) % 2 == 0); -+ gcc_assert (REGNO (operands[0]) + 1 == REGNO (operands[1])); ++;; zero_extend version of above ++(define_insn "*and_si3_compare0_uxtw" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:SI (SHIFT:SI ++ (match_operand:SI 1 "register_operand" "r") ++ (match_operand:QI 2 "aarch64_shift_imm_si" "n")) ++ (match_operand:SI 3 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2)) ++ (match_dup 3))))] ++ "" ++ "ands\\t%w0, %w3, %w1, %2" ++ [(set_attr "v8type" "logics_shift") ++ (set_attr "mode" "SI")] ++) + -+ return (operands_ok_ldrd_strd (operands[0], operands[1], -+ base, offset, -+ false, load)); -+ } -+ } + (define_insn "*_3" + [(set (match_operand:GPI 0 "register_operand" "=r") + (LOGICAL:GPI (SHIFT:GPI +@@ -2485,6 +2807,35 @@ + [(set_attr "v8type" "logic") + (set_attr "mode" "")]) + ++(define_insn "*and_one_cmpl3_compare0" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:GPI (not:GPI ++ (match_operand:GPI 1 "register_operand" "r")) ++ (match_operand:GPI 2 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))] ++ "" ++ "bics\\t%0, %2, %1" ++ [(set_attr "v8type" "logics") ++ (set_attr "mode" "")]) + -+ return false; -+} -+#undef SWAP_RTX ++;; zero_extend version of above ++(define_insn "*and_one_cmplsi3_compare0_uxtw" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:SI (not:SI ++ (match_operand:SI 1 "register_operand" "r")) ++ (match_operand:SI 2 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))] ++ "" ++ "bics\\t%w0, %w2, %w1" ++ [(set_attr "v8type" "logics") ++ (set_attr "mode" "SI")]) + + (define_insn "*_one_cmpl_3" + [(set (match_operand:GPI 0 "register_operand" "=r") + (LOGICAL:GPI (not:GPI +@@ -2497,6 +2848,43 @@ + [(set_attr "v8type" "logic_shift") + (set_attr "mode" "")]) + ++(define_insn "*and_one_cmpl_3_compare0" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:GPI (not:GPI ++ (SHIFT:GPI ++ (match_operand:GPI 1 "register_operand" "r") ++ (match_operand:QI 2 "aarch64_shift_imm_" "n"))) ++ (match_operand:GPI 3 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:GPI 0 "register_operand" "=r") ++ (and:GPI (not:GPI ++ (SHIFT:GPI ++ (match_dup 1) (match_dup 2))) (match_dup 3)))] ++ "" ++ "bics\\t%0, %3, %1, %2" ++ [(set_attr "v8type" "logics_shift") ++ (set_attr "mode" "")]) + ++;; zero_extend version of above ++(define_insn "*and_one_cmpl_si3_compare0_uxtw" ++ [(set (reg:CC_NZ CC_REGNUM) ++ (compare:CC_NZ ++ (and:SI (not:SI ++ (SHIFT:SI ++ (match_operand:SI 1 "register_operand" "r") ++ (match_operand:QI 2 "aarch64_shift_imm_si" "n"))) ++ (match_operand:SI 3 "register_operand" "r")) ++ (const_int 0))) ++ (set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI (and:SI ++ (not:SI ++ (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))] ++ "" ++ "bics\\t%w0, %w3, %w1, %2" ++ [(set_attr "v8type" "logics_shift") ++ (set_attr "mode" "SI")]) + - - /* Print a symbolic form of X to the debug file, F. */ - static void -@@ -13872,6 +14370,16 @@ - && IN_RANGE (INTVAL (op1), -7, 7)) - action = CONV; - } -+ /* ADCS , */ -+ else if (GET_CODE (XEXP (src, 0)) == PLUS -+ && rtx_equal_p (XEXP (XEXP (src, 0), 0), dst) -+ && low_register_operand (XEXP (XEXP (src, 0), 1), -+ SImode) -+ && COMPARISON_P (op1) -+ && cc_register (XEXP (op1, 0), VOIDmode) -+ && maybe_get_arm_condition_code (op1) == ARM_CS -+ && XEXP (op1, 1) == const0_rtx) -+ action = CONV; - break; - - case MINUS: -@@ -14830,7 +15338,8 @@ - { - /* Constraints should ensure this. */ - gcc_assert (code0 == MEM && code1 == REG); -- gcc_assert (REGNO (operands[1]) != IP_REGNUM); -+ gcc_assert ((REGNO (operands[1]) != IP_REGNUM) -+ || (TARGET_ARM && TARGET_LDRD)); - - switch (GET_CODE (XEXP (operands[0], 0))) - { -@@ -16303,124 +16812,308 @@ - } - } - --/* Generate and emit a pattern that will be recognized as STRD pattern. If even -- number of registers are being pushed, multiple STRD patterns are created for -- all register pairs. If odd number of registers are pushed, emit a -- combination of STRDs and STR for the prologue saves. */ -+/* Generate and emit a sequence of insns equivalent to PUSH, but using -+ STR and STRD. If an even number of registers are being pushed, one -+ or more STRD patterns are created for each register pair. If an -+ odd number of registers are pushed, emit an initial STR followed by -+ as many STRD instructions as are needed. This works best when the -+ stack is initially 64-bit aligned (the normal case), since it -+ ensures that each STRD is also 64-bit aligned. */ - static void - thumb2_emit_strd_push (unsigned long saved_regs_mask) - { - int num_regs = 0; -- int i, j; -+ int i; -+ int regno; - rtx par = NULL_RTX; -- rtx insn = NULL_RTX; - rtx dwarf = NULL_RTX; -- rtx tmp, reg, tmp1; -+ rtx tmp; -+ bool first = true; + (define_insn "clz2" + [(set (match_operand:GPI 0 "register_operand" "=r") + (clz:GPI (match_operand:GPI 1 "register_operand" "r")))] +@@ -2704,6 +3092,62 @@ + (set_attr "mode" "")] + ) -+ num_regs = bit_count (saved_regs_mask); ++(define_insn "*extr5_insn" ++ [(set (match_operand:GPI 0 "register_operand" "=r") ++ (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") ++ (match_operand 3 "const_int_operand" "n")) ++ (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r") ++ (match_operand 4 "const_int_operand" "n"))))] ++ "UINTVAL (operands[3]) < GET_MODE_BITSIZE (mode) && ++ (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (mode))" ++ "extr\\t%0, %1, %2, %4" ++ [(set_attr "v8type" "shift") ++ (set_attr "mode" "")] ++) + -+ /* Must be at least one register to save, and can't save SP or PC. */ -+ gcc_assert (num_regs > 0 && num_regs <= 14); -+ gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); -+ gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); ++;; zero_extend version of the above ++(define_insn "*extrsi5_insn_uxtw" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI ++ (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") ++ (match_operand 3 "const_int_operand" "n")) ++ (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") ++ (match_operand 4 "const_int_operand" "n")))))] ++ "UINTVAL (operands[3]) < 32 && ++ (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)" ++ "extr\\t%w0, %w1, %w2, %4" ++ [(set_attr "v8type" "shift") ++ (set_attr "mode" "SI")] ++) + -+ /* Create sequence for DWARF info. All the frame-related data for -+ debugging is held in this wrapper. */ -+ dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1)); ++(define_insn "*ror3_insn" ++ [(set (match_operand:GPI 0 "register_operand" "=r") ++ (rotate:GPI (match_operand:GPI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand" "n")))] ++ "UINTVAL (operands[2]) < GET_MODE_BITSIZE (mode)" ++{ ++ operands[3] = GEN_INT ( - UINTVAL (operands[2])); ++ return "ror\\t%0, %1, %3"; ++} ++ [(set_attr "v8type" "shift") ++ (set_attr "mode" "")] ++) + -+ /* Describe the stack adjustment. */ -+ tmp = gen_rtx_SET (VOIDmode, -+ stack_pointer_rtx, -+ plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, 0) = tmp; ++;; zero_extend version of the above ++(define_insn "*rorsi3_insn_uxtw" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI ++ (rotate:SI (match_operand:SI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand" "n"))))] ++ "UINTVAL (operands[2]) < 32" ++{ ++ operands[3] = GEN_INT (32 - UINTVAL (operands[2])); ++ return "ror\\t%w0, %w1, %3"; ++} ++ [(set_attr "v8type" "shift") ++ (set_attr "mode" "SI")] ++) + -+ /* Find the first register. */ -+ for (regno = 0; (saved_regs_mask & (1 << regno)) == 0; regno++) -+ ; + (define_insn "*_ashl" + [(set (match_operand:GPI 0 "register_operand" "=r") + (ANY_EXTEND:GPI +@@ -2770,6 +3214,65 @@ + (set_attr "mode" "")] + ) + ++;; Bitfield Insert (insv) ++(define_expand "insv" ++ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand") ++ (match_operand 1 "const_int_operand") ++ (match_operand 2 "const_int_operand")) ++ (match_operand:GPI 3 "general_operand"))] ++ "" ++{ ++ unsigned HOST_WIDE_INT width = UINTVAL (operands[1]); ++ unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]); ++ rtx value = operands[3]; + -+ i = 0; ++ if (width == 0 || (pos + width) > GET_MODE_BITSIZE (mode)) ++ FAIL; + -+ /* If there's an odd number of registers to push. Start off by -+ pushing a single register. This ensures that subsequent strd -+ operations are dword aligned (assuming that SP was originally -+ 64-bit aligned). */ -+ if ((num_regs & 1) != 0) ++ if (CONST_INT_P (value)) + { -+ rtx reg, mem, insn; ++ unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1; + -+ reg = gen_rtx_REG (SImode, regno); -+ if (num_regs == 1) -+ mem = gen_frame_mem (Pmode, gen_rtx_PRE_DEC (Pmode, -+ stack_pointer_rtx)); -+ else -+ mem = gen_frame_mem (Pmode, -+ gen_rtx_PRE_MODIFY -+ (Pmode, stack_pointer_rtx, -+ plus_constant (Pmode, stack_pointer_rtx, -+ -4 * num_regs))); ++ /* Prefer AND/OR for inserting all zeros or all ones. */ ++ if ((UINTVAL (value) & mask) == 0 ++ || (UINTVAL (value) & mask) == mask) ++ FAIL; + -+ tmp = gen_rtx_SET (VOIDmode, mem, reg); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ insn = emit_insn (tmp); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); -+ tmp = gen_rtx_SET (VOIDmode, gen_frame_mem (Pmode, stack_pointer_rtx), -+ reg); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ i++; -+ regno++; -+ XVECEXP (dwarf, 0, i) = tmp; -+ first = false; ++ /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */ ++ if (width == 16 && (pos % 16) == 0) ++ DONE; + } ++ operands[3] = force_reg (mode, value); ++}) + -+ while (i < num_regs) -+ if (saved_regs_mask & (1 << regno)) -+ { -+ rtx reg1, reg2, mem1, mem2; -+ rtx tmp0, tmp1, tmp2; -+ int regno2; -+ -+ /* Find the register to pair with this one. */ -+ for (regno2 = regno + 1; (saved_regs_mask & (1 << regno2)) == 0; -+ regno2++) -+ ; -+ -+ reg1 = gen_rtx_REG (SImode, regno); -+ reg2 = gen_rtx_REG (SImode, regno2); -+ -+ if (first) -+ { -+ rtx insn; -+ -+ first = false; -+ mem1 = gen_frame_mem (Pmode, plus_constant (Pmode, -+ stack_pointer_rtx, -+ -4 * num_regs)); -+ mem2 = gen_frame_mem (Pmode, plus_constant (Pmode, -+ stack_pointer_rtx, -+ -4 * (num_regs - 1))); -+ tmp0 = gen_rtx_SET (VOIDmode, stack_pointer_rtx, -+ plus_constant (Pmode, stack_pointer_rtx, -+ -4 * (num_regs))); -+ tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1); -+ tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2); -+ RTX_FRAME_RELATED_P (tmp0) = 1; -+ RTX_FRAME_RELATED_P (tmp1) = 1; -+ RTX_FRAME_RELATED_P (tmp2) = 1; -+ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (3)); -+ XVECEXP (par, 0, 0) = tmp0; -+ XVECEXP (par, 0, 1) = tmp1; -+ XVECEXP (par, 0, 2) = tmp2; -+ insn = emit_insn (par); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); -+ } -+ else -+ { -+ mem1 = gen_frame_mem (Pmode, plus_constant (Pmode, -+ stack_pointer_rtx, -+ 4 * i)); -+ mem2 = gen_frame_mem (Pmode, plus_constant (Pmode, -+ stack_pointer_rtx, -+ 4 * (i + 1))); -+ tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1); -+ tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2); -+ RTX_FRAME_RELATED_P (tmp1) = 1; -+ RTX_FRAME_RELATED_P (tmp2) = 1; -+ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); -+ XVECEXP (par, 0, 0) = tmp1; -+ XVECEXP (par, 0, 1) = tmp2; -+ emit_insn (par); -+ } -+ -+ /* Create unwind information. This is an approximation. */ -+ tmp1 = gen_rtx_SET (VOIDmode, -+ gen_frame_mem (Pmode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ 4 * i)), -+ reg1); -+ tmp2 = gen_rtx_SET (VOIDmode, -+ gen_frame_mem (Pmode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ 4 * (i + 1))), -+ reg2); ++(define_insn "*insv_reg" ++ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") ++ (match_operand 1 "const_int_operand" "n") ++ (match_operand 2 "const_int_operand" "n")) ++ (match_operand:GPI 3 "register_operand" "r"))] ++ "!(UINTVAL (operands[1]) == 0 ++ || (UINTVAL (operands[2]) + UINTVAL (operands[1]) ++ > GET_MODE_BITSIZE (mode)))" ++ "bfi\\t%0, %3, %2, %1" ++ [(set_attr "v8type" "bfm") ++ (set_attr "mode" "")] ++) + -+ RTX_FRAME_RELATED_P (tmp1) = 1; -+ RTX_FRAME_RELATED_P (tmp2) = 1; -+ XVECEXP (dwarf, 0, i + 1) = tmp1; -+ XVECEXP (dwarf, 0, i + 2) = tmp2; -+ i += 2; -+ regno = regno2 + 1; -+ } -+ else -+ regno++; ++(define_insn "*extr_insv_lower_reg" ++ [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") ++ (match_operand 1 "const_int_operand" "n") ++ (const_int 0)) ++ (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r") ++ (match_dup 1) ++ (match_operand 3 "const_int_operand" "n")))] ++ "!(UINTVAL (operands[1]) == 0 ++ || (UINTVAL (operands[3]) + UINTVAL (operands[1]) ++ > GET_MODE_BITSIZE (mode)))" ++ "bfxil\\t%0, %2, %3, %1" ++ [(set_attr "v8type" "bfm") ++ (set_attr "mode" "")] ++) + -+ return; -+} + (define_insn "*_shft_" + [(set (match_operand:GPI 0 "register_operand" "=r") + (ashift:GPI (ANY_EXTEND:GPI +@@ -3090,6 +3593,27 @@ + (set_attr "mode" "")] + ) + ++(define_insn "aarch64_frecp" ++ [(set (match_operand:GPF 0 "register_operand" "=w") ++ (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] ++ FRECP))] ++ "TARGET_FLOAT" ++ "frecp\\t%0, %1" ++ [(set_attr "v8type" "frecp") ++ (set_attr "mode" "")] ++) + -+/* STRD in ARM mode requires consecutive registers. This function emits STRD -+ whenever possible, otherwise it emits single-word stores. The first store -+ also allocates stack space for all saved registers, using writeback with -+ post-addressing mode. All other stores use offset addressing. If no STRD -+ can be emitted, this function emits a sequence of single-word stores, -+ and not an STM as before, because single-word stores provide more freedom -+ scheduling and can be turned into an STM by peephole optimizations. */ -+static void -+arm_emit_strd_push (unsigned long saved_regs_mask) -+{ -+ int num_regs = 0; -+ int i, j, dwarf_index = 0; -+ int offset = 0; -+ rtx dwarf = NULL_RTX; -+ rtx insn = NULL_RTX; -+ rtx tmp, mem; ++(define_insn "aarch64_frecps" ++ [(set (match_operand:GPF 0 "register_operand" "=w") ++ (unspec:GPF [(match_operand:GPF 1 "register_operand" "w") ++ (match_operand:GPF 2 "register_operand" "w")] ++ UNSPEC_FRECPS))] ++ "TARGET_FLOAT" ++ "frecps\\t%0, %1, %2" ++ [(set_attr "v8type" "frecps") ++ (set_attr "mode" "")] ++) + -+ /* TODO: A more efficient code can be emitted by changing the -+ layout, e.g., first push all pairs that can use STRD to keep the -+ stack aligned, and then push all other registers. */ - for (i = 0; i <= LAST_ARM_REGNUM; i++) - if (saved_regs_mask & (1 << i)) - num_regs++; + ;; ------------------------------------------------------------------- + ;; Reload support + ;; ------------------------------------------------------------------- +@@ -3146,9 +3670,9 @@ + ;; after or during reload as we don't want these patterns to start + ;; kicking in during the combiner. + +-(define_insn "aarch64_movdi_tilow" ++(define_insn "aarch64_movdi_low" + [(set (match_operand:DI 0 "register_operand" "=r") +- (truncate:DI (match_operand:TI 1 "register_operand" "w")))] ++ (truncate:DI (match_operand:TX 1 "register_operand" "w")))] + "reload_completed || reload_in_progress" + "fmov\\t%x0, %d1" + [(set_attr "v8type" "fmovf2i") +@@ -3156,10 +3680,10 @@ + (set_attr "length" "4") + ]) -- gcc_assert (num_regs && num_regs <= 16); -+ gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); -+ gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); -+ gcc_assert (num_regs > 0); +-(define_insn "aarch64_movdi_tihigh" ++(define_insn "aarch64_movdi_high" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI +- (lshiftrt:TI (match_operand:TI 1 "register_operand" "w") ++ (lshiftrt:TX (match_operand:TX 1 "register_operand" "w") + (const_int 64))))] + "reload_completed || reload_in_progress" + "fmov\\t%x0, %1.d[1]" +@@ -3168,24 +3692,22 @@ + (set_attr "length" "4") + ]) -- /* Pre-decrement the stack pointer, based on there being num_regs 4-byte -- registers to push. */ -- tmp = gen_rtx_SET (VOIDmode, -- stack_pointer_rtx, -- plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); -- RTX_FRAME_RELATED_P (tmp) = 1; -- insn = emit_insn (tmp); +-(define_insn "aarch64_movtihigh_di" +- [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w") ++(define_insn "aarch64_movhigh_di" ++ [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w") + (const_int 64) (const_int 64)) +- (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))] ++ (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] + "reload_completed || reload_in_progress" + "fmov\\t%0.d[1], %x1" - - /* Create sequence for DWARF info. */ - dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1)); - -- /* RTLs cannot be shared, hence create new copy for dwarf. */ -- tmp1 = gen_rtx_SET (VOIDmode, -+ /* For dwarf info, we generate explicit stack update. */ -+ tmp = gen_rtx_SET (VOIDmode, - stack_pointer_rtx, - plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); -- RTX_FRAME_RELATED_P (tmp1) = 1; -- XVECEXP (dwarf, 0, 0) = tmp1; -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, dwarf_index++) = tmp; + [(set_attr "v8type" "fmovi2f") + (set_attr "mode" "DI") + (set_attr "length" "4") + ]) -- gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); -- gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); +-(define_insn "aarch64_movtilow_di" +- [(set (match_operand:TI 0 "register_operand" "=w") +- (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))] ++(define_insn "aarch64_movlow_di" ++ [(set (match_operand:TX 0 "register_operand" "=w") ++ (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] + "reload_completed || reload_in_progress" + "fmov\\t%d0, %x1" - -- /* Var j iterates over all the registers to gather all the registers in -- saved_regs_mask. Var i gives index of register R_j in stack frame. -- A PARALLEL RTX of register-pair is created here, so that pattern for -- STRD can be matched. If num_regs is odd, 1st register will be pushed -- using STR and remaining registers will be pushed with STRD in pairs. -- If num_regs is even, all registers are pushed with STRD in pairs. -- Hence, skip first element for odd num_regs. */ -- for (i = num_regs - 1, j = LAST_ARM_REGNUM; i >= (num_regs % 2); j--) -+ /* Save registers. */ -+ offset = - 4 * num_regs; -+ j = 0; -+ while (j <= LAST_ARM_REGNUM) - if (saved_regs_mask & (1 << j)) - { -- /* Create RTX for store. New RTX is created for dwarf as -- they are not sharable. */ -- reg = gen_rtx_REG (SImode, j); -- tmp = gen_rtx_SET (SImode, -- gen_frame_mem -- (SImode, -- plus_constant (Pmode, stack_pointer_rtx, 4 * i)), -- reg); -+ if ((j % 2 == 0) -+ && (saved_regs_mask & (1 << (j + 1)))) -+ { -+ /* Current register and previous register form register pair for -+ which STRD can be generated. */ -+ if (offset < 0) -+ { -+ /* Allocate stack space for all saved registers. */ -+ tmp = plus_constant (Pmode, stack_pointer_rtx, offset); -+ tmp = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, tmp); -+ mem = gen_frame_mem (DImode, tmp); -+ offset = 0; -+ } -+ else if (offset > 0) -+ mem = gen_frame_mem (DImode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ offset)); -+ else -+ mem = gen_frame_mem (DImode, stack_pointer_rtx); - -- tmp1 = gen_rtx_SET (SImode, -- gen_frame_mem -- (SImode, -- plus_constant (Pmode, stack_pointer_rtx, 4 * i)), -- reg); -- RTX_FRAME_RELATED_P (tmp) = 1; -- RTX_FRAME_RELATED_P (tmp1) = 1; -+ tmp = gen_rtx_SET (DImode, mem, gen_rtx_REG (DImode, j)); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ tmp = emit_insn (tmp); + [(set_attr "v8type" "fmovi2f") + (set_attr "mode" "DI") + (set_attr "length" "4") +@@ -3197,7 +3719,6 @@ + (truncate:DI (match_operand:TI 1 "register_operand" "w"))))] + "reload_completed || reload_in_progress" + "fmov\\t%d0, %d1" +- + [(set_attr "v8type" "fmovi2f") + (set_attr "mode" "DI") + (set_attr "length" "4") +@@ -3231,6 +3752,16 @@ + (set_attr "mode" "DI")] + ) -- if (((i - (num_regs % 2)) % 2) == 1) -- /* When (i - (num_regs % 2)) is odd, the RTX to be emitted is yet to -- be created. Hence create it first. The STRD pattern we are -- generating is : -- [ (SET (MEM (PLUS (SP) (NUM))) (reg_t1)) -- (SET (MEM (PLUS (SP) (NUM + 4))) (reg_t2)) ] -- where the target registers need not be consecutive. */ -- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); -+ /* Record the first store insn. */ -+ if (dwarf_index == 1) -+ insn = tmp; ++(define_insn "ldr_got_tiny" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] ++ UNSPEC_GOTTINYPIC))] ++ "" ++ "ldr\\t%0, %L1" ++ [(set_attr "v8type" "load1") ++ (set_attr "mode" "DI")] ++) ++ + (define_insn "aarch64_load_tp_hard" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_TLS))] +--- a/src/gcc/config/aarch64/aarch64-option-extensions.def ++++ b/src/gcc/config/aarch64/aarch64-option-extensions.def +@@ -35,3 +35,4 @@ + AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, AARCH64_FL_FPSIMD | AARCH64_FL_CRYPTO) + AARCH64_OPT_EXTENSION("simd", AARCH64_FL_FPSIMD, AARCH64_FL_SIMD | AARCH64_FL_CRYPTO) + AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO | AARCH64_FL_FPSIMD, AARCH64_FL_CRYPTO) ++AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, AARCH64_FL_CRC) +--- a/src/gcc/config/aarch64/aarch64-builtins.c ++++ b/src/gcc/config/aarch64/aarch64-builtins.c +@@ -30,6 +30,7 @@ + #include "langhooks.h" + #include "diagnostic-core.h" + #include "optabs.h" ++#include "gimple.h" -- /* Register R_j is added in PARALLEL RTX. If (i - (num_regs % 2)) is -- even, the reg_j is added as 0th element and if it is odd, reg_i is -- added as 1st element of STRD pattern shown above. */ -- XVECEXP (par, 0, ((i - (num_regs % 2)) % 2)) = tmp; -- XVECEXP (dwarf, 0, (i + 1)) = tmp1; -+ /* Generate dwarf info. */ -+ mem = gen_frame_mem (SImode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ offset)); -+ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j)); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, dwarf_index++) = tmp; + enum aarch64_simd_builtin_type_mode + { +@@ -50,6 +51,7 @@ + T_OI, + T_XI, + T_SI, ++ T_SF, + T_HI, + T_QI, + T_MAX +@@ -72,6 +74,7 @@ + #define oi_UP T_OI + #define xi_UP T_XI + #define si_UP T_SI ++#define sf_UP T_SF + #define hi_UP T_HI + #define qi_UP T_QI -- if (((i - (num_regs % 2)) % 2) == 0) -- /* When (i - (num_regs % 2)) is even, RTXs for both the registers -- to be loaded are generated in above given STRD pattern, and the -- pattern can be emitted now. */ -- emit_insn (par); -+ mem = gen_frame_mem (SImode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ offset + 4)); -+ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j + 1)); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, dwarf_index++) = tmp; +@@ -128,123 +131,136 @@ + unsigned int fcode; + } aarch64_simd_builtin_datum; -- i--; -- } -+ offset += 8; -+ j += 2; -+ } -+ else -+ { -+ /* Emit a single word store. */ -+ if (offset < 0) -+ { -+ /* Allocate stack space for all saved registers. */ -+ tmp = plus_constant (Pmode, stack_pointer_rtx, offset); -+ tmp = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, tmp); -+ mem = gen_frame_mem (SImode, tmp); -+ offset = 0; -+ } -+ else if (offset > 0) -+ mem = gen_frame_mem (SImode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ offset)); -+ else -+ mem = gen_frame_mem (SImode, stack_pointer_rtx); +-#define CF(N, X) CODE_FOR_aarch64_##N##X ++#define CF0(N, X) CODE_FOR_aarch64_##N##X ++#define CF1(N, X) CODE_FOR_##N##X##1 ++#define CF2(N, X) CODE_FOR_##N##X##2 ++#define CF3(N, X) CODE_FOR_##N##X##3 ++#define CF4(N, X) CODE_FOR_##N##X##4 ++#define CF10(N, X) CODE_FOR_##N##X -- if ((num_regs % 2) == 1) -- { -- /* If odd number of registers are pushed, generate STR pattern to store -- lone register. */ -- for (; (saved_regs_mask & (1 << j)) == 0; j--); -+ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j)); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ tmp = emit_insn (tmp); +-#define VAR1(T, N, A) \ +- {#N, AARCH64_SIMD_##T, UP (A), CF (N, A), 0}, +-#define VAR2(T, N, A, B) \ +- VAR1 (T, N, A) \ +- VAR1 (T, N, B) +-#define VAR3(T, N, A, B, C) \ +- VAR2 (T, N, A, B) \ +- VAR1 (T, N, C) +-#define VAR4(T, N, A, B, C, D) \ +- VAR3 (T, N, A, B, C) \ +- VAR1 (T, N, D) +-#define VAR5(T, N, A, B, C, D, E) \ +- VAR4 (T, N, A, B, C, D) \ +- VAR1 (T, N, E) +-#define VAR6(T, N, A, B, C, D, E, F) \ +- VAR5 (T, N, A, B, C, D, E) \ +- VAR1 (T, N, F) +-#define VAR7(T, N, A, B, C, D, E, F, G) \ +- VAR6 (T, N, A, B, C, D, E, F) \ +- VAR1 (T, N, G) +-#define VAR8(T, N, A, B, C, D, E, F, G, H) \ +- VAR7 (T, N, A, B, C, D, E, F, G) \ +- VAR1 (T, N, H) +-#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \ +- VAR8 (T, N, A, B, C, D, E, F, G, H) \ +- VAR1 (T, N, I) +-#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \ +- VAR9 (T, N, A, B, C, D, E, F, G, H, I) \ +- VAR1 (T, N, J) +-#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \ +- VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \ +- VAR1 (T, N, K) +-#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \ +- VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \ +- VAR1 (T, N, L) ++#define VAR1(T, N, MAP, A) \ ++ {#N, AARCH64_SIMD_##T, UP (A), CF##MAP (N, A), 0}, ++#define VAR2(T, N, MAP, A, B) \ ++ VAR1 (T, N, MAP, A) \ ++ VAR1 (T, N, MAP, B) ++#define VAR3(T, N, MAP, A, B, C) \ ++ VAR2 (T, N, MAP, A, B) \ ++ VAR1 (T, N, MAP, C) ++#define VAR4(T, N, MAP, A, B, C, D) \ ++ VAR3 (T, N, MAP, A, B, C) \ ++ VAR1 (T, N, MAP, D) ++#define VAR5(T, N, MAP, A, B, C, D, E) \ ++ VAR4 (T, N, MAP, A, B, C, D) \ ++ VAR1 (T, N, MAP, E) ++#define VAR6(T, N, MAP, A, B, C, D, E, F) \ ++ VAR5 (T, N, MAP, A, B, C, D, E) \ ++ VAR1 (T, N, MAP, F) ++#define VAR7(T, N, MAP, A, B, C, D, E, F, G) \ ++ VAR6 (T, N, MAP, A, B, C, D, E, F) \ ++ VAR1 (T, N, MAP, G) ++#define VAR8(T, N, MAP, A, B, C, D, E, F, G, H) \ ++ VAR7 (T, N, MAP, A, B, C, D, E, F, G) \ ++ VAR1 (T, N, MAP, H) ++#define VAR9(T, N, MAP, A, B, C, D, E, F, G, H, I) \ ++ VAR8 (T, N, MAP, A, B, C, D, E, F, G, H) \ ++ VAR1 (T, N, MAP, I) ++#define VAR10(T, N, MAP, A, B, C, D, E, F, G, H, I, J) \ ++ VAR9 (T, N, MAP, A, B, C, D, E, F, G, H, I) \ ++ VAR1 (T, N, MAP, J) ++#define VAR11(T, N, MAP, A, B, C, D, E, F, G, H, I, J, K) \ ++ VAR10 (T, N, MAP, A, B, C, D, E, F, G, H, I, J) \ ++ VAR1 (T, N, MAP, K) ++#define VAR12(T, N, MAP, A, B, C, D, E, F, G, H, I, J, K, L) \ ++ VAR11 (T, N, MAP, A, B, C, D, E, F, G, H, I, J, K) \ ++ VAR1 (T, N, MAP, L) -- tmp1 = gen_frame_mem (SImode, plus_constant (Pmode, -- stack_pointer_rtx, 4 * i)); -- reg = gen_rtx_REG (SImode, j); -- tmp = gen_rtx_SET (SImode, tmp1, reg); -- RTX_FRAME_RELATED_P (tmp) = 1; -+ /* Record the first store insn. */ -+ if (dwarf_index == 1) -+ insn = tmp; + /* BUILTIN_ macros should expand to cover the same range of + modes as is given for each define_mode_iterator in + config/aarch64/iterators.md. */ -- emit_insn (tmp); -+ /* Generate dwarf info. */ -+ mem = gen_frame_mem (SImode, -+ plus_constant(Pmode, -+ stack_pointer_rtx, -+ offset)); -+ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j)); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, dwarf_index++) = tmp; +-#define BUILTIN_DX(T, N) \ +- VAR2 (T, N, di, df) +-#define BUILTIN_SDQ_I(T, N) \ +- VAR4 (T, N, qi, hi, si, di) +-#define BUILTIN_SD_HSI(T, N) \ +- VAR2 (T, N, hi, si) +-#define BUILTIN_V2F(T, N) \ +- VAR2 (T, N, v2sf, v2df) +-#define BUILTIN_VALL(T, N) \ +- VAR10 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, v2sf, v4sf, v2df) +-#define BUILTIN_VB(T, N) \ +- VAR2 (T, N, v8qi, v16qi) +-#define BUILTIN_VD(T, N) \ +- VAR4 (T, N, v8qi, v4hi, v2si, v2sf) +-#define BUILTIN_VDC(T, N) \ +- VAR6 (T, N, v8qi, v4hi, v2si, v2sf, di, df) +-#define BUILTIN_VDIC(T, N) \ +- VAR3 (T, N, v8qi, v4hi, v2si) +-#define BUILTIN_VDN(T, N) \ +- VAR3 (T, N, v4hi, v2si, di) +-#define BUILTIN_VDQ(T, N) \ +- VAR7 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) +-#define BUILTIN_VDQF(T, N) \ +- VAR3 (T, N, v2sf, v4sf, v2df) +-#define BUILTIN_VDQHS(T, N) \ +- VAR4 (T, N, v4hi, v8hi, v2si, v4si) +-#define BUILTIN_VDQIF(T, N) \ +- VAR9 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2sf, v4sf, v2df) +-#define BUILTIN_VDQM(T, N) \ +- VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si) +-#define BUILTIN_VDQV(T, N) \ +- VAR5 (T, N, v8qi, v16qi, v4hi, v8hi, v4si) +-#define BUILTIN_VDQ_BHSI(T, N) \ +- VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si) +-#define BUILTIN_VDQ_I(T, N) \ +- VAR7 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) +-#define BUILTIN_VDW(T, N) \ +- VAR3 (T, N, v8qi, v4hi, v2si) +-#define BUILTIN_VD_BHSI(T, N) \ +- VAR3 (T, N, v8qi, v4hi, v2si) +-#define BUILTIN_VD_HSI(T, N) \ +- VAR2 (T, N, v4hi, v2si) +-#define BUILTIN_VD_RE(T, N) \ +- VAR6 (T, N, v8qi, v4hi, v2si, v2sf, di, df) +-#define BUILTIN_VQ(T, N) \ +- VAR6 (T, N, v16qi, v8hi, v4si, v2di, v4sf, v2df) +-#define BUILTIN_VQN(T, N) \ +- VAR3 (T, N, v8hi, v4si, v2di) +-#define BUILTIN_VQW(T, N) \ +- VAR3 (T, N, v16qi, v8hi, v4si) +-#define BUILTIN_VQ_HSI(T, N) \ +- VAR2 (T, N, v8hi, v4si) +-#define BUILTIN_VQ_S(T, N) \ +- VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si) +-#define BUILTIN_VSDQ_HSI(T, N) \ +- VAR6 (T, N, v4hi, v8hi, v2si, v4si, hi, si) +-#define BUILTIN_VSDQ_I(T, N) \ +- VAR11 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si, di) +-#define BUILTIN_VSDQ_I_BHSI(T, N) \ +- VAR10 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si) +-#define BUILTIN_VSDQ_I_DI(T, N) \ +- VAR8 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, di) +-#define BUILTIN_VSD_HSI(T, N) \ +- VAR4 (T, N, v4hi, v2si, hi, si) +-#define BUILTIN_VSQN_HSDI(T, N) \ +- VAR6 (T, N, v8hi, v4si, v2di, hi, si, di) +-#define BUILTIN_VSTRUCT(T, N) \ +- VAR3 (T, N, oi, ci, xi) ++#define BUILTIN_DX(T, N, MAP) \ ++ VAR2 (T, N, MAP, di, df) ++#define BUILTIN_GPF(T, N, MAP) \ ++ VAR2 (T, N, MAP, sf, df) ++#define BUILTIN_SDQ_I(T, N, MAP) \ ++ VAR4 (T, N, MAP, qi, hi, si, di) ++#define BUILTIN_SD_HSI(T, N, MAP) \ ++ VAR2 (T, N, MAP, hi, si) ++#define BUILTIN_V2F(T, N, MAP) \ ++ VAR2 (T, N, MAP, v2sf, v2df) ++#define BUILTIN_VALL(T, N, MAP) \ ++ VAR10 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, \ ++ v4si, v2di, v2sf, v4sf, v2df) ++#define BUILTIN_VALLDI(T, N, MAP) \ ++ VAR11 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, \ ++ v4si, v2di, v2sf, v4sf, v2df, di) ++#define BUILTIN_VB(T, N, MAP) \ ++ VAR2 (T, N, MAP, v8qi, v16qi) ++#define BUILTIN_VD(T, N, MAP) \ ++ VAR4 (T, N, MAP, v8qi, v4hi, v2si, v2sf) ++#define BUILTIN_VDC(T, N, MAP) \ ++ VAR6 (T, N, MAP, v8qi, v4hi, v2si, v2sf, di, df) ++#define BUILTIN_VDIC(T, N, MAP) \ ++ VAR3 (T, N, MAP, v8qi, v4hi, v2si) ++#define BUILTIN_VDN(T, N, MAP) \ ++ VAR3 (T, N, MAP, v4hi, v2si, di) ++#define BUILTIN_VDQ(T, N, MAP) \ ++ VAR7 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) ++#define BUILTIN_VDQF(T, N, MAP) \ ++ VAR3 (T, N, MAP, v2sf, v4sf, v2df) ++#define BUILTIN_VDQH(T, N, MAP) \ ++ VAR2 (T, N, MAP, v4hi, v8hi) ++#define BUILTIN_VDQHS(T, N, MAP) \ ++ VAR4 (T, N, MAP, v4hi, v8hi, v2si, v4si) ++#define BUILTIN_VDQIF(T, N, MAP) \ ++ VAR9 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2sf, v4sf, v2df) ++#define BUILTIN_VDQM(T, N, MAP) \ ++ VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si) ++#define BUILTIN_VDQV(T, N, MAP) \ ++ VAR5 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v4si) ++#define BUILTIN_VDQ_BHSI(T, N, MAP) \ ++ VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si) ++#define BUILTIN_VDQ_I(T, N, MAP) \ ++ VAR7 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di) ++#define BUILTIN_VDW(T, N, MAP) \ ++ VAR3 (T, N, MAP, v8qi, v4hi, v2si) ++#define BUILTIN_VD_BHSI(T, N, MAP) \ ++ VAR3 (T, N, MAP, v8qi, v4hi, v2si) ++#define BUILTIN_VD_HSI(T, N, MAP) \ ++ VAR2 (T, N, MAP, v4hi, v2si) ++#define BUILTIN_VD_RE(T, N, MAP) \ ++ VAR6 (T, N, MAP, v8qi, v4hi, v2si, v2sf, di, df) ++#define BUILTIN_VQ(T, N, MAP) \ ++ VAR6 (T, N, MAP, v16qi, v8hi, v4si, v2di, v4sf, v2df) ++#define BUILTIN_VQN(T, N, MAP) \ ++ VAR3 (T, N, MAP, v8hi, v4si, v2di) ++#define BUILTIN_VQW(T, N, MAP) \ ++ VAR3 (T, N, MAP, v16qi, v8hi, v4si) ++#define BUILTIN_VQ_HSI(T, N, MAP) \ ++ VAR2 (T, N, MAP, v8hi, v4si) ++#define BUILTIN_VQ_S(T, N, MAP) \ ++ VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si) ++#define BUILTIN_VSDQ_HSI(T, N, MAP) \ ++ VAR6 (T, N, MAP, v4hi, v8hi, v2si, v4si, hi, si) ++#define BUILTIN_VSDQ_I(T, N, MAP) \ ++ VAR11 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si, di) ++#define BUILTIN_VSDQ_I_BHSI(T, N, MAP) \ ++ VAR10 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si) ++#define BUILTIN_VSDQ_I_DI(T, N, MAP) \ ++ VAR8 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, di) ++#define BUILTIN_VSD_HSI(T, N, MAP) \ ++ VAR4 (T, N, MAP, v4hi, v2si, hi, si) ++#define BUILTIN_VSQN_HSDI(T, N, MAP) \ ++ VAR6 (T, N, MAP, v8hi, v4si, v2di, hi, si, di) ++#define BUILTIN_VSTRUCT(T, N, MAP) \ ++ VAR3 (T, N, MAP, oi, ci, xi) -- tmp1 = gen_rtx_SET (SImode, -- gen_frame_mem -- (SImode, -- plus_constant (Pmode, stack_pointer_rtx, 4 * i)), -- reg); -- RTX_FRAME_RELATED_P (tmp1) = 1; -- XVECEXP (dwarf, 0, (i + 1)) = tmp1; -- } -+ offset += 4; -+ j += 1; -+ } -+ } -+ else -+ j++; + static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = { + #include "aarch64-simd-builtins.def" + }; -+ /* Attach dwarf info to the first insn we generate. */ -+ gcc_assert (insn != NULL_RTX); - add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); - RTX_FRAME_RELATED_P (insn) = 1; -- return; - } + #undef VAR1 +-#define VAR1(T, N, A) \ ++#define VAR1(T, N, MAP, A) \ + AARCH64_SIMD_BUILTIN_##N##A, - /* Generate and emit an insn that we will recognize as a push_multi. -@@ -16565,6 +17258,19 @@ - return par; - } + enum aarch64_builtins +@@ -257,53 +273,6 @@ + AARCH64_BUILTIN_MAX + }; -+/* Add a REG_CFA_ADJUST_CFA REG note to INSN. -+ SIZE is the offset to be adjusted. -+ DEST and SRC might be stack_pointer_rtx or hard_frame_pointer_rtx. */ -+static void -+arm_add_cfa_adjust_cfa_note (rtx insn, int size, rtx dest, rtx src) -+{ -+ rtx dwarf; -+ -+ RTX_FRAME_RELATED_P (insn) = 1; -+ dwarf = gen_rtx_SET (VOIDmode, dest, plus_constant (Pmode, src, size)); -+ add_reg_note (insn, REG_CFA_ADJUST_CFA, dwarf); -+} -+ - /* Generate and emit an insn pattern that we will recognize as a pop_multi. - SAVED_REGS_MASK shows which registers need to be restored. +-#undef BUILTIN_DX +-#undef BUILTIN_SDQ_I +-#undef BUILTIN_SD_HSI +-#undef BUILTIN_V2F +-#undef BUILTIN_VALL +-#undef BUILTIN_VB +-#undef BUILTIN_VD +-#undef BUILTIN_VDC +-#undef BUILTIN_VDIC +-#undef BUILTIN_VDN +-#undef BUILTIN_VDQ +-#undef BUILTIN_VDQF +-#undef BUILTIN_VDQHS +-#undef BUILTIN_VDQIF +-#undef BUILTIN_VDQM +-#undef BUILTIN_VDQV +-#undef BUILTIN_VDQ_BHSI +-#undef BUILTIN_VDQ_I +-#undef BUILTIN_VDW +-#undef BUILTIN_VD_BHSI +-#undef BUILTIN_VD_HSI +-#undef BUILTIN_VD_RE +-#undef BUILTIN_VQ +-#undef BUILTIN_VQN +-#undef BUILTIN_VQW +-#undef BUILTIN_VQ_HSI +-#undef BUILTIN_VQ_S +-#undef BUILTIN_VSDQ_HSI +-#undef BUILTIN_VSDQ_I +-#undef BUILTIN_VSDQ_I_BHSI +-#undef BUILTIN_VSDQ_I_DI +-#undef BUILTIN_VSD_HSI +-#undef BUILTIN_VSQN_HSDI +-#undef BUILTIN_VSTRUCT +-#undef CF +-#undef VAR1 +-#undef VAR2 +-#undef VAR3 +-#undef VAR4 +-#undef VAR5 +-#undef VAR6 +-#undef VAR7 +-#undef VAR8 +-#undef VAR9 +-#undef VAR10 +-#undef VAR11 +- + static GTY(()) tree aarch64_builtin_decls[AARCH64_BUILTIN_MAX]; -@@ -16622,6 +17328,17 @@ - if (saved_regs_mask & (1 << i)) + #define NUM_DREG_TYPES 6 +@@ -609,7 +578,7 @@ { - reg = gen_rtx_REG (SImode, i); -+ if ((num_regs == 1) && emit_update && !return_in_pc) + "v8qi", "v4hi", "v2si", "v2sf", "di", "df", + "v16qi", "v8hi", "v4si", "v4sf", "v2di", "v2df", +- "ti", "ei", "oi", "xi", "si", "hi", "qi" ++ "ti", "ei", "oi", "xi", "si", "sf", "hi", "qi" + }; + char namebuf[60]; + tree ftype = NULL; +@@ -1259,30 +1228,82 @@ + && in_mode == N##Fmode && in_n == C) + case BUILT_IN_FLOOR: + case BUILT_IN_FLOORF: +- return AARCH64_FIND_FRINT_VARIANT (frintm); ++ return AARCH64_FIND_FRINT_VARIANT (floor); + case BUILT_IN_CEIL: + case BUILT_IN_CEILF: +- return AARCH64_FIND_FRINT_VARIANT (frintp); ++ return AARCH64_FIND_FRINT_VARIANT (ceil); + case BUILT_IN_TRUNC: + case BUILT_IN_TRUNCF: +- return AARCH64_FIND_FRINT_VARIANT (frintz); ++ return AARCH64_FIND_FRINT_VARIANT (btrunc); + case BUILT_IN_ROUND: + case BUILT_IN_ROUNDF: +- return AARCH64_FIND_FRINT_VARIANT (frinta); ++ return AARCH64_FIND_FRINT_VARIANT (round); + case BUILT_IN_NEARBYINT: + case BUILT_IN_NEARBYINTF: +- return AARCH64_FIND_FRINT_VARIANT (frinti); ++ return AARCH64_FIND_FRINT_VARIANT (nearbyint); + case BUILT_IN_SQRT: + case BUILT_IN_SQRTF: + return AARCH64_FIND_FRINT_VARIANT (sqrt); + #undef AARCH64_CHECK_BUILTIN_MODE + #define AARCH64_CHECK_BUILTIN_MODE(C, N) \ ++ (out_mode == SImode && out_n == C \ ++ && in_mode == N##Imode && in_n == C) ++ case BUILT_IN_CLZ: + { -+ /* Emit single load with writeback. */ -+ tmp = gen_frame_mem (SImode, -+ gen_rtx_POST_INC (Pmode, -+ stack_pointer_rtx)); -+ tmp = emit_insn (gen_rtx_SET (VOIDmode, reg, tmp)); -+ REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); -+ return; ++ if (AARCH64_CHECK_BUILTIN_MODE (4, S)) ++ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_clzv4si]; ++ return NULL_TREE; + } ++#undef AARCH64_CHECK_BUILTIN_MODE ++#define AARCH64_CHECK_BUILTIN_MODE(C, N) \ + (out_mode == N##Imode && out_n == C \ + && in_mode == N##Fmode && in_n == C) + case BUILT_IN_LFLOOR: +- return AARCH64_FIND_FRINT_VARIANT (fcvtms); ++ case BUILT_IN_IFLOORF: ++ { ++ tree new_tree = NULL_TREE; ++ if (AARCH64_CHECK_BUILTIN_MODE (2, D)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lfloorv2dfv2di]; ++ else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lfloorv4sfv4si]; ++ else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lfloorv2sfv2si]; ++ return new_tree; ++ } + case BUILT_IN_LCEIL: +- return AARCH64_FIND_FRINT_VARIANT (fcvtps); ++ case BUILT_IN_ICEILF: ++ { ++ tree new_tree = NULL_TREE; ++ if (AARCH64_CHECK_BUILTIN_MODE (2, D)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lceilv2dfv2di]; ++ else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lceilv4sfv4si]; ++ else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lceilv2sfv2si]; ++ return new_tree; ++ } ++ case BUILT_IN_LROUND: ++ case BUILT_IN_IROUNDF: ++ { ++ tree new_tree = NULL_TREE; ++ if (AARCH64_CHECK_BUILTIN_MODE (2, D)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lroundv2dfv2di]; ++ else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lroundv4sfv4si]; ++ else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) ++ new_tree = ++ aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lroundv2sfv2si]; ++ return new_tree; ++ } + - tmp = gen_rtx_SET (VOIDmode, - reg, - gen_frame_mem -@@ -16644,6 +17361,9 @@ - par = emit_insn (par); + default: + return NULL_TREE; + } +@@ -1290,5 +1311,160 @@ - REG_NOTES (par) = dwarf; -+ if (!return_in_pc) -+ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD * num_regs, -+ stack_pointer_rtx, stack_pointer_rtx); + return NULL_TREE; } - - /* Generate and emit an insn pattern that we will recognize as a pop_multi -@@ -16714,6 +17434,9 @@ - - par = emit_insn (par); - REG_NOTES (par) = dwarf; + -+ arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs, -+ base_reg, base_reg); - } - - /* Generate and emit a pattern that will be recognized as LDRD pattern. If even -@@ -16789,6 +17512,7 @@ - pattern can be emitted now. */ - par = emit_insn (par); - REG_NOTES (par) = dwarf; -+ RTX_FRAME_RELATED_P (par) = 1; - } - - i++; -@@ -16805,7 +17529,12 @@ - stack_pointer_rtx, - plus_constant (Pmode, stack_pointer_rtx, 4 * i)); - RTX_FRAME_RELATED_P (tmp) = 1; -- emit_insn (tmp); -+ tmp = emit_insn (tmp); -+ if (!return_in_pc) ++#undef VAR1 ++#define VAR1(T, N, MAP, A) \ ++ case AARCH64_SIMD_BUILTIN_##N##A: ++ ++tree ++aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args, ++ bool ignore ATTRIBUTE_UNUSED) ++{ ++ int fcode = DECL_FUNCTION_CODE (fndecl); ++ tree type = TREE_TYPE (TREE_TYPE (fndecl)); ++ ++ switch (fcode) + { -+ arm_add_cfa_adjust_cfa_note (tmp, UNITS_PER_WORD * i, -+ stack_pointer_rtx, stack_pointer_rtx); ++ BUILTIN_VALLDI (UNOP, abs, 2) ++ return fold_build1 (ABS_EXPR, type, args[0]); ++ break; ++ BUILTIN_VALLDI (BINOP, cmge, 0) ++ return fold_build2 (GE_EXPR, type, args[0], args[1]); ++ break; ++ BUILTIN_VALLDI (BINOP, cmgt, 0) ++ return fold_build2 (GT_EXPR, type, args[0], args[1]); ++ break; ++ BUILTIN_VALLDI (BINOP, cmeq, 0) ++ return fold_build2 (EQ_EXPR, type, args[0], args[1]); ++ break; ++ BUILTIN_VSDQ_I_DI (BINOP, cmtst, 0) ++ { ++ tree and_node = fold_build2 (BIT_AND_EXPR, type, args[0], args[1]); ++ tree vec_zero_node = build_zero_cst (type); ++ return fold_build2 (NE_EXPR, type, and_node, vec_zero_node); ++ break; ++ } ++ VAR1 (UNOP, floatv2si, 2, v2sf) ++ VAR1 (UNOP, floatv4si, 2, v4sf) ++ VAR1 (UNOP, floatv2di, 2, v2df) ++ return fold_build1 (FLOAT_EXPR, type, args[0]); ++ default: ++ break; + } - - dwarf = NULL_RTX; - -@@ -16839,9 +17568,11 @@ - else - { - par = emit_insn (tmp); -+ REG_NOTES (par) = dwarf; -+ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD, -+ stack_pointer_rtx, stack_pointer_rtx); - } - -- REG_NOTES (par) = dwarf; - } - else if ((num_regs % 2) == 1 && return_in_pc) - { -@@ -16853,6 +17584,132 @@ - return; - } - -+/* LDRD in ARM mode needs consecutive registers as operands. This function -+ emits LDRD whenever possible, otherwise it emits single-word loads. It uses -+ offset addressing and then generates one separate stack udpate. This provides -+ more scheduling freedom, compared to writeback on every load. However, -+ if the function returns using load into PC directly -+ (i.e., if PC is in SAVED_REGS_MASK), the stack needs to be updated -+ before the last load. TODO: Add a peephole optimization to recognize -+ the new epilogue sequence as an LDM instruction whenever possible. TODO: Add -+ peephole optimization to merge the load at stack-offset zero -+ with the stack update instruction using load with writeback -+ in post-index addressing mode. */ -+static void -+arm_emit_ldrd_pop (unsigned long saved_regs_mask) ++ ++ return NULL_TREE; ++} ++ ++bool ++aarch64_gimple_fold_builtin (gimple_stmt_iterator *gsi) +{ -+ int j = 0; -+ int offset = 0; -+ rtx par = NULL_RTX; -+ rtx dwarf = NULL_RTX; -+ rtx tmp, mem; ++ bool changed = false; ++ gimple stmt = gsi_stmt (*gsi); ++ tree call = gimple_call_fn (stmt); ++ tree fndecl; ++ gimple new_stmt = NULL; ++ if (call) ++ { ++ fndecl = gimple_call_fndecl (stmt); ++ if (fndecl) ++ { ++ int fcode = DECL_FUNCTION_CODE (fndecl); ++ int nargs = gimple_call_num_args (stmt); ++ tree *args = (nargs > 0 ++ ? gimple_call_arg_ptr (stmt, 0) ++ : &error_mark_node); ++ ++ switch (fcode) ++ { ++ BUILTIN_VALL (UNOP, reduc_splus_, 10) ++ new_stmt = gimple_build_assign_with_ops ( ++ REDUC_PLUS_EXPR, ++ gimple_call_lhs (stmt), ++ args[0], ++ NULL_TREE); ++ break; ++ BUILTIN_VDQIF (UNOP, reduc_smax_, 10) ++ new_stmt = gimple_build_assign_with_ops ( ++ REDUC_MAX_EXPR, ++ gimple_call_lhs (stmt), ++ args[0], ++ NULL_TREE); ++ break; ++ BUILTIN_VDQIF (UNOP, reduc_smin_, 10) ++ new_stmt = gimple_build_assign_with_ops ( ++ REDUC_MIN_EXPR, ++ gimple_call_lhs (stmt), ++ args[0], ++ NULL_TREE); ++ break; + -+ /* Restore saved registers. */ -+ gcc_assert (!((saved_regs_mask & (1 << SP_REGNUM)))); -+ j = 0; -+ while (j <= LAST_ARM_REGNUM) -+ if (saved_regs_mask & (1 << j)) -+ { -+ if ((j % 2) == 0 -+ && (saved_regs_mask & (1 << (j + 1))) -+ && (j + 1) != PC_REGNUM) -+ { -+ /* Current register and next register form register pair for which -+ LDRD can be generated. PC is always the last register popped, and -+ we handle it separately. */ -+ if (offset > 0) -+ mem = gen_frame_mem (DImode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ offset)); -+ else -+ mem = gen_frame_mem (DImode, stack_pointer_rtx); ++ default: ++ break; ++ } ++ } ++ } + -+ tmp = gen_rtx_SET (DImode, gen_rtx_REG (DImode, j), mem); -+ tmp = emit_insn (tmp); -+ RTX_FRAME_RELATED_P (tmp) = 1; ++ if (new_stmt) ++ { ++ gsi_replace (gsi, new_stmt, true); ++ changed = true; ++ } + -+ /* Generate dwarf info. */ ++ return changed; ++} + -+ dwarf = alloc_reg_note (REG_CFA_RESTORE, -+ gen_rtx_REG (SImode, j), -+ NULL_RTX); -+ dwarf = alloc_reg_note (REG_CFA_RESTORE, -+ gen_rtx_REG (SImode, j + 1), -+ dwarf); + #undef AARCH64_CHECK_BUILTIN_MODE + #undef AARCH64_FIND_FRINT_VARIANT ++#undef BUILTIN_DX ++#undef BUILTIN_SDQ_I ++#undef BUILTIN_SD_HSI ++#undef BUILTIN_V2F ++#undef BUILTIN_VALL ++#undef BUILTIN_VB ++#undef BUILTIN_VD ++#undef BUILTIN_VDC ++#undef BUILTIN_VDIC ++#undef BUILTIN_VDN ++#undef BUILTIN_VDQ ++#undef BUILTIN_VDQF ++#undef BUILTIN_VDQH ++#undef BUILTIN_VDQHS ++#undef BUILTIN_VDQIF ++#undef BUILTIN_VDQM ++#undef BUILTIN_VDQV ++#undef BUILTIN_VDQ_BHSI ++#undef BUILTIN_VDQ_I ++#undef BUILTIN_VDW ++#undef BUILTIN_VD_BHSI ++#undef BUILTIN_VD_HSI ++#undef BUILTIN_VD_RE ++#undef BUILTIN_VQ ++#undef BUILTIN_VQN ++#undef BUILTIN_VQW ++#undef BUILTIN_VQ_HSI ++#undef BUILTIN_VQ_S ++#undef BUILTIN_VSDQ_HSI ++#undef BUILTIN_VSDQ_I ++#undef BUILTIN_VSDQ_I_BHSI ++#undef BUILTIN_VSDQ_I_DI ++#undef BUILTIN_VSD_HSI ++#undef BUILTIN_VSQN_HSDI ++#undef BUILTIN_VSTRUCT ++#undef CF0 ++#undef CF1 ++#undef CF2 ++#undef CF3 ++#undef CF4 ++#undef CF10 ++#undef VAR1 ++#undef VAR2 ++#undef VAR3 ++#undef VAR4 ++#undef VAR5 ++#undef VAR6 ++#undef VAR7 ++#undef VAR8 ++#undef VAR9 ++#undef VAR10 ++#undef VAR11 + -+ REG_NOTES (tmp) = dwarf; +--- a/src/gcc/config/aarch64/aarch64-protos.h ++++ b/src/gcc/config/aarch64/aarch64-protos.h +@@ -68,6 +68,24 @@ + Each of of these represents a thread-local symbol, and corresponds to the + thread local storage relocation operator for the symbol being referred to. + ++ SYMBOL_TINY_ABSOLUTE + -+ offset += 8; -+ j += 2; -+ } -+ else if (j != PC_REGNUM) -+ { -+ /* Emit a single word load. */ -+ if (offset > 0) -+ mem = gen_frame_mem (SImode, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ offset)); -+ else -+ mem = gen_frame_mem (SImode, stack_pointer_rtx); ++ Generate symbol accesses as a PC relative address using a single ++ instruction. To compute the address of symbol foo, we generate: + -+ tmp = gen_rtx_SET (SImode, gen_rtx_REG (SImode, j), mem); -+ tmp = emit_insn (tmp); -+ RTX_FRAME_RELATED_P (tmp) = 1; ++ ADR x0, foo + -+ /* Generate dwarf info. */ -+ REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, -+ gen_rtx_REG (SImode, j), -+ NULL_RTX); ++ SYMBOL_TINY_GOT + -+ offset += 4; -+ j += 1; -+ } -+ else /* j == PC_REGNUM */ -+ j++; -+ } -+ else -+ j++; ++ Generate symbol accesses via the GOT using a single PC relative ++ instruction. To compute the address of symbol foo, we generate: + -+ /* Update the stack. */ -+ if (offset > 0) -+ { -+ tmp = gen_rtx_SET (Pmode, -+ stack_pointer_rtx, -+ plus_constant (Pmode, -+ stack_pointer_rtx, -+ offset)); -+ tmp = emit_insn (tmp); -+ arm_add_cfa_adjust_cfa_note (tmp, offset, -+ stack_pointer_rtx, stack_pointer_rtx); -+ offset = 0; -+ } ++ ldr t0, :got:foo + -+ if (saved_regs_mask & (1 << PC_REGNUM)) -+ { -+ /* Only PC is to be popped. */ -+ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); -+ XVECEXP (par, 0, 0) = ret_rtx; -+ tmp = gen_rtx_SET (SImode, -+ gen_rtx_REG (SImode, PC_REGNUM), -+ gen_frame_mem (SImode, -+ gen_rtx_POST_INC (SImode, -+ stack_pointer_rtx))); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (par, 0, 1) = tmp; -+ par = emit_jump_insn (par); ++ The value of foo can subsequently read using: + -+ /* Generate dwarf info. */ -+ dwarf = alloc_reg_note (REG_CFA_RESTORE, -+ gen_rtx_REG (SImode, PC_REGNUM), -+ NULL_RTX); -+ REG_NOTES (par) = dwarf; -+ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD, -+ stack_pointer_rtx, stack_pointer_rtx); -+ } -+} ++ ldrb t0, [t0] + - /* Calculate the size of the return value that is passed in registers. */ - static unsigned - arm_size_return_regs (void) -@@ -16877,11 +17734,27 @@ - || df_regs_ever_live_p (LR_REGNUM)); - } + SYMBOL_FORCE_TO_MEM : Global variables are addressed using + constant pool. All variable addresses are spilled into constant + pools. The constant pools themselves are addressed using PC +@@ -81,6 +99,8 @@ + SYMBOL_SMALL_TLSDESC, + SYMBOL_SMALL_GOTTPREL, + SYMBOL_SMALL_TPREL, ++ SYMBOL_TINY_ABSOLUTE, ++ SYMBOL_TINY_GOT, + SYMBOL_FORCE_TO_MEM + }; -+/* We do not know if r3 will be available because -+ we do have an indirect tailcall happening in this -+ particular case. */ -+static bool -+is_indirect_tailcall_p (rtx call) +@@ -126,35 +146,66 @@ + const int FP2FP; + }; + ++/* Cost for vector insn classes. */ ++struct cpu_vector_cost +{ -+ rtx pat = PATTERN (call); ++ const int scalar_stmt_cost; /* Cost of any scalar operation, ++ excluding load and store. */ ++ const int scalar_load_cost; /* Cost of scalar load. */ ++ const int scalar_store_cost; /* Cost of scalar store. */ ++ const int vec_stmt_cost; /* Cost of any vector operation, ++ excluding load, store, ++ vector-to-scalar and ++ scalar-to-vector operation. */ ++ const int vec_to_scalar_cost; /* Cost of vec-to-scalar operation. */ ++ const int scalar_to_vec_cost; /* Cost of scalar-to-vector ++ operation. */ ++ const int vec_align_load_cost; /* Cost of aligned vector load. */ ++ const int vec_unalign_load_cost; /* Cost of unaligned vector load. */ ++ const int vec_unalign_store_cost; /* Cost of unaligned vector store. */ ++ const int vec_store_cost; /* Cost of vector store. */ ++ const int cond_taken_branch_cost; /* Cost of taken branch. */ ++ const int cond_not_taken_branch_cost; /* Cost of not taken branch. */ ++}; ++ + struct tune_params + { + const struct cpu_rtx_cost_table *const insn_extra_cost; + const struct cpu_addrcost_table *const addr_cost; + const struct cpu_regmove_cost *const regmove_cost; ++ const struct cpu_vector_cost *const vec_costs; + const int memmov_cost; + }; -+ /* Indirect tail call. */ -+ pat = XVECEXP (pat, 0, 0); -+ if (GET_CODE (pat) == SET) -+ pat = SET_SRC (pat); + HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned); + bool aarch64_bitmask_imm (HOST_WIDE_INT val, enum machine_mode); ++enum aarch64_symbol_type ++aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context); + bool aarch64_constant_address_p (rtx); + bool aarch64_float_const_zero_rtx_p (rtx); + bool aarch64_function_arg_regno_p (unsigned); + bool aarch64_gen_movmemqi (rtx *); ++bool aarch64_gimple_fold_builtin (gimple_stmt_iterator *); + bool aarch64_is_extend_from_extract (enum machine_mode, rtx, rtx); + bool aarch64_is_long_call_p (rtx); + bool aarch64_label_mentioned_p (rtx); + bool aarch64_legitimate_pic_operand_p (rtx); + bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode); ++bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context, ++ enum machine_mode); ++char *aarch64_output_scalar_simd_mov_immediate (rtx, enum machine_mode); ++char *aarch64_output_simd_mov_immediate (rtx, enum machine_mode, unsigned); + bool aarch64_pad_arg_upward (enum machine_mode, const_tree); + bool aarch64_pad_reg_upward (enum machine_mode, const_tree, bool); + bool aarch64_regno_ok_for_base_p (int, bool); + bool aarch64_regno_ok_for_index_p (int, bool); + bool aarch64_simd_imm_scalar_p (rtx x, enum machine_mode mode); + bool aarch64_simd_imm_zero_p (rtx, enum machine_mode); ++bool aarch64_simd_scalar_immediate_valid_for_move (rtx, enum machine_mode); + bool aarch64_simd_shift_imm_p (rtx, enum machine_mode, bool); ++bool aarch64_simd_valid_immediate (rtx, enum machine_mode, bool, ++ struct simd_immediate_info *); + bool aarch64_symbolic_address_p (rtx); +-bool aarch64_symbolic_constant_p (rtx, enum aarch64_symbol_context, +- enum aarch64_symbol_type *); + bool aarch64_uimm12_shift (HOST_WIDE_INT); + const char *aarch64_output_casesi (rtx *); + enum aarch64_symbol_type aarch64_classify_symbol (rtx, +@@ -165,9 +216,6 @@ + int aarch64_hard_regno_mode_ok (unsigned, enum machine_mode); + int aarch64_hard_regno_nregs (unsigned, enum machine_mode); + int aarch64_simd_attr_length_move (rtx); +-int aarch64_simd_immediate_valid_for_move (rtx, enum machine_mode, rtx *, +- int *, unsigned char *, int *, +- int *); + int aarch64_uxt_size (int, HOST_WIDE_INT); + rtx aarch64_final_eh_return_addr (void); + rtx aarch64_legitimize_reload_address (rtx *, enum machine_mode, int, int, int); +@@ -177,6 +225,7 @@ + bool aarch64_simd_mem_operand_p (rtx); + rtx aarch64_simd_vect_par_cnst_half (enum machine_mode, bool); + rtx aarch64_tls_get_addr (void); ++tree aarch64_fold_builtin (tree, int, tree *, bool); + unsigned aarch64_dbx_register_number (unsigned); + unsigned aarch64_trampoline_size (void); + void aarch64_asm_output_labelref (FILE *, const char *); +@@ -216,6 +265,10 @@ + + bool aarch64_split_128bit_move_p (rtx, rtx); + ++void aarch64_split_simd_combine (rtx, rtx, rtx); + -+ pat = XEXP (XEXP (pat, 0), 0); -+ return REG_P (pat); -+} ++void aarch64_split_simd_move (rtx, rtx); + - /* Return true if r3 is used by any of the tail call insns in the - current function. */ - static bool --any_sibcall_uses_r3 (void) -+any_sibcall_could_use_r3 (void) - { - edge_iterator ei; - edge e; -@@ -16895,7 +17768,8 @@ - if (!CALL_P (call)) - call = prev_nonnote_nondebug_insn (call); - gcc_assert (CALL_P (call) && SIBLING_CALL_P (call)); -- if (find_regno_fusage (call, USE, 3)) -+ if (find_regno_fusage (call, USE, 3) -+ || is_indirect_tailcall_p (call)) - return true; - } - return false; -@@ -17062,9 +17936,11 @@ - /* If it is safe to use r3, then do so. This sometimes - generates better code on Thumb-2 by avoiding the need to - use 32-bit push/pop instructions. */ -- if (! any_sibcall_uses_r3 () -+ if (! any_sibcall_could_use_r3 () - && arm_size_return_regs () <= 12 -- && (offsets->saved_regs_mask & (1 << 3)) == 0) -+ && (offsets->saved_regs_mask & (1 << 3)) == 0 -+ && (TARGET_THUMB2 -+ || !(TARGET_LDRD && current_tune->prefer_ldrd_strd))) - { - reg = 3; - } -@@ -17497,6 +18373,12 @@ - { - thumb2_emit_strd_push (live_regs_mask); - } -+ else if (TARGET_ARM -+ && !TARGET_APCS_FRAME -+ && !IS_INTERRUPT (func_type)) -+ { -+ arm_emit_strd_push (live_regs_mask); -+ } - else - { - insn = emit_multi_reg_push (live_regs_mask); -@@ -18774,7 +19656,14 @@ - enum arm_cond_code code; - int n; - int mask; -+ int max; + /* Check for a legitimate floating point constant for FMOV. */ + bool aarch64_float_const_representable_p (rtx); -+ /* Maximum number of conditionally executed instructions in a block -+ is minimum of the two max values: maximum allowed in an IT block -+ and maximum that is beneficial according to the cost model and tune. */ -+ max = (max_insns_skipped < MAX_INSN_PER_IT_BLOCK) ? -+ max_insns_skipped : MAX_INSN_PER_IT_BLOCK; +@@ -249,6 +302,4 @@ + extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel); + extern bool + aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel); +- +-char* aarch64_output_simd_mov_immediate (rtx *, enum machine_mode, unsigned); + #endif /* GCC_AARCH64_PROTOS_H */ +--- a/src/gcc/config/aarch64/aarch64-simd-builtins.def ++++ b/src/gcc/config/aarch64/aarch64-simd-builtins.def +@@ -18,248 +18,344 @@ + along with GCC; see the file COPYING3. If not see + . */ + +-/* In the list below, the BUILTIN_ macros should +- correspond to the iterator used to construct the instruction's +- patterns in aarch64-simd.md. A helpful idiom to follow when +- adding new builtins is to add a line for each pattern in the md +- file. Thus, ADDP, which has one pattern defined for the VD_BHSI +- iterator, and one for DImode, has two entries below. */ ++/* In the list below, the BUILTIN_ macros expand to create ++ builtins for each of the modes described by . When adding ++ new builtins to this list, a helpful idiom to follow is to add ++ a line for each pattern in the md file. Thus, ADDP, which has one ++ pattern defined for the VD_BHSI iterator, and one for DImode, has two ++ entries below. + +- BUILTIN_VD_RE (CREATE, create) +- BUILTIN_VQ_S (GETLANE, get_lane_signed) +- BUILTIN_VDQ (GETLANE, get_lane_unsigned) +- BUILTIN_VDQF (GETLANE, get_lane) +- VAR1 (GETLANE, get_lane, di) +- BUILTIN_VDC (COMBINE, combine) +- BUILTIN_VB (BINOP, pmul) +- BUILTIN_VDQF (UNOP, sqrt) +- BUILTIN_VD_BHSI (BINOP, addp) +- VAR1 (UNOP, addp, di) ++ Parameter 1 is the 'type' of the intrinsic. This is used to ++ describe the type modifiers (for example; unsigned) applied to ++ each of the parameters to the intrinsic function. + +- BUILTIN_VD_RE (REINTERP, reinterpretdi) +- BUILTIN_VDC (REINTERP, reinterpretv8qi) +- BUILTIN_VDC (REINTERP, reinterpretv4hi) +- BUILTIN_VDC (REINTERP, reinterpretv2si) +- BUILTIN_VDC (REINTERP, reinterpretv2sf) +- BUILTIN_VQ (REINTERP, reinterpretv16qi) +- BUILTIN_VQ (REINTERP, reinterpretv8hi) +- BUILTIN_VQ (REINTERP, reinterpretv4si) +- BUILTIN_VQ (REINTERP, reinterpretv4sf) +- BUILTIN_VQ (REINTERP, reinterpretv2di) +- BUILTIN_VQ (REINTERP, reinterpretv2df) ++ Parameter 2 is the name of the intrinsic. This is appended ++ to `__builtin_aarch64_` to give the intrinsic name ++ as exported to the front-ends. + +- BUILTIN_VDQ_I (BINOP, dup_lane) +- BUILTIN_SDQ_I (BINOP, dup_lane) ++ Parameter 3 describes how to map from the name to the CODE_FOR_ ++ macro holding the RTL pattern for the intrinsic. This mapping is: ++ 0 - CODE_FOR_aarch64_ ++ 1-9 - CODE_FOR_<1-9> ++ 10 - CODE_FOR_. */ + - /* Remove the previous insn from the count of insns to be output. */ - if (arm_condexec_count) - arm_condexec_count--; -@@ -18816,9 +19705,9 @@ - /* ??? Recognize conditional jumps, and combine them with IT blocks. */ - if (GET_CODE (body) != COND_EXEC) - break; -- /* Allow up to 4 conditionally executed instructions in a block. */ -+ /* Maximum number of conditionally executed instructions in a block. */ - n = get_attr_ce_count (insn); -- if (arm_condexec_masklen + n > 4) -+ if (arm_condexec_masklen + n > max) - break; ++ BUILTIN_VD_RE (CREATE, create, 0) ++ BUILTIN_VDC (COMBINE, combine, 0) ++ BUILTIN_VB (BINOP, pmul, 0) ++ BUILTIN_VDQF (UNOP, sqrt, 2) ++ BUILTIN_VD_BHSI (BINOP, addp, 0) ++ VAR1 (UNOP, addp, 0, di) ++ VAR1 (UNOP, clz, 2, v4si) ++ ++ BUILTIN_VALL (GETLANE, get_lane, 0) ++ VAR1 (GETLANE, get_lane, 0, di) ++ ++ BUILTIN_VD_RE (REINTERP, reinterpretdi, 0) ++ BUILTIN_VDC (REINTERP, reinterpretv8qi, 0) ++ BUILTIN_VDC (REINTERP, reinterpretv4hi, 0) ++ BUILTIN_VDC (REINTERP, reinterpretv2si, 0) ++ BUILTIN_VDC (REINTERP, reinterpretv2sf, 0) ++ BUILTIN_VQ (REINTERP, reinterpretv16qi, 0) ++ BUILTIN_VQ (REINTERP, reinterpretv8hi, 0) ++ BUILTIN_VQ (REINTERP, reinterpretv4si, 0) ++ BUILTIN_VQ (REINTERP, reinterpretv4sf, 0) ++ BUILTIN_VQ (REINTERP, reinterpretv2di, 0) ++ BUILTIN_VQ (REINTERP, reinterpretv2df, 0) ++ ++ BUILTIN_VDQ_I (BINOP, dup_lane, 0) + /* Implemented by aarch64_qshl. */ +- BUILTIN_VSDQ_I (BINOP, sqshl) +- BUILTIN_VSDQ_I (BINOP, uqshl) +- BUILTIN_VSDQ_I (BINOP, sqrshl) +- BUILTIN_VSDQ_I (BINOP, uqrshl) ++ BUILTIN_VSDQ_I (BINOP, sqshl, 0) ++ BUILTIN_VSDQ_I (BINOP, uqshl, 0) ++ BUILTIN_VSDQ_I (BINOP, sqrshl, 0) ++ BUILTIN_VSDQ_I (BINOP, uqrshl, 0) + /* Implemented by aarch64_. */ +- BUILTIN_VSDQ_I (BINOP, sqadd) +- BUILTIN_VSDQ_I (BINOP, uqadd) +- BUILTIN_VSDQ_I (BINOP, sqsub) +- BUILTIN_VSDQ_I (BINOP, uqsub) ++ BUILTIN_VSDQ_I (BINOP, sqadd, 0) ++ BUILTIN_VSDQ_I (BINOP, uqadd, 0) ++ BUILTIN_VSDQ_I (BINOP, sqsub, 0) ++ BUILTIN_VSDQ_I (BINOP, uqsub, 0) + /* Implemented by aarch64_qadd. */ +- BUILTIN_VSDQ_I (BINOP, suqadd) +- BUILTIN_VSDQ_I (BINOP, usqadd) ++ BUILTIN_VSDQ_I (BINOP, suqadd, 0) ++ BUILTIN_VSDQ_I (BINOP, usqadd, 0) + + /* Implemented by aarch64_get_dreg. */ +- BUILTIN_VDC (GETLANE, get_dregoi) +- BUILTIN_VDC (GETLANE, get_dregci) +- BUILTIN_VDC (GETLANE, get_dregxi) ++ BUILTIN_VDC (GETLANE, get_dregoi, 0) ++ BUILTIN_VDC (GETLANE, get_dregci, 0) ++ BUILTIN_VDC (GETLANE, get_dregxi, 0) + /* Implemented by aarch64_get_qreg. */ +- BUILTIN_VQ (GETLANE, get_qregoi) +- BUILTIN_VQ (GETLANE, get_qregci) +- BUILTIN_VQ (GETLANE, get_qregxi) ++ BUILTIN_VQ (GETLANE, get_qregoi, 0) ++ BUILTIN_VQ (GETLANE, get_qregci, 0) ++ BUILTIN_VQ (GETLANE, get_qregxi, 0) + /* Implemented by aarch64_set_qreg. */ +- BUILTIN_VQ (SETLANE, set_qregoi) +- BUILTIN_VQ (SETLANE, set_qregci) +- BUILTIN_VQ (SETLANE, set_qregxi) ++ BUILTIN_VQ (SETLANE, set_qregoi, 0) ++ BUILTIN_VQ (SETLANE, set_qregci, 0) ++ BUILTIN_VQ (SETLANE, set_qregxi, 0) + /* Implemented by aarch64_ld. */ +- BUILTIN_VDC (LOADSTRUCT, ld2) +- BUILTIN_VDC (LOADSTRUCT, ld3) +- BUILTIN_VDC (LOADSTRUCT, ld4) ++ BUILTIN_VDC (LOADSTRUCT, ld2, 0) ++ BUILTIN_VDC (LOADSTRUCT, ld3, 0) ++ BUILTIN_VDC (LOADSTRUCT, ld4, 0) + /* Implemented by aarch64_ld. */ +- BUILTIN_VQ (LOADSTRUCT, ld2) +- BUILTIN_VQ (LOADSTRUCT, ld3) +- BUILTIN_VQ (LOADSTRUCT, ld4) ++ BUILTIN_VQ (LOADSTRUCT, ld2, 0) ++ BUILTIN_VQ (LOADSTRUCT, ld3, 0) ++ BUILTIN_VQ (LOADSTRUCT, ld4, 0) + /* Implemented by aarch64_st. */ +- BUILTIN_VDC (STORESTRUCT, st2) +- BUILTIN_VDC (STORESTRUCT, st3) +- BUILTIN_VDC (STORESTRUCT, st4) ++ BUILTIN_VDC (STORESTRUCT, st2, 0) ++ BUILTIN_VDC (STORESTRUCT, st3, 0) ++ BUILTIN_VDC (STORESTRUCT, st4, 0) + /* Implemented by aarch64_st. */ +- BUILTIN_VQ (STORESTRUCT, st2) +- BUILTIN_VQ (STORESTRUCT, st3) +- BUILTIN_VQ (STORESTRUCT, st4) ++ BUILTIN_VQ (STORESTRUCT, st2, 0) ++ BUILTIN_VQ (STORESTRUCT, st3, 0) ++ BUILTIN_VQ (STORESTRUCT, st4, 0) - predicate = COND_EXEC_TEST (body); -@@ -19376,6 +20265,7 @@ - typedef enum { - T_V8QI, - T_V4HI, -+ T_V4HF, - T_V2SI, - T_V2SF, - T_DI, -@@ -19393,8 +20283,8 @@ - #define TYPE_MODE_BIT(X) (1 << (X)) +- BUILTIN_VQW (BINOP, saddl2) +- BUILTIN_VQW (BINOP, uaddl2) +- BUILTIN_VQW (BINOP, ssubl2) +- BUILTIN_VQW (BINOP, usubl2) +- BUILTIN_VQW (BINOP, saddw2) +- BUILTIN_VQW (BINOP, uaddw2) +- BUILTIN_VQW (BINOP, ssubw2) +- BUILTIN_VQW (BINOP, usubw2) ++ BUILTIN_VQW (BINOP, saddl2, 0) ++ BUILTIN_VQW (BINOP, uaddl2, 0) ++ BUILTIN_VQW (BINOP, ssubl2, 0) ++ BUILTIN_VQW (BINOP, usubl2, 0) ++ BUILTIN_VQW (BINOP, saddw2, 0) ++ BUILTIN_VQW (BINOP, uaddw2, 0) ++ BUILTIN_VQW (BINOP, ssubw2, 0) ++ BUILTIN_VQW (BINOP, usubw2, 0) + /* Implemented by aarch64_l. */ +- BUILTIN_VDW (BINOP, saddl) +- BUILTIN_VDW (BINOP, uaddl) +- BUILTIN_VDW (BINOP, ssubl) +- BUILTIN_VDW (BINOP, usubl) ++ BUILTIN_VDW (BINOP, saddl, 0) ++ BUILTIN_VDW (BINOP, uaddl, 0) ++ BUILTIN_VDW (BINOP, ssubl, 0) ++ BUILTIN_VDW (BINOP, usubl, 0) + /* Implemented by aarch64_w. */ +- BUILTIN_VDW (BINOP, saddw) +- BUILTIN_VDW (BINOP, uaddw) +- BUILTIN_VDW (BINOP, ssubw) +- BUILTIN_VDW (BINOP, usubw) ++ BUILTIN_VDW (BINOP, saddw, 0) ++ BUILTIN_VDW (BINOP, uaddw, 0) ++ BUILTIN_VDW (BINOP, ssubw, 0) ++ BUILTIN_VDW (BINOP, usubw, 0) + /* Implemented by aarch64_h. */ +- BUILTIN_VQ_S (BINOP, shadd) +- BUILTIN_VQ_S (BINOP, uhadd) +- BUILTIN_VQ_S (BINOP, srhadd) +- BUILTIN_VQ_S (BINOP, urhadd) ++ BUILTIN_VQ_S (BINOP, shadd, 0) ++ BUILTIN_VQ_S (BINOP, uhadd, 0) ++ BUILTIN_VQ_S (BINOP, srhadd, 0) ++ BUILTIN_VQ_S (BINOP, urhadd, 0) + /* Implemented by aarch64_hn. */ +- BUILTIN_VQN (BINOP, addhn) +- BUILTIN_VQN (BINOP, raddhn) ++ BUILTIN_VQN (BINOP, addhn, 0) ++ BUILTIN_VQN (BINOP, raddhn, 0) + /* Implemented by aarch64_hn2. */ +- BUILTIN_VQN (TERNOP, addhn2) +- BUILTIN_VQN (TERNOP, raddhn2) ++ BUILTIN_VQN (TERNOP, addhn2, 0) ++ BUILTIN_VQN (TERNOP, raddhn2, 0) - #define TB_DREG (TYPE_MODE_BIT (T_V8QI) | TYPE_MODE_BIT (T_V4HI) \ -- | TYPE_MODE_BIT (T_V2SI) | TYPE_MODE_BIT (T_V2SF) \ -- | TYPE_MODE_BIT (T_DI)) -+ | TYPE_MODE_BIT (T_V4HF) | TYPE_MODE_BIT (T_V2SI) \ -+ | TYPE_MODE_BIT (T_V2SF) | TYPE_MODE_BIT (T_DI)) - #define TB_QREG (TYPE_MODE_BIT (T_V16QI) | TYPE_MODE_BIT (T_V8HI) \ - | TYPE_MODE_BIT (T_V4SI) | TYPE_MODE_BIT (T_V4SF) \ - | TYPE_MODE_BIT (T_V2DI) | TYPE_MODE_BIT (T_TI)) -@@ -19401,6 +20291,7 @@ +- BUILTIN_VSQN_HSDI (UNOP, sqmovun) ++ BUILTIN_VSQN_HSDI (UNOP, sqmovun, 0) + /* Implemented by aarch64_qmovn. */ +- BUILTIN_VSQN_HSDI (UNOP, sqmovn) +- BUILTIN_VSQN_HSDI (UNOP, uqmovn) ++ BUILTIN_VSQN_HSDI (UNOP, sqmovn, 0) ++ BUILTIN_VSQN_HSDI (UNOP, uqmovn, 0) + /* Implemented by aarch64_s. */ +- BUILTIN_VSDQ_I_BHSI (UNOP, sqabs) +- BUILTIN_VSDQ_I_BHSI (UNOP, sqneg) ++ BUILTIN_VSDQ_I_BHSI (UNOP, sqabs, 0) ++ BUILTIN_VSDQ_I_BHSI (UNOP, sqneg, 0) - #define v8qi_UP T_V8QI - #define v4hi_UP T_V4HI -+#define v4hf_UP T_V4HF - #define v2si_UP T_V2SI - #define v2sf_UP T_V2SF - #define di_UP T_DI -@@ -19436,6 +20327,8 @@ - NEON_SCALARMULH, - NEON_SCALARMAC, - NEON_CONVERT, -+ NEON_FLOAT_WIDEN, -+ NEON_FLOAT_NARROW, - NEON_FIXCONV, - NEON_SELECT, - NEON_RESULTPAIR, -@@ -19496,7 +20389,8 @@ - VAR9 (T, N, A, B, C, D, E, F, G, H, I), \ - {#N, NEON_##T, UP (J), CF (N, J), 0} +- BUILTIN_VSD_HSI (QUADOP, sqdmlal_lane) +- BUILTIN_VSD_HSI (QUADOP, sqdmlsl_lane) +- BUILTIN_VSD_HSI (QUADOP, sqdmlal_laneq) +- BUILTIN_VSD_HSI (QUADOP, sqdmlsl_laneq) +- BUILTIN_VQ_HSI (TERNOP, sqdmlal2) +- BUILTIN_VQ_HSI (TERNOP, sqdmlsl2) +- BUILTIN_VQ_HSI (QUADOP, sqdmlal2_lane) +- BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_lane) +- BUILTIN_VQ_HSI (QUADOP, sqdmlal2_laneq) +- BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_laneq) +- BUILTIN_VQ_HSI (TERNOP, sqdmlal2_n) +- BUILTIN_VQ_HSI (TERNOP, sqdmlsl2_n) ++ BUILTIN_VSD_HSI (QUADOP, sqdmlal_lane, 0) ++ BUILTIN_VSD_HSI (QUADOP, sqdmlsl_lane, 0) ++ BUILTIN_VSD_HSI (QUADOP, sqdmlal_laneq, 0) ++ BUILTIN_VSD_HSI (QUADOP, sqdmlsl_laneq, 0) ++ BUILTIN_VQ_HSI (TERNOP, sqdmlal2, 0) ++ BUILTIN_VQ_HSI (TERNOP, sqdmlsl2, 0) ++ BUILTIN_VQ_HSI (QUADOP, sqdmlal2_lane, 0) ++ BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_lane, 0) ++ BUILTIN_VQ_HSI (QUADOP, sqdmlal2_laneq, 0) ++ BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_laneq, 0) ++ BUILTIN_VQ_HSI (TERNOP, sqdmlal2_n, 0) ++ BUILTIN_VQ_HSI (TERNOP, sqdmlsl2_n, 0) + /* Implemented by aarch64_sqdmll. */ +- BUILTIN_VSD_HSI (TERNOP, sqdmlal) +- BUILTIN_VSD_HSI (TERNOP, sqdmlsl) ++ BUILTIN_VSD_HSI (TERNOP, sqdmlal, 0) ++ BUILTIN_VSD_HSI (TERNOP, sqdmlsl, 0) + /* Implemented by aarch64_sqdmll_n. */ +- BUILTIN_VD_HSI (TERNOP, sqdmlal_n) +- BUILTIN_VD_HSI (TERNOP, sqdmlsl_n) ++ BUILTIN_VD_HSI (TERNOP, sqdmlal_n, 0) ++ BUILTIN_VD_HSI (TERNOP, sqdmlsl_n, 0) --/* The mode entries in the following table correspond to the "key" type of the -+/* The NEON builtin data can be found in arm_neon_builtins.def. -+ The mode entries in the following table correspond to the "key" type of the - instruction variant, i.e. equivalent to that which would be specified after - the assembler mnemonic, which usually refers to the last vector operand. - (Signed/unsigned/polynomial types are not differentiated between though, and -@@ -19506,196 +20400,7 @@ +- BUILTIN_VSD_HSI (BINOP, sqdmull) +- BUILTIN_VSD_HSI (TERNOP, sqdmull_lane) +- BUILTIN_VD_HSI (TERNOP, sqdmull_laneq) +- BUILTIN_VD_HSI (BINOP, sqdmull_n) +- BUILTIN_VQ_HSI (BINOP, sqdmull2) +- BUILTIN_VQ_HSI (TERNOP, sqdmull2_lane) +- BUILTIN_VQ_HSI (TERNOP, sqdmull2_laneq) +- BUILTIN_VQ_HSI (BINOP, sqdmull2_n) ++ BUILTIN_VSD_HSI (BINOP, sqdmull, 0) ++ BUILTIN_VSD_HSI (TERNOP, sqdmull_lane, 0) ++ BUILTIN_VD_HSI (TERNOP, sqdmull_laneq, 0) ++ BUILTIN_VD_HSI (BINOP, sqdmull_n, 0) ++ BUILTIN_VQ_HSI (BINOP, sqdmull2, 0) ++ BUILTIN_VQ_HSI (TERNOP, sqdmull2_lane, 0) ++ BUILTIN_VQ_HSI (TERNOP, sqdmull2_laneq, 0) ++ BUILTIN_VQ_HSI (BINOP, sqdmull2_n, 0) + /* Implemented by aarch64_sqdmulh. */ +- BUILTIN_VSDQ_HSI (BINOP, sqdmulh) +- BUILTIN_VSDQ_HSI (BINOP, sqrdmulh) ++ BUILTIN_VSDQ_HSI (BINOP, sqdmulh, 0) ++ BUILTIN_VSDQ_HSI (BINOP, sqrdmulh, 0) + /* Implemented by aarch64_sqdmulh_lane. */ +- BUILTIN_VDQHS (TERNOP, sqdmulh_lane) +- BUILTIN_VDQHS (TERNOP, sqdmulh_laneq) +- BUILTIN_VDQHS (TERNOP, sqrdmulh_lane) +- BUILTIN_VDQHS (TERNOP, sqrdmulh_laneq) +- BUILTIN_SD_HSI (TERNOP, sqdmulh_lane) +- BUILTIN_SD_HSI (TERNOP, sqrdmulh_lane) ++ BUILTIN_VDQHS (TERNOP, sqdmulh_lane, 0) ++ BUILTIN_VDQHS (TERNOP, sqdmulh_laneq, 0) ++ BUILTIN_VDQHS (TERNOP, sqrdmulh_lane, 0) ++ BUILTIN_VDQHS (TERNOP, sqrdmulh_laneq, 0) ++ BUILTIN_SD_HSI (TERNOP, sqdmulh_lane, 0) ++ BUILTIN_SD_HSI (TERNOP, sqrdmulh_lane, 0) - static neon_builtin_datum neon_builtin_data[] = - { -- VAR10 (BINOP, vadd, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR3 (BINOP, vaddl, v8qi, v4hi, v2si), -- VAR3 (BINOP, vaddw, v8qi, v4hi, v2si), -- VAR6 (BINOP, vhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR8 (BINOP, vqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR3 (BINOP, vaddhn, v8hi, v4si, v2di), -- VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si), -- VAR2 (TERNOP, vfma, v2sf, v4sf), -- VAR2 (TERNOP, vfms, v2sf, v4sf), -- VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si), -- VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si), -- VAR2 (TERNOP, vqdmlal, v4hi, v2si), -- VAR2 (TERNOP, vqdmlsl, v4hi, v2si), -- VAR3 (BINOP, vmull, v8qi, v4hi, v2si), -- VAR2 (SCALARMULL, vmull_n, v4hi, v2si), -- VAR2 (LANEMULL, vmull_lane, v4hi, v2si), -- VAR2 (SCALARMULL, vqdmull_n, v4hi, v2si), -- VAR2 (LANEMULL, vqdmull_lane, v4hi, v2si), -- VAR4 (SCALARMULH, vqdmulh_n, v4hi, v2si, v8hi, v4si), -- VAR4 (LANEMULH, vqdmulh_lane, v4hi, v2si, v8hi, v4si), -- VAR2 (BINOP, vqdmull, v4hi, v2si), -- VAR8 (BINOP, vshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR8 (BINOP, vqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR8 (SHIFTIMM, vshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR3 (SHIFTIMM, vshrn_n, v8hi, v4si, v2di), -- VAR3 (SHIFTIMM, vqshrn_n, v8hi, v4si, v2di), -- VAR3 (SHIFTIMM, vqshrun_n, v8hi, v4si, v2di), -- VAR8 (SHIFTIMM, vshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR8 (SHIFTIMM, vqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR8 (SHIFTIMM, vqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR3 (SHIFTIMM, vshll_n, v8qi, v4hi, v2si), -- VAR8 (SHIFTACC, vsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR10 (BINOP, vsub, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR3 (BINOP, vsubl, v8qi, v4hi, v2si), -- VAR3 (BINOP, vsubw, v8qi, v4hi, v2si), -- VAR8 (BINOP, vqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR6 (BINOP, vhsub, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR3 (BINOP, vsubhn, v8hi, v4si, v2di), -- VAR8 (BINOP, vceq, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR8 (BINOP, vcge, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR6 (BINOP, vcgeu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR8 (BINOP, vcgt, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR6 (BINOP, vcgtu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR2 (BINOP, vcage, v2sf, v4sf), -- VAR2 (BINOP, vcagt, v2sf, v4sf), -- VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR8 (BINOP, vabd, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR3 (BINOP, vabdl, v8qi, v4hi, v2si), -- VAR6 (TERNOP, vaba, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR3 (TERNOP, vabal, v8qi, v4hi, v2si), -- VAR8 (BINOP, vmax, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR8 (BINOP, vmin, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR4 (BINOP, vpadd, v8qi, v4hi, v2si, v2sf), -- VAR6 (UNOP, vpaddl, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR6 (BINOP, vpadal, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR4 (BINOP, vpmax, v8qi, v4hi, v2si, v2sf), -- VAR4 (BINOP, vpmin, v8qi, v4hi, v2si, v2sf), -- VAR2 (BINOP, vrecps, v2sf, v4sf), -- VAR2 (BINOP, vrsqrts, v2sf, v4sf), -- VAR8 (SHIFTINSERT, vsri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR8 (SHIFTINSERT, vsli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -- VAR8 (UNOP, vabs, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR6 (UNOP, vqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR8 (UNOP, vneg, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR6 (UNOP, vqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR6 (UNOP, vcls, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR6 (UNOP, vclz, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- VAR2 (UNOP, vcnt, v8qi, v16qi), -- VAR4 (UNOP, vrecpe, v2si, v2sf, v4si, v4sf), -- VAR4 (UNOP, vrsqrte, v2si, v2sf, v4si, v4sf), -- VAR6 (UNOP, vmvn, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -- /* FIXME: vget_lane supports more variants than this! */ -- VAR10 (GETLANE, vget_lane, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (SETLANE, vset_lane, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR5 (CREATE, vcreate, v8qi, v4hi, v2si, v2sf, di), -- VAR10 (DUP, vdup_n, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (DUPLANE, vdup_lane, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR5 (COMBINE, vcombine, v8qi, v4hi, v2si, v2sf, di), -- VAR5 (SPLIT, vget_high, v16qi, v8hi, v4si, v4sf, v2di), -- VAR5 (SPLIT, vget_low, v16qi, v8hi, v4si, v4sf, v2di), -- VAR3 (UNOP, vmovn, v8hi, v4si, v2di), -- VAR3 (UNOP, vqmovn, v8hi, v4si, v2di), -- VAR3 (UNOP, vqmovun, v8hi, v4si, v2di), -- VAR3 (UNOP, vmovl, v8qi, v4hi, v2si), -- VAR6 (LANEMUL, vmul_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR6 (LANEMAC, vmla_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR2 (LANEMAC, vmlal_lane, v4hi, v2si), -- VAR2 (LANEMAC, vqdmlal_lane, v4hi, v2si), -- VAR6 (LANEMAC, vmls_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR2 (LANEMAC, vmlsl_lane, v4hi, v2si), -- VAR2 (LANEMAC, vqdmlsl_lane, v4hi, v2si), -- VAR6 (SCALARMUL, vmul_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR6 (SCALARMAC, vmla_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR2 (SCALARMAC, vmlal_n, v4hi, v2si), -- VAR2 (SCALARMAC, vqdmlal_n, v4hi, v2si), -- VAR6 (SCALARMAC, vmls_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR2 (SCALARMAC, vmlsl_n, v4hi, v2si), -- VAR2 (SCALARMAC, vqdmlsl_n, v4hi, v2si), -- VAR10 (BINOP, vext, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR8 (UNOP, vrev64, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR4 (UNOP, vrev32, v8qi, v4hi, v16qi, v8hi), -- VAR2 (UNOP, vrev16, v8qi, v16qi), -- VAR4 (CONVERT, vcvt, v2si, v2sf, v4si, v4sf), -- VAR4 (FIXCONV, vcvt_n, v2si, v2sf, v4si, v4sf), -- VAR10 (SELECT, vbsl, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR2 (RINT, vrintn, v2sf, v4sf), -- VAR2 (RINT, vrinta, v2sf, v4sf), -- VAR2 (RINT, vrintp, v2sf, v4sf), -- VAR2 (RINT, vrintm, v2sf, v4sf), -- VAR2 (RINT, vrintz, v2sf, v4sf), -- VAR2 (RINT, vrintx, v2sf, v4sf), -- VAR1 (VTBL, vtbl1, v8qi), -- VAR1 (VTBL, vtbl2, v8qi), -- VAR1 (VTBL, vtbl3, v8qi), -- VAR1 (VTBL, vtbl4, v8qi), -- VAR1 (VTBX, vtbx1, v8qi), -- VAR1 (VTBX, vtbx2, v8qi), -- VAR1 (VTBX, vtbx3, v8qi), -- VAR1 (VTBX, vtbx4, v8qi), -- VAR8 (RESULTPAIR, vtrn, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR8 (RESULTPAIR, vzip, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR8 (RESULTPAIR, vuzp, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -- VAR5 (REINTERP, vreinterpretv8qi, v8qi, v4hi, v2si, v2sf, di), -- VAR5 (REINTERP, vreinterpretv4hi, v8qi, v4hi, v2si, v2sf, di), -- VAR5 (REINTERP, vreinterpretv2si, v8qi, v4hi, v2si, v2sf, di), -- VAR5 (REINTERP, vreinterpretv2sf, v8qi, v4hi, v2si, v2sf, di), -- VAR5 (REINTERP, vreinterpretdi, v8qi, v4hi, v2si, v2sf, di), -- VAR5 (REINTERP, vreinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di), -- VAR5 (REINTERP, vreinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di), -- VAR5 (REINTERP, vreinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di), -- VAR5 (REINTERP, vreinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di), -- VAR5 (REINTERP, vreinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (LOAD1, vld1, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (LOAD1LANE, vld1_lane, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (LOAD1, vld1_dup, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (STORE1, vst1, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (STORE1LANE, vst1_lane, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR9 (LOADSTRUCT, -- vld2, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -- VAR7 (LOADSTRUCTLANE, vld2_lane, -- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR5 (LOADSTRUCT, vld2_dup, v8qi, v4hi, v2si, v2sf, di), -- VAR9 (STORESTRUCT, vst2, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -- VAR7 (STORESTRUCTLANE, vst2_lane, -- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR9 (LOADSTRUCT, -- vld3, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -- VAR7 (LOADSTRUCTLANE, vld3_lane, -- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR5 (LOADSTRUCT, vld3_dup, v8qi, v4hi, v2si, v2sf, di), -- VAR9 (STORESTRUCT, vst3, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -- VAR7 (STORESTRUCTLANE, vst3_lane, -- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR9 (LOADSTRUCT, vld4, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -- VAR7 (LOADSTRUCTLANE, vld4_lane, -- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR5 (LOADSTRUCT, vld4_dup, v8qi, v4hi, v2si, v2sf, di), -- VAR9 (STORESTRUCT, vst4, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -- VAR7 (STORESTRUCTLANE, vst4_lane, -- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -- VAR10 (LOGICBINOP, vand, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (LOGICBINOP, vorr, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (BINOP, veor, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (LOGICBINOP, vbic, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -- VAR10 (LOGICBINOP, vorn, -- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) -+#include "arm_neon_builtins.def" - }; +- BUILTIN_VSDQ_I_DI (BINOP, sshl_n) +- BUILTIN_VSDQ_I_DI (BINOP, ushl_n) ++ BUILTIN_VSDQ_I_DI (BINOP, ashl, 3) + /* Implemented by aarch64_shl. */ +- BUILTIN_VSDQ_I_DI (BINOP, sshl) +- BUILTIN_VSDQ_I_DI (BINOP, ushl) +- BUILTIN_VSDQ_I_DI (BINOP, srshl) +- BUILTIN_VSDQ_I_DI (BINOP, urshl) ++ BUILTIN_VSDQ_I_DI (BINOP, sshl, 0) ++ BUILTIN_VSDQ_I_DI (BINOP, ushl, 0) ++ BUILTIN_VSDQ_I_DI (BINOP, srshl, 0) ++ BUILTIN_VSDQ_I_DI (BINOP, urshl, 0) - #undef CF -@@ -19710,9 +20415,36 @@ - #undef VAR9 - #undef VAR10 +- BUILTIN_VSDQ_I_DI (SHIFTIMM, sshr_n) +- BUILTIN_VSDQ_I_DI (SHIFTIMM, ushr_n) ++ BUILTIN_VSDQ_I_DI (SHIFTIMM, ashr, 3) ++ BUILTIN_VSDQ_I_DI (SHIFTIMM, lshr, 3) + /* Implemented by aarch64_shr_n. */ +- BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n) +- BUILTIN_VSDQ_I_DI (SHIFTIMM, urshr_n) ++ BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n, 0) ++ BUILTIN_VSDQ_I_DI (SHIFTIMM, urshr_n, 0) + /* Implemented by aarch64_sra_n. */ +- BUILTIN_VSDQ_I_DI (SHIFTACC, ssra_n) +- BUILTIN_VSDQ_I_DI (SHIFTACC, usra_n) +- BUILTIN_VSDQ_I_DI (SHIFTACC, srsra_n) +- BUILTIN_VSDQ_I_DI (SHIFTACC, ursra_n) ++ BUILTIN_VSDQ_I_DI (SHIFTACC, ssra_n, 0) ++ BUILTIN_VSDQ_I_DI (SHIFTACC, usra_n, 0) ++ BUILTIN_VSDQ_I_DI (SHIFTACC, srsra_n, 0) ++ BUILTIN_VSDQ_I_DI (SHIFTACC, ursra_n, 0) + /* Implemented by aarch64_shll_n. */ +- BUILTIN_VDW (SHIFTIMM, sshll_n) +- BUILTIN_VDW (SHIFTIMM, ushll_n) ++ BUILTIN_VDW (SHIFTIMM, sshll_n, 0) ++ BUILTIN_VDW (SHIFTIMM, ushll_n, 0) + /* Implemented by aarch64_shll2_n. */ +- BUILTIN_VQW (SHIFTIMM, sshll2_n) +- BUILTIN_VQW (SHIFTIMM, ushll2_n) ++ BUILTIN_VQW (SHIFTIMM, sshll2_n, 0) ++ BUILTIN_VQW (SHIFTIMM, ushll2_n, 0) + /* Implemented by aarch64_qshrn_n. */ +- BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrun_n) +- BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrun_n) +- BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrn_n) +- BUILTIN_VSQN_HSDI (SHIFTIMM, uqshrn_n) +- BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrn_n) +- BUILTIN_VSQN_HSDI (SHIFTIMM, uqrshrn_n) ++ BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrun_n, 0) ++ BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrun_n, 0) ++ BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrn_n, 0) ++ BUILTIN_VSQN_HSDI (SHIFTIMM, uqshrn_n, 0) ++ BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrn_n, 0) ++ BUILTIN_VSQN_HSDI (SHIFTIMM, uqrshrn_n, 0) + /* Implemented by aarch64_si_n. */ +- BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssri_n) +- BUILTIN_VSDQ_I_DI (SHIFTINSERT, usri_n) +- BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssli_n) +- BUILTIN_VSDQ_I_DI (SHIFTINSERT, usli_n) ++ BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssri_n, 0) ++ BUILTIN_VSDQ_I_DI (SHIFTINSERT, usri_n, 0) ++ BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssli_n, 0) ++ BUILTIN_VSDQ_I_DI (SHIFTINSERT, usli_n, 0) + /* Implemented by aarch64_qshl_n. */ +- BUILTIN_VSDQ_I (SHIFTIMM, sqshlu_n) +- BUILTIN_VSDQ_I (SHIFTIMM, sqshl_n) +- BUILTIN_VSDQ_I (SHIFTIMM, uqshl_n) ++ BUILTIN_VSDQ_I (SHIFTIMM, sqshlu_n, 0) ++ BUILTIN_VSDQ_I (SHIFTIMM, sqshl_n, 0) ++ BUILTIN_VSDQ_I (SHIFTIMM, uqshl_n, 0) --/* Neon defines builtins from ARM_BUILTIN_MAX upwards, though they don't have -- symbolic names defined here (which would require too much duplication). -- FIXME? */ -+#define CF(N,X) ARM_BUILTIN_NEON_##N##X -+#define VAR1(T, N, A) \ -+ CF (N, A) -+#define VAR2(T, N, A, B) \ -+ VAR1 (T, N, A), \ -+ CF (N, B) -+#define VAR3(T, N, A, B, C) \ -+ VAR2 (T, N, A, B), \ -+ CF (N, C) -+#define VAR4(T, N, A, B, C, D) \ -+ VAR3 (T, N, A, B, C), \ -+ CF (N, D) -+#define VAR5(T, N, A, B, C, D, E) \ -+ VAR4 (T, N, A, B, C, D), \ -+ CF (N, E) -+#define VAR6(T, N, A, B, C, D, E, F) \ -+ VAR5 (T, N, A, B, C, D, E), \ -+ CF (N, F) -+#define VAR7(T, N, A, B, C, D, E, F, G) \ -+ VAR6 (T, N, A, B, C, D, E, F), \ -+ CF (N, G) -+#define VAR8(T, N, A, B, C, D, E, F, G, H) \ -+ VAR7 (T, N, A, B, C, D, E, F, G), \ -+ CF (N, H) -+#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \ -+ VAR8 (T, N, A, B, C, D, E, F, G, H), \ -+ CF (N, I) -+#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \ -+ VAR9 (T, N, A, B, C, D, E, F, G, H, I), \ -+ CF (N, J) - enum arm_builtins - { - ARM_BUILTIN_GETWCGR0, -@@ -19961,13 +20693,54 @@ + /* Implemented by aarch64_cm. */ +- BUILTIN_VSDQ_I_DI (BINOP, cmeq) +- BUILTIN_VSDQ_I_DI (BINOP, cmge) +- BUILTIN_VSDQ_I_DI (BINOP, cmgt) +- BUILTIN_VSDQ_I_DI (BINOP, cmle) +- BUILTIN_VSDQ_I_DI (BINOP, cmlt) ++ BUILTIN_VALLDI (BINOP, cmeq, 0) ++ BUILTIN_VALLDI (BINOP, cmge, 0) ++ BUILTIN_VALLDI (BINOP, cmgt, 0) ++ BUILTIN_VALLDI (BINOP, cmle, 0) ++ BUILTIN_VALLDI (BINOP, cmlt, 0) + /* Implemented by aarch64_cm. */ +- BUILTIN_VSDQ_I_DI (BINOP, cmhs) +- BUILTIN_VSDQ_I_DI (BINOP, cmhi) +- BUILTIN_VSDQ_I_DI (BINOP, cmtst) ++ BUILTIN_VSDQ_I_DI (BINOP, cmgeu, 0) ++ BUILTIN_VSDQ_I_DI (BINOP, cmgtu, 0) ++ BUILTIN_VSDQ_I_DI (BINOP, cmtst, 0) - ARM_BUILTIN_WMERGE, +- /* Implemented by aarch64_. */ +- BUILTIN_VDQF (BINOP, fmax) +- BUILTIN_VDQF (BINOP, fmin) +- /* Implemented by aarch64_. */ +- BUILTIN_VDQ_BHSI (BINOP, smax) +- BUILTIN_VDQ_BHSI (BINOP, smin) +- BUILTIN_VDQ_BHSI (BINOP, umax) +- BUILTIN_VDQ_BHSI (BINOP, umin) ++ /* Implemented by reduc_plus_. */ ++ BUILTIN_VALL (UNOP, reduc_splus_, 10) ++ BUILTIN_VDQ (UNOP, reduc_uplus_, 10) -- ARM_BUILTIN_NEON_BASE, -+ ARM_BUILTIN_CRC32B, -+ ARM_BUILTIN_CRC32H, -+ ARM_BUILTIN_CRC32W, -+ ARM_BUILTIN_CRC32CB, -+ ARM_BUILTIN_CRC32CH, -+ ARM_BUILTIN_CRC32CW, +- /* Implemented by aarch64_frint. */ +- BUILTIN_VDQF (UNOP, frintz) +- BUILTIN_VDQF (UNOP, frintp) +- BUILTIN_VDQF (UNOP, frintm) +- BUILTIN_VDQF (UNOP, frinti) +- BUILTIN_VDQF (UNOP, frintx) +- BUILTIN_VDQF (UNOP, frinta) ++ /* Implemented by reduc__. */ ++ BUILTIN_VDQIF (UNOP, reduc_smax_, 10) ++ BUILTIN_VDQIF (UNOP, reduc_smin_, 10) ++ BUILTIN_VDQ_BHSI (UNOP, reduc_umax_, 10) ++ BUILTIN_VDQ_BHSI (UNOP, reduc_umin_, 10) ++ BUILTIN_VDQF (UNOP, reduc_smax_nan_, 10) ++ BUILTIN_VDQF (UNOP, reduc_smin_nan_, 10) -- ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE + ARRAY_SIZE (neon_builtin_data) -+#undef CRYPTO1 -+#undef CRYPTO2 -+#undef CRYPTO3 -+ -+#define CRYPTO1(L, U, M1, M2) \ -+ ARM_BUILTIN_CRYPTO_##U, -+#define CRYPTO2(L, U, M1, M2, M3) \ -+ ARM_BUILTIN_CRYPTO_##U, -+#define CRYPTO3(L, U, M1, M2, M3, M4) \ -+ ARM_BUILTIN_CRYPTO_##U, -+ -+#include "crypto.def" -+ -+#undef CRYPTO1 -+#undef CRYPTO2 -+#undef CRYPTO3 +- /* Implemented by aarch64_fcvt. */ +- BUILTIN_VDQF (UNOP, fcvtzs) +- BUILTIN_VDQF (UNOP, fcvtzu) +- BUILTIN_VDQF (UNOP, fcvtas) +- BUILTIN_VDQF (UNOP, fcvtau) +- BUILTIN_VDQF (UNOP, fcvtps) +- BUILTIN_VDQF (UNOP, fcvtpu) +- BUILTIN_VDQF (UNOP, fcvtms) +- BUILTIN_VDQF (UNOP, fcvtmu) ++ /* Implemented by 3. ++ smax variants map to fmaxnm, ++ smax_nan variants map to fmax. */ ++ BUILTIN_VDQIF (BINOP, smax, 3) ++ BUILTIN_VDQIF (BINOP, smin, 3) ++ BUILTIN_VDQ_BHSI (BINOP, umax, 3) ++ BUILTIN_VDQ_BHSI (BINOP, umin, 3) ++ BUILTIN_VDQF (BINOP, smax_nan, 3) ++ BUILTIN_VDQF (BINOP, smin_nan, 3) + ++ /* Implemented by 2. */ ++ BUILTIN_VDQF (UNOP, btrunc, 2) ++ BUILTIN_VDQF (UNOP, ceil, 2) ++ BUILTIN_VDQF (UNOP, floor, 2) ++ BUILTIN_VDQF (UNOP, nearbyint, 2) ++ BUILTIN_VDQF (UNOP, rint, 2) ++ BUILTIN_VDQF (UNOP, round, 2) ++ BUILTIN_VDQF (UNOP, frintn, 2) + -+#include "arm_neon_builtins.def" ++ /* Implemented by l2. */ ++ VAR1 (UNOP, lbtruncv2sf, 2, v2si) ++ VAR1 (UNOP, lbtruncv4sf, 2, v4si) ++ VAR1 (UNOP, lbtruncv2df, 2, v2di) + -+ ,ARM_BUILTIN_MAX - }; - -+#define ARM_BUILTIN_NEON_BASE (ARM_BUILTIN_MAX - ARRAY_SIZE (neon_builtin_data)) ++ VAR1 (UNOP, lbtruncuv2sf, 2, v2si) ++ VAR1 (UNOP, lbtruncuv4sf, 2, v4si) ++ VAR1 (UNOP, lbtruncuv2df, 2, v2di) + -+#undef CF -+#undef VAR1 -+#undef VAR2 -+#undef VAR3 -+#undef VAR4 -+#undef VAR5 -+#undef VAR6 -+#undef VAR7 -+#undef VAR8 -+#undef VAR9 -+#undef VAR10 ++ VAR1 (UNOP, lroundv2sf, 2, v2si) ++ VAR1 (UNOP, lroundv4sf, 2, v4si) ++ VAR1 (UNOP, lroundv2df, 2, v2di) ++ /* Implemented by l2. */ ++ VAR1 (UNOP, lroundsf, 2, si) ++ VAR1 (UNOP, lrounddf, 2, di) + - static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX]; - -+#define NUM_DREG_TYPES 5 -+#define NUM_QREG_TYPES 6 ++ VAR1 (UNOP, lrounduv2sf, 2, v2si) ++ VAR1 (UNOP, lrounduv4sf, 2, v4si) ++ VAR1 (UNOP, lrounduv2df, 2, v2di) ++ VAR1 (UNOP, lroundusf, 2, si) ++ VAR1 (UNOP, lroundudf, 2, di) + - static void - arm_init_neon_builtins (void) - { -@@ -19976,10 +20749,12 @@ - - tree neon_intQI_type_node; - tree neon_intHI_type_node; -+ tree neon_floatHF_type_node; - tree neon_polyQI_type_node; - tree neon_polyHI_type_node; - tree neon_intSI_type_node; - tree neon_intDI_type_node; -+ tree neon_intUTI_type_node; - tree neon_float_type_node; - - tree intQI_pointer_node; -@@ -20002,6 +20777,7 @@ - - tree V8QI_type_node; - tree V4HI_type_node; -+ tree V4HF_type_node; - tree V2SI_type_node; - tree V2SF_type_node; - tree V16QI_type_node; -@@ -20041,9 +20817,9 @@ - tree void_ftype_pv4sf_v4sf_v4sf; - tree void_ftype_pv2di_v2di_v2di; - -- tree reinterp_ftype_dreg[5][5]; -- tree reinterp_ftype_qreg[5][5]; -- tree dreg_types[5], qreg_types[5]; -+ tree reinterp_ftype_dreg[NUM_DREG_TYPES][NUM_DREG_TYPES]; -+ tree reinterp_ftype_qreg[NUM_QREG_TYPES][NUM_QREG_TYPES]; -+ tree dreg_types[NUM_DREG_TYPES], qreg_types[NUM_QREG_TYPES]; - - /* Create distinguished type nodes for NEON vector element types, - and pointers to values of such types, so we can detect them later. */ -@@ -20056,6 +20832,9 @@ - neon_float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (neon_float_type_node) = FLOAT_TYPE_SIZE; - layout_type (neon_float_type_node); -+ neon_floatHF_type_node = make_node (REAL_TYPE); -+ TYPE_PRECISION (neon_floatHF_type_node) = GET_MODE_PRECISION (HFmode); -+ layout_type (neon_floatHF_type_node); - - /* Define typedefs which exactly correspond to the modes we are basing vector - types on. If you change these names you'll need to change -@@ -20064,6 +20843,8 @@ - "__builtin_neon_qi"); - (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node, - "__builtin_neon_hi"); -+ (*lang_hooks.types.register_builtin_type) (neon_floatHF_type_node, -+ "__builtin_neon_hf"); - (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node, - "__builtin_neon_si"); - (*lang_hooks.types.register_builtin_type) (neon_float_type_node, -@@ -20105,6 +20886,8 @@ - build_vector_type_for_mode (neon_intQI_type_node, V8QImode); - V4HI_type_node = - build_vector_type_for_mode (neon_intHI_type_node, V4HImode); -+ V4HF_type_node = -+ build_vector_type_for_mode (neon_floatHF_type_node, V4HFmode); - V2SI_type_node = - build_vector_type_for_mode (neon_intSI_type_node, V2SImode); - V2SF_type_node = -@@ -20126,7 +20909,9 @@ - intUHI_type_node = make_unsigned_type (GET_MODE_PRECISION (HImode)); - intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode)); - intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode)); -+ neon_intUTI_type_node = make_unsigned_type (GET_MODE_PRECISION (TImode)); - -+ - (*lang_hooks.types.register_builtin_type) (intUQI_type_node, - "__builtin_neon_uqi"); - (*lang_hooks.types.register_builtin_type) (intUHI_type_node, -@@ -20135,6 +20920,10 @@ - "__builtin_neon_usi"); - (*lang_hooks.types.register_builtin_type) (intUDI_type_node, - "__builtin_neon_udi"); -+ (*lang_hooks.types.register_builtin_type) (intUDI_type_node, -+ "__builtin_neon_poly64"); -+ (*lang_hooks.types.register_builtin_type) (neon_intUTI_type_node, -+ "__builtin_neon_poly128"); - - /* Opaque integer types for structures of vectors. */ - intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode)); -@@ -20196,6 +20985,80 @@ - build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node, - V2DI_type_node, NULL); - -+ if (TARGET_CRYPTO && TARGET_HARD_FLOAT) -+ { -+ tree V4USI_type_node = -+ build_vector_type_for_mode (intUSI_type_node, V4SImode); ++ VAR1 (UNOP, lceilv2sf, 2, v2si) ++ VAR1 (UNOP, lceilv4sf, 2, v4si) ++ VAR1 (UNOP, lceilv2df, 2, v2di) ++ ++ VAR1 (UNOP, lceiluv2sf, 2, v2si) ++ VAR1 (UNOP, lceiluv4sf, 2, v4si) ++ VAR1 (UNOP, lceiluv2df, 2, v2di) ++ VAR1 (UNOP, lceilusf, 2, si) ++ VAR1 (UNOP, lceiludf, 2, di) + -+ tree V16UQI_type_node = -+ build_vector_type_for_mode (intUQI_type_node, V16QImode); ++ VAR1 (UNOP, lfloorv2sf, 2, v2si) ++ VAR1 (UNOP, lfloorv4sf, 2, v4si) ++ VAR1 (UNOP, lfloorv2df, 2, v2di) ++ ++ VAR1 (UNOP, lflooruv2sf, 2, v2si) ++ VAR1 (UNOP, lflooruv4sf, 2, v4si) ++ VAR1 (UNOP, lflooruv2df, 2, v2di) ++ VAR1 (UNOP, lfloorusf, 2, si) ++ VAR1 (UNOP, lfloorudf, 2, di) + -+ tree v16uqi_ftype_v16uqi -+ = build_function_type_list (V16UQI_type_node, V16UQI_type_node, NULL_TREE); ++ VAR1 (UNOP, lfrintnv2sf, 2, v2si) ++ VAR1 (UNOP, lfrintnv4sf, 2, v4si) ++ VAR1 (UNOP, lfrintnv2df, 2, v2di) ++ VAR1 (UNOP, lfrintnsf, 2, si) ++ VAR1 (UNOP, lfrintndf, 2, di) + -+ tree v16uqi_ftype_v16uqi_v16uqi -+ = build_function_type_list (V16UQI_type_node, V16UQI_type_node, -+ V16UQI_type_node, NULL_TREE); -+ -+ tree v4usi_ftype_v4usi -+ = build_function_type_list (V4USI_type_node, V4USI_type_node, NULL_TREE); -+ -+ tree v4usi_ftype_v4usi_v4usi -+ = build_function_type_list (V4USI_type_node, V4USI_type_node, -+ V4USI_type_node, NULL_TREE); -+ -+ tree v4usi_ftype_v4usi_v4usi_v4usi -+ = build_function_type_list (V4USI_type_node, V4USI_type_node, -+ V4USI_type_node, V4USI_type_node, NULL_TREE); -+ -+ tree uti_ftype_udi_udi -+ = build_function_type_list (neon_intUTI_type_node, intUDI_type_node, -+ intUDI_type_node, NULL_TREE); -+ -+ #undef CRYPTO1 -+ #undef CRYPTO2 -+ #undef CRYPTO3 -+ #undef C -+ #undef N -+ #undef CF -+ #undef FT1 -+ #undef FT2 -+ #undef FT3 -+ -+ #define C(U) \ -+ ARM_BUILTIN_CRYPTO_##U -+ #define N(L) \ -+ "__builtin_arm_crypto_"#L -+ #define FT1(R, A) \ -+ R##_ftype_##A -+ #define FT2(R, A1, A2) \ -+ R##_ftype_##A1##_##A2 -+ #define FT3(R, A1, A2, A3) \ -+ R##_ftype_##A1##_##A2##_##A3 -+ #define CRYPTO1(L, U, R, A) \ -+ arm_builtin_decls[C (U)] = add_builtin_function (N (L), FT1 (R, A), \ -+ C (U), BUILT_IN_MD, \ -+ NULL, NULL_TREE); -+ #define CRYPTO2(L, U, R, A1, A2) \ -+ arm_builtin_decls[C (U)] = add_builtin_function (N (L), FT2 (R, A1, A2), \ -+ C (U), BUILT_IN_MD, \ -+ NULL, NULL_TREE); -+ -+ #define CRYPTO3(L, U, R, A1, A2, A3) \ -+ arm_builtin_decls[C (U)] = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \ -+ C (U), BUILT_IN_MD, \ -+ NULL, NULL_TREE); -+ #include "crypto.def" -+ -+ #undef CRYPTO1 -+ #undef CRYPTO2 -+ #undef CRYPTO3 -+ #undef C -+ #undef N -+ #undef FT1 -+ #undef FT2 -+ #undef FT3 -+ } - dreg_types[0] = V8QI_type_node; - dreg_types[1] = V4HI_type_node; - dreg_types[2] = V2SI_type_node; -@@ -20207,14 +21070,17 @@ - qreg_types[2] = V4SI_type_node; - qreg_types[3] = V4SF_type_node; - qreg_types[4] = V2DI_type_node; -+ qreg_types[5] = neon_intUTI_type_node; ++ VAR1 (UNOP, lfrintnuv2sf, 2, v2si) ++ VAR1 (UNOP, lfrintnuv4sf, 2, v4si) ++ VAR1 (UNOP, lfrintnuv2df, 2, v2di) ++ VAR1 (UNOP, lfrintnusf, 2, si) ++ VAR1 (UNOP, lfrintnudf, 2, di) ++ ++ /* Implemented by 2. */ ++ VAR1 (UNOP, floatv2si, 2, v2sf) ++ VAR1 (UNOP, floatv4si, 2, v4sf) ++ VAR1 (UNOP, floatv2di, 2, v2df) ++ ++ VAR1 (UNOP, floatunsv2si, 2, v2sf) ++ VAR1 (UNOP, floatunsv4si, 2, v4sf) ++ VAR1 (UNOP, floatunsv2di, 2, v2df) ++ + /* Implemented by + aarch64_. */ +- BUILTIN_VALL (BINOP, zip1) +- BUILTIN_VALL (BINOP, zip2) +- BUILTIN_VALL (BINOP, uzp1) +- BUILTIN_VALL (BINOP, uzp2) +- BUILTIN_VALL (BINOP, trn1) +- BUILTIN_VALL (BINOP, trn2) ++ BUILTIN_VALL (BINOP, zip1, 0) ++ BUILTIN_VALL (BINOP, zip2, 0) ++ BUILTIN_VALL (BINOP, uzp1, 0) ++ BUILTIN_VALL (BINOP, uzp2, 0) ++ BUILTIN_VALL (BINOP, trn1, 0) ++ BUILTIN_VALL (BINOP, trn2, 0) -- for (i = 0; i < 5; i++) -+ for (i = 0; i < NUM_QREG_TYPES; i++) - { - int j; -- for (j = 0; j < 5; j++) -+ for (j = 0; j < NUM_QREG_TYPES; j++) - { -- reinterp_ftype_dreg[i][j] -- = build_function_type_list (dreg_types[i], dreg_types[j], NULL); -+ if (i < NUM_DREG_TYPES && j < NUM_DREG_TYPES) -+ reinterp_ftype_dreg[i][j] -+ = build_function_type_list (dreg_types[i], dreg_types[j], NULL); ++ /* Implemented by ++ aarch64_frecp. */ ++ BUILTIN_GPF (UNOP, frecpe, 0) ++ BUILTIN_GPF (BINOP, frecps, 0) ++ BUILTIN_GPF (UNOP, frecpx, 0) + - reinterp_ftype_qreg[i][j] - = build_function_type_list (qreg_types[i], qreg_types[j], NULL); - } -@@ -20227,7 +21093,7 @@ - neon_builtin_datum *d = &neon_builtin_data[i]; ++ BUILTIN_VDQF (UNOP, frecpe, 0) ++ BUILTIN_VDQF (BINOP, frecps, 0) ++ ++ BUILTIN_VALLDI (UNOP, abs, 2) ++ ++ VAR1 (UNOP, vec_unpacks_hi_, 10, v4sf) ++ VAR1 (BINOP, float_truncate_hi_, 0, v4sf) ++ ++ VAR1 (UNOP, float_extend_lo_, 0, v2df) ++ VAR1 (UNOP, float_truncate_lo_, 0, v2sf) ++ + /* Implemented by aarch64_ld1. */ +- BUILTIN_VALL (LOAD1, ld1) ++ BUILTIN_VALL (LOAD1, ld1, 0) - const char* const modenames[] = { -- "v8qi", "v4hi", "v2si", "v2sf", "di", -+ "v8qi", "v4hi", "v4hf", "v2si", "v2sf", "di", - "v16qi", "v8hi", "v4si", "v4sf", "v2di", - "ti", "ei", "oi" - }; -@@ -20429,9 +21295,14 @@ + /* Implemented by aarch64_st1. */ +- BUILTIN_VALL (STORE1, st1) ++ BUILTIN_VALL (STORE1, st1, 0) - case NEON_REINTERP: - { -- /* We iterate over 5 doubleword types, then 5 quadword -- types. */ -- int rhs = d->mode % 5; -+ /* We iterate over NUM_DREG_TYPES doubleword types, -+ then NUM_QREG_TYPES quadword types. -+ V4HF is not a type used in reinterpret, so we translate -+ d->mode to the correct index in reinterp_ftype_dreg. */ -+ bool qreg_p -+ = GET_MODE_SIZE (insn_data[d->code].operand[0].mode) > 8; -+ int rhs = (d->mode - ((!qreg_p && (d->mode > T_V4HF)) ? 1 : 0)) -+ % NUM_QREG_TYPES; - switch (insn_data[d->code].operand[0].mode) - { - case V8QImode: ftype = reinterp_ftype_dreg[0][rhs]; break; -@@ -20444,11 +21315,43 @@ - case V4SImode: ftype = reinterp_ftype_qreg[2][rhs]; break; - case V4SFmode: ftype = reinterp_ftype_qreg[3][rhs]; break; - case V2DImode: ftype = reinterp_ftype_qreg[4][rhs]; break; -+ case TImode: ftype = reinterp_ftype_qreg[5][rhs]; break; - default: gcc_unreachable (); - } - } - break; -+ case NEON_FLOAT_WIDEN: -+ { -+ tree eltype = NULL_TREE; -+ tree return_type = NULL_TREE; +--- a/src/gcc/config/aarch64/constraints.md ++++ b/src/gcc/config/aarch64/constraints.md +@@ -75,11 +75,6 @@ + "Integer constant zero." + (match_test "op == const0_rtx")) -+ switch (insn_data[d->code].operand[1].mode) -+ { -+ case V4HFmode: -+ eltype = V4HF_type_node; -+ return_type = V4SF_type_node; -+ break; -+ default: gcc_unreachable (); -+ } -+ ftype = build_function_type_list (return_type, eltype, NULL); -+ break; -+ } -+ case NEON_FLOAT_NARROW: -+ { -+ tree eltype = NULL_TREE; -+ tree return_type = NULL_TREE; -+ -+ switch (insn_data[d->code].operand[1].mode) -+ { -+ case V4SFmode: -+ eltype = V4SF_type_node; -+ return_type = V4HF_type_node; -+ break; -+ default: gcc_unreachable (); -+ } -+ ftype = build_function_type_list (return_type, eltype, NULL); -+ break; -+ } - default: - gcc_unreachable (); - } -@@ -20463,6 +21366,9 @@ - } - } +-(define_constraint "Usa" +- "A constraint that matches an absolute symbolic address." +- (and (match_code "const,symbol_ref") +- (match_test "aarch64_symbolic_address_p (op)"))) +- + (define_constraint "Ush" + "A constraint that matches an absolute symbolic address high part." + (and (match_code "high") +@@ -148,10 +143,25 @@ + "@internal + A constraint that matches vector of immediates." + (and (match_code "const_vector") +- (match_test "aarch64_simd_immediate_valid_for_move (op, GET_MODE (op), +- NULL, NULL, NULL, +- NULL, NULL) != 0"))) ++ (match_test "aarch64_simd_valid_immediate (op, GET_MODE (op), ++ false, NULL)"))) -+#undef NUM_DREG_TYPES -+#undef NUM_QREG_TYPES -+ - #define def_mbuiltin(MASK, NAME, TYPE, CODE) \ - do \ - { \ -@@ -20485,7 +21391,7 @@ - const enum rtx_code comparison; - const unsigned int flag; - }; -- ++(define_constraint "Dh" ++ "@internal ++ A constraint that matches an immediate operand valid for\ ++ AdvSIMD scalar move in HImode." ++ (and (match_code "const_int") ++ (match_test "aarch64_simd_scalar_immediate_valid_for_move (op, ++ HImode)"))) + - static const struct builtin_description bdesc_2arg[] = - { - #define IWMMXT_BUILTIN(code, string, builtin) \ -@@ -20591,6 +21497,33 @@ - IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS) - IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ) - IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ) -+ -+#define CRC32_BUILTIN(L, U) \ -+ {0, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \ -+ UNKNOWN, 0}, -+ CRC32_BUILTIN (crc32b, CRC32B) -+ CRC32_BUILTIN (crc32h, CRC32H) -+ CRC32_BUILTIN (crc32w, CRC32W) -+ CRC32_BUILTIN (crc32cb, CRC32CB) -+ CRC32_BUILTIN (crc32ch, CRC32CH) -+ CRC32_BUILTIN (crc32cw, CRC32CW) -+#undef CRC32_BUILTIN -+ -+ -+#define CRYPTO_BUILTIN(L, U) \ -+ {0, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, ARM_BUILTIN_CRYPTO_##U, \ -+ UNKNOWN, 0}, -+#undef CRYPTO1 -+#undef CRYPTO2 -+#undef CRYPTO3 -+#define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U) -+#define CRYPTO1(L, U, R, A) -+#define CRYPTO3(L, U, R, A1, A2, A3) -+#include "crypto.def" -+#undef CRYPTO1 -+#undef CRYPTO2 -+#undef CRYPTO3 ++(define_constraint "Dq" ++ "@internal ++ A constraint that matches an immediate operand valid for\ ++ AdvSIMD scalar move in QImode." ++ (and (match_code "const_int") ++ (match_test "aarch64_simd_scalar_immediate_valid_for_move (op, ++ QImode)"))) + + (define_constraint "Dl" + "@internal + A constraint that matches vector of immediates for left shifts." +--- a/src/gcc/config/aarch64/aarch64.c ++++ b/src/gcc/config/aarch64/aarch64.c +@@ -45,6 +45,8 @@ + #include "gimple.h" + #include "optabs.h" + #include "dwarf2.h" ++#include "cfgloop.h" ++#include "tree-vectorizer.h" + + /* Classifies an address. + +@@ -87,6 +89,15 @@ + enum aarch64_symbol_type symbol_type; }; - static const struct builtin_description bdesc_1arg[] = -@@ -20619,8 +21552,28 @@ - IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB) - IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH) - IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW) -+ -+#define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U) -+#define CRYPTO2(L, U, R, A1, A2) -+#define CRYPTO3(L, U, R, A1, A2, A3) -+#include "crypto.def" -+#undef CRYPTO1 -+#undef CRYPTO2 -+#undef CRYPTO3 ++struct simd_immediate_info ++{ ++ rtx value; ++ int shift; ++ int element_width; ++ bool mvn; ++ bool msl; ++}; ++ + /* The current code model. */ + enum aarch64_code_model aarch64_cmodel; + +@@ -103,8 +114,6 @@ + static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED; + static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED; + static void aarch64_override_options_after_change (void); +-static int aarch64_simd_valid_immediate (rtx, enum machine_mode, int, rtx *, +- int *, unsigned char *, int *, int *); + static bool aarch64_vector_mode_supported_p (enum machine_mode); + static unsigned bit_count (unsigned HOST_WIDE_INT); + static bool aarch64_const_vec_all_same_int_p (rtx, +@@ -178,14 +187,35 @@ + NAMED_PARAM (FP2FP, 4) }; -+static const struct builtin_description bdesc_3arg[] = ++/* Generic costs for vector insn classes. */ + #if HAVE_DESIGNATED_INITIALIZERS && GCC_VERSION >= 2007 + __extension__ + #endif ++static const struct cpu_vector_cost generic_vector_cost = +{ -+#define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U) -+#define CRYPTO1(L, U, R, A) -+#define CRYPTO2(L, U, R, A1, A2) -+#include "crypto.def" -+#undef CRYPTO1 -+#undef CRYPTO2 -+#undef CRYPTO3 -+ }; -+#undef CRYPTO_BUILTIN -+ - /* Set up all the iWMMXt builtins. This is not called if - TARGET_IWMMXT is zero. */ - -@@ -20815,7 +21768,7 @@ - enum machine_mode mode; - tree type; ++ NAMED_PARAM (scalar_stmt_cost, 1), ++ NAMED_PARAM (scalar_load_cost, 1), ++ NAMED_PARAM (scalar_store_cost, 1), ++ NAMED_PARAM (vec_stmt_cost, 1), ++ NAMED_PARAM (vec_to_scalar_cost, 1), ++ NAMED_PARAM (scalar_to_vec_cost, 1), ++ NAMED_PARAM (vec_align_load_cost, 1), ++ NAMED_PARAM (vec_unalign_load_cost, 1), ++ NAMED_PARAM (vec_unalign_store_cost, 1), ++ NAMED_PARAM (vec_store_cost, 1), ++ NAMED_PARAM (cond_taken_branch_cost, 3), ++ NAMED_PARAM (cond_not_taken_branch_cost, 1) ++}; ++ ++#if HAVE_DESIGNATED_INITIALIZERS && GCC_VERSION >= 2007 ++__extension__ ++#endif + static const struct tune_params generic_tunings = + { + &generic_rtx_cost_table, + &generic_addrcost_table, + &generic_regmove_cost, ++ &generic_vector_cost, + NAMED_PARAM (memmov_cost, 4) + }; -- if (d->name == 0) -+ if (d->name == 0 || !(d->mask == FL_IWMMXT || d->mask == FL_IWMMXT2)) - continue; +@@ -524,13 +554,15 @@ + return; + } - mode = insn_data[d->icode].operand[1].mode; -@@ -21010,6 +21963,42 @@ - } ++ case SYMBOL_TINY_ABSOLUTE: ++ emit_insn (gen_rtx_SET (Pmode, dest, imm)); ++ return; ++ + case SYMBOL_SMALL_GOT: + { + rtx tmp_reg = dest; + if (can_create_pseudo_p ()) +- { +- tmp_reg = gen_reg_rtx (Pmode); +- } ++ tmp_reg = gen_reg_rtx (Pmode); + emit_move_insn (tmp_reg, gen_rtx_HIGH (Pmode, imm)); + emit_insn (gen_ldr_got_small (dest, tmp_reg, imm)); + return; +@@ -581,6 +613,10 @@ + return; + } - static void -+arm_init_crc32_builtins () -+{ -+ tree si_ftype_si_qi -+ = build_function_type_list (unsigned_intSI_type_node, -+ unsigned_intSI_type_node, -+ unsigned_intQI_type_node, NULL_TREE); -+ tree si_ftype_si_hi -+ = build_function_type_list (unsigned_intSI_type_node, -+ unsigned_intSI_type_node, -+ unsigned_intHI_type_node, NULL_TREE); -+ tree si_ftype_si_si -+ = build_function_type_list (unsigned_intSI_type_node, -+ unsigned_intSI_type_node, -+ unsigned_intSI_type_node, NULL_TREE); -+ -+ arm_builtin_decls[ARM_BUILTIN_CRC32B] -+ = add_builtin_function ("__builtin_arm_crc32b", si_ftype_si_qi, -+ ARM_BUILTIN_CRC32B, BUILT_IN_MD, NULL, NULL_TREE); -+ arm_builtin_decls[ARM_BUILTIN_CRC32H] -+ = add_builtin_function ("__builtin_arm_crc32h", si_ftype_si_hi, -+ ARM_BUILTIN_CRC32H, BUILT_IN_MD, NULL, NULL_TREE); -+ arm_builtin_decls[ARM_BUILTIN_CRC32W] -+ = add_builtin_function ("__builtin_arm_crc32w", si_ftype_si_si, -+ ARM_BUILTIN_CRC32W, BUILT_IN_MD, NULL, NULL_TREE); -+ arm_builtin_decls[ARM_BUILTIN_CRC32CB] -+ = add_builtin_function ("__builtin_arm_crc32cb", si_ftype_si_qi, -+ ARM_BUILTIN_CRC32CB, BUILT_IN_MD, NULL, NULL_TREE); -+ arm_builtin_decls[ARM_BUILTIN_CRC32CH] -+ = add_builtin_function ("__builtin_arm_crc32ch", si_ftype_si_hi, -+ ARM_BUILTIN_CRC32CH, BUILT_IN_MD, NULL, NULL_TREE); -+ arm_builtin_decls[ARM_BUILTIN_CRC32CW] -+ = add_builtin_function ("__builtin_arm_crc32cw", si_ftype_si_si, -+ ARM_BUILTIN_CRC32CW, BUILT_IN_MD, NULL, NULL_TREE); -+} ++ case SYMBOL_TINY_GOT: ++ emit_insn (gen_ldr_got_tiny (dest, imm)); ++ return; + -+static void - arm_init_builtins (void) + default: + gcc_unreachable (); + } +@@ -604,49 +640,85 @@ { - if (TARGET_REALLY_IWMMXT) -@@ -21020,6 +22009,9 @@ + rtx low_dst; + +- gcc_assert (GET_MODE (dst) == TImode); ++ enum machine_mode src_mode = GET_MODE (src); ++ enum machine_mode dst_mode = GET_MODE (dst); ++ int src_regno = REGNO (src); ++ int dst_regno = REGNO (dst); - if (arm_fp16_format) - arm_init_fp16_builtins (); ++ gcc_assert (dst_mode == TImode || dst_mode == TFmode); + -+ if (TARGET_CRC32) -+ arm_init_crc32_builtins (); + if (REG_P (dst) && REG_P (src)) + { +- int src_regno = REGNO (src); +- int dst_regno = REGNO (dst); ++ gcc_assert (src_mode == TImode || src_mode == TFmode); + +- gcc_assert (GET_MODE (src) == TImode); +- + /* Handle r -> w, w -> r. */ + if (FP_REGNUM_P (dst_regno) && GP_REGNUM_P (src_regno)) + { +- emit_insn (gen_aarch64_movtilow_di (dst, +- gen_lowpart (word_mode, src))); +- emit_insn (gen_aarch64_movtihigh_di (dst, +- gen_highpart (word_mode, src))); +- return; ++ switch (src_mode) { ++ case TImode: ++ emit_insn ++ (gen_aarch64_movtilow_di (dst, gen_lowpart (word_mode, src))); ++ emit_insn ++ (gen_aarch64_movtihigh_di (dst, gen_highpart (word_mode, src))); ++ return; ++ case TFmode: ++ emit_insn ++ (gen_aarch64_movtflow_di (dst, gen_lowpart (word_mode, src))); ++ emit_insn ++ (gen_aarch64_movtfhigh_di (dst, gen_highpart (word_mode, src))); ++ return; ++ default: ++ gcc_unreachable (); ++ } + } + else if (GP_REGNUM_P (dst_regno) && FP_REGNUM_P (src_regno)) + { +- emit_insn (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst), +- src)); +- emit_insn (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst), +- src)); +- return; ++ switch (src_mode) { ++ case TImode: ++ emit_insn ++ (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst), src)); ++ emit_insn ++ (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst), src)); ++ return; ++ case TFmode: ++ emit_insn ++ (gen_aarch64_movdi_tflow (gen_lowpart (word_mode, dst), src)); ++ emit_insn ++ (gen_aarch64_movdi_tfhigh (gen_highpart (word_mode, dst), src)); ++ return; ++ default: ++ gcc_unreachable (); ++ } + } + /* Fall through to r -> r cases. */ + } + +- low_dst = gen_lowpart (word_mode, dst); +- if (REG_P (low_dst) +- && reg_overlap_mentioned_p (low_dst, src)) +- { +- aarch64_emit_move (gen_highpart (word_mode, dst), +- gen_highpart_mode (word_mode, TImode, src)); +- aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); +- } +- else +- { +- aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); +- aarch64_emit_move (gen_highpart (word_mode, dst), +- gen_highpart_mode (word_mode, TImode, src)); +- } ++ switch (dst_mode) { ++ case TImode: ++ low_dst = gen_lowpart (word_mode, dst); ++ if (REG_P (low_dst) ++ && reg_overlap_mentioned_p (low_dst, src)) ++ { ++ aarch64_emit_move (gen_highpart (word_mode, dst), ++ gen_highpart_mode (word_mode, TImode, src)); ++ aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); ++ } ++ else ++ { ++ aarch64_emit_move (low_dst, gen_lowpart (word_mode, src)); ++ aarch64_emit_move (gen_highpart (word_mode, dst), ++ gen_highpart_mode (word_mode, TImode, src)); ++ } ++ return; ++ case TFmode: ++ emit_move_insn (gen_rtx_REG (DFmode, dst_regno), ++ gen_rtx_REG (DFmode, src_regno)); ++ emit_move_insn (gen_rtx_REG (DFmode, dst_regno + 1), ++ gen_rtx_REG (DFmode, src_regno + 1)); ++ return; ++ default: ++ gcc_unreachable (); ++ } } - /* Return the ARM builtin for CODE. */ -@@ -21113,6 +22105,73 @@ - return x; + bool +@@ -656,11 +728,99 @@ + || ! (FP_REGNUM_P (REGNO (dst)) && FP_REGNUM_P (REGNO (src)))); } -+/* Function to expand ternary builtins. */ -+static rtx -+arm_expand_ternop_builtin (enum insn_code icode, -+ tree exp, rtx target) -+{ -+ rtx pat; -+ tree arg0 = CALL_EXPR_ARG (exp, 0); -+ tree arg1 = CALL_EXPR_ARG (exp, 1); -+ tree arg2 = CALL_EXPR_ARG (exp, 2); ++/* Split a complex SIMD combine. */ + -+ rtx op0 = expand_normal (arg0); -+ rtx op1 = expand_normal (arg1); -+ rtx op2 = expand_normal (arg2); -+ rtx op3 = NULL_RTX; ++void ++aarch64_split_simd_combine (rtx dst, rtx src1, rtx src2) ++{ ++ enum machine_mode src_mode = GET_MODE (src1); ++ enum machine_mode dst_mode = GET_MODE (dst); + -+ /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select -+ lane operand depending on endianness. */ -+ bool builtin_sha1cpm_p = false; ++ gcc_assert (VECTOR_MODE_P (dst_mode)); + -+ if (insn_data[icode].n_operands == 5) ++ if (REG_P (dst) && REG_P (src1) && REG_P (src2)) + { -+ gcc_assert (icode == CODE_FOR_crypto_sha1c -+ || icode == CODE_FOR_crypto_sha1p -+ || icode == CODE_FOR_crypto_sha1m); -+ builtin_sha1cpm_p = true; -+ } -+ enum machine_mode tmode = insn_data[icode].operand[0].mode; -+ enum machine_mode mode0 = insn_data[icode].operand[1].mode; -+ enum machine_mode mode1 = insn_data[icode].operand[2].mode; -+ enum machine_mode mode2 = insn_data[icode].operand[3].mode; -+ -+ -+ if (VECTOR_MODE_P (mode0)) -+ op0 = safe_vector_operand (op0, mode0); -+ if (VECTOR_MODE_P (mode1)) -+ op1 = safe_vector_operand (op1, mode1); -+ if (VECTOR_MODE_P (mode2)) -+ op2 = safe_vector_operand (op2, mode2); -+ -+ if (! target -+ || GET_MODE (target) != tmode -+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ -+ gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode) -+ && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode) -+ && (GET_MODE (op2) == mode2 || GET_MODE (op2) == VOIDmode)); -+ -+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ op0 = copy_to_mode_reg (mode0, op0); -+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) -+ op1 = copy_to_mode_reg (mode1, op1); -+ if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) -+ op2 = copy_to_mode_reg (mode2, op2); -+ if (builtin_sha1cpm_p) -+ op3 = GEN_INT (TARGET_BIG_END ? 1 : 0); ++ rtx (*gen) (rtx, rtx, rtx); + -+ if (builtin_sha1cpm_p) -+ pat = GEN_FCN (icode) (target, op0, op1, op2, op3); -+ else -+ pat = GEN_FCN (icode) (target, op0, op1, op2); -+ if (! pat) -+ return 0; -+ emit_insn (pat); -+ return target; ++ switch (src_mode) ++ { ++ case V8QImode: ++ gen = gen_aarch64_simd_combinev8qi; ++ break; ++ case V4HImode: ++ gen = gen_aarch64_simd_combinev4hi; ++ break; ++ case V2SImode: ++ gen = gen_aarch64_simd_combinev2si; ++ break; ++ case V2SFmode: ++ gen = gen_aarch64_simd_combinev2sf; ++ break; ++ case DImode: ++ gen = gen_aarch64_simd_combinedi; ++ break; ++ case DFmode: ++ gen = gen_aarch64_simd_combinedf; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ emit_insn (gen (dst, src1, src2)); ++ return; ++ } +} + - /* Subroutine of arm_expand_builtin to take care of binop insns. */ - - static rtx -@@ -21162,9 +22221,17 @@ - rtx pat; - tree arg0 = CALL_EXPR_ARG (exp, 0); - rtx op0 = expand_normal (arg0); -+ rtx op1 = NULL_RTX; - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode0 = insn_data[icode].operand[1].mode; -+ bool builtin_sha1h_p = false; - -+ if (insn_data[icode].n_operands == 3) ++/* Split a complex SIMD move. */ ++ ++void ++aarch64_split_simd_move (rtx dst, rtx src) ++{ ++ enum machine_mode src_mode = GET_MODE (src); ++ enum machine_mode dst_mode = GET_MODE (dst); ++ ++ gcc_assert (VECTOR_MODE_P (dst_mode)); ++ ++ if (REG_P (dst) && REG_P (src)) + { -+ gcc_assert (icode == CODE_FOR_crypto_sha1h); -+ builtin_sha1h_p = true; ++ rtx (*gen) (rtx, rtx); ++ ++ gcc_assert (VECTOR_MODE_P (src_mode)); ++ ++ switch (src_mode) ++ { ++ case V16QImode: ++ gen = gen_aarch64_split_simd_movv16qi; ++ break; ++ case V8HImode: ++ gen = gen_aarch64_split_simd_movv8hi; ++ break; ++ case V4SImode: ++ gen = gen_aarch64_split_simd_movv4si; ++ break; ++ case V2DImode: ++ gen = gen_aarch64_split_simd_movv2di; ++ break; ++ case V4SFmode: ++ gen = gen_aarch64_split_simd_movv4sf; ++ break; ++ case V2DFmode: ++ gen = gen_aarch64_split_simd_movv2df; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ emit_insn (gen (dst, src)); ++ return; + } ++} + - if (! target - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) -@@ -21179,8 +22246,13 @@ - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); + static rtx +-aarch64_force_temporary (rtx x, rtx value) ++aarch64_force_temporary (enum machine_mode mode, rtx x, rtx value) + { + if (can_create_pseudo_p ()) +- return force_reg (Pmode, value); ++ return force_reg (mode, value); + else + { + x = aarch64_emit_move (x, value); +@@ -672,15 +832,16 @@ + static rtx + aarch64_add_offset (enum machine_mode mode, rtx temp, rtx reg, HOST_WIDE_INT offset) + { +- if (!aarch64_plus_immediate (GEN_INT (offset), DImode)) ++ if (!aarch64_plus_immediate (GEN_INT (offset), mode)) + { + rtx high; + /* Load the full offset into a register. This + might be improvable in the future. */ + high = GEN_INT (offset); + offset = 0; +- high = aarch64_force_temporary (temp, high); +- reg = aarch64_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg)); ++ high = aarch64_force_temporary (mode, temp, high); ++ reg = aarch64_force_temporary (mode, temp, ++ gen_rtx_PLUS (mode, high, reg)); } -+ if (builtin_sha1h_p) -+ op1 = GEN_INT (TARGET_BIG_END ? 1 : 0); + return plus_constant (mode, reg, offset); + } +@@ -719,7 +880,7 @@ + && targetm.cannot_force_const_mem (mode, imm)) + { + gcc_assert(can_create_pseudo_p ()); +- base = aarch64_force_temporary (dest, base); ++ base = aarch64_force_temporary (mode, dest, base); + base = aarch64_add_offset (mode, NULL, base, INTVAL (offset)); + aarch64_emit_move (dest, base); + return; +@@ -733,10 +894,11 @@ + case SYMBOL_SMALL_TLSDESC: + case SYMBOL_SMALL_GOTTPREL: + case SYMBOL_SMALL_GOT: ++ case SYMBOL_TINY_GOT: + if (offset != const0_rtx) + { + gcc_assert(can_create_pseudo_p ()); +- base = aarch64_force_temporary (dest, base); ++ base = aarch64_force_temporary (mode, dest, base); + base = aarch64_add_offset (mode, NULL, base, INTVAL (offset)); + aarch64_emit_move (dest, base); + return; +@@ -745,6 +907,7 @@ -- pat = GEN_FCN (icode) (target, op0); -+ if (builtin_sha1h_p) -+ pat = GEN_FCN (icode) (target, op0, op1); -+ else -+ pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); -@@ -21452,6 +22524,8 @@ - case NEON_DUP: - case NEON_RINT: - case NEON_SPLIT: -+ case NEON_FLOAT_WIDEN: -+ case NEON_FLOAT_NARROW: - case NEON_REINTERP: - return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode, - NEON_ARG_COPY_TO_REG, NEON_ARG_STOP); -@@ -21649,7 +22723,7 @@ - rtx op1; - rtx op2; - rtx pat; -- int fcode = DECL_FUNCTION_CODE (fndecl); -+ unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - size_t i; - enum machine_mode tmode; - enum machine_mode mode0; -@@ -22143,6 +23217,10 @@ - if (d->code == (const enum arm_builtins) fcode) - return arm_expand_unop_builtin (d->icode, exp, target, 0); - -+ for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++) -+ if (d->code == (const enum arm_builtins) fcode) -+ return arm_expand_ternop_builtin (d->icode, exp, target); + case SYMBOL_SMALL_TPREL: + case SYMBOL_SMALL_ABSOLUTE: ++ case SYMBOL_TINY_ABSOLUTE: + aarch64_load_symref_appropriately (dest, imm, sty); + return; + +@@ -2553,12 +2716,14 @@ + aarch64_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) + { + rtx base, offset; + - /* @@@ Should really do something sensible here. */ - return NULL_RTX; + if (GET_CODE (x) == HIGH) + return true; + + split_const (x, &base, &offset); + if (GET_CODE (base) == SYMBOL_REF || GET_CODE (base) == LABEL_REF) +- return (aarch64_classify_symbol (base, SYMBOL_CONTEXT_ADR) != SYMBOL_FORCE_TO_MEM); ++ return (aarch64_classify_symbol (base, SYMBOL_CONTEXT_ADR) ++ != SYMBOL_FORCE_TO_MEM); + + return aarch64_tls_referenced_p (x); } -@@ -23366,7 +24444,7 @@ - all we really need to check here is if single register is to be - returned, or multiple register return. */ - void --thumb2_expand_return (void) -+thumb2_expand_return (bool simple_return) - { - int i, num_regs; - unsigned long saved_regs_mask; -@@ -23379,7 +24457,7 @@ - if (saved_regs_mask & (1 << i)) - num_regs++; +@@ -2996,10 +3161,13 @@ -- if (saved_regs_mask) -+ if (!simple_return && saved_regs_mask) - { - if (num_regs == 1) - { -@@ -23658,6 +24736,7 @@ + /* Classify the base of symbolic expression X, given that X appears in + context CONTEXT. */ +-static enum aarch64_symbol_type +-aarch64_classify_symbolic_expression (rtx x, enum aarch64_symbol_context context) ++ ++enum aarch64_symbol_type ++aarch64_classify_symbolic_expression (rtx x, ++ enum aarch64_symbol_context context) + { + rtx offset; ++ + split_const (x, &x, &offset); + return aarch64_classify_symbol (x, context); + } +@@ -3087,17 +3255,19 @@ + if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode) + && y == const0_rtx + && (code == EQ || code == NE || code == LT || code == GE) +- && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS || GET_CODE (x) == AND)) ++ && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS || GET_CODE (x) == AND ++ || GET_CODE (x) == NEG)) + return CC_NZmode; - if (frame_pointer_needed) - { -+ rtx insn; - /* Restore stack pointer if necessary. */ - if (TARGET_ARM) - { -@@ -23668,9 +24747,12 @@ - /* Force out any pending memory operations that reference stacked data - before stack de-allocation occurs. */ - emit_insn (gen_blockage ()); -- emit_insn (gen_addsi3 (stack_pointer_rtx, -- hard_frame_pointer_rtx, -- GEN_INT (amount))); -+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, -+ hard_frame_pointer_rtx, -+ GEN_INT (amount))); -+ arm_add_cfa_adjust_cfa_note (insn, amount, -+ stack_pointer_rtx, -+ hard_frame_pointer_rtx); +- /* A compare with a shifted operand. Because of canonicalization, ++ /* A compare with a shifted or negated operand. Because of canonicalization, + the comparison will have to be swapped when we emit the assembly + code. */ + if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode) + && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG) + && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT + || GET_CODE (x) == LSHIFTRT +- || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)) ++ || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND ++ || GET_CODE (x) == NEG)) + return CC_SWPmode; - /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not - deleted. */ -@@ -23680,16 +24762,25 @@ - { - /* In Thumb-2 mode, the frame pointer points to the last saved - register. */ -- amount = offsets->locals_base - offsets->saved_regs; -- if (amount) -- emit_insn (gen_addsi3 (hard_frame_pointer_rtx, -- hard_frame_pointer_rtx, -- GEN_INT (amount))); -+ amount = offsets->locals_base - offsets->saved_regs; -+ if (amount) -+ { -+ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, -+ hard_frame_pointer_rtx, -+ GEN_INT (amount))); -+ arm_add_cfa_adjust_cfa_note (insn, amount, -+ hard_frame_pointer_rtx, -+ hard_frame_pointer_rtx); -+ } + /* A compare of a mode narrower than SI mode against zero can be done +@@ -3282,26 +3452,6 @@ + asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]); + break; - /* Force out any pending memory operations that reference stacked data - before stack de-allocation occurs. */ - emit_insn (gen_blockage ()); -- emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx)); -+ insn = emit_insn (gen_movsi (stack_pointer_rtx, -+ hard_frame_pointer_rtx)); -+ arm_add_cfa_adjust_cfa_note (insn, 0, -+ stack_pointer_rtx, -+ hard_frame_pointer_rtx); - /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not - deleted. */ - emit_insn (gen_force_register_use (stack_pointer_rtx)); -@@ -23702,12 +24793,15 @@ - amount = offsets->outgoing_args - offsets->saved_regs; - if (amount) - { -+ rtx tmp; - /* Force out any pending memory operations that reference stacked data - before stack de-allocation occurs. */ - emit_insn (gen_blockage ()); -- emit_insn (gen_addsi3 (stack_pointer_rtx, -- stack_pointer_rtx, -- GEN_INT (amount))); -+ tmp = emit_insn (gen_addsi3 (stack_pointer_rtx, -+ stack_pointer_rtx, -+ GEN_INT (amount))); -+ arm_add_cfa_adjust_cfa_note (tmp, amount, -+ stack_pointer_rtx, stack_pointer_rtx); - /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is - not deleted. */ - emit_insn (gen_force_register_use (stack_pointer_rtx)); -@@ -23760,6 +24854,8 @@ - REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE, - gen_rtx_REG (V2SImode, i), - NULL_RTX); -+ arm_add_cfa_adjust_cfa_note (insn, UNITS_PER_WORD, -+ stack_pointer_rtx, stack_pointer_rtx); - } +- case 'Q': +- /* Print the least significant register of a pair (TImode) of regs. */ +- if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1)) +- { +- output_operand_lossage ("invalid operand for '%%%c'", code); +- return; +- } +- asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0)]); +- break; +- +- case 'R': +- /* Print the most significant register of a pair (TImode) of regs. */ +- if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1)) +- { +- output_operand_lossage ("invalid operand for '%%%c'", code); +- return; +- } +- asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1)]); +- break; +- + case 'm': + /* Print a condition (eq, ne, etc). */ - if (saved_regs_mask) -@@ -23807,6 +24903,9 @@ - REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE, - gen_rtx_REG (SImode, i), - NULL_RTX); -+ arm_add_cfa_adjust_cfa_note (insn, UNITS_PER_WORD, -+ stack_pointer_rtx, -+ stack_pointer_rtx); - } - } - } -@@ -23818,6 +24917,8 @@ - { - if (TARGET_THUMB2) - thumb2_emit_ldrd_pop (saved_regs_mask); -+ else if (TARGET_ARM && !IS_INTERRUPT (func_type)) -+ arm_emit_ldrd_pop (saved_regs_mask); - else - arm_emit_multi_reg_pop (saved_regs_mask); - } -@@ -23830,10 +24931,34 @@ - } +@@ -3349,7 +3499,7 @@ + output_operand_lossage ("incompatible floating point / vector register operand for '%%%c'", code); + return; + } +- asm_fprintf (f, "%s%c%d", REGISTER_PREFIX, code, REGNO (x) - V0_REGNUM); ++ asm_fprintf (f, "%c%d", code, REGNO (x) - V0_REGNUM); + break; - if (crtl->args.pretend_args_size) -- emit_insn (gen_addsi3 (stack_pointer_rtx, -- stack_pointer_rtx, -- GEN_INT (crtl->args.pretend_args_size))); -+ { -+ int i, j; -+ rtx dwarf = NULL_RTX; -+ rtx tmp = emit_insn (gen_addsi3 (stack_pointer_rtx, -+ stack_pointer_rtx, -+ GEN_INT (crtl->args.pretend_args_size))); + case 'S': +@@ -3362,18 +3512,17 @@ + output_operand_lossage ("incompatible floating point / vector register operand for '%%%c'", code); + return; + } +- asm_fprintf (f, "%sv%d", REGISTER_PREFIX, +- REGNO (x) - V0_REGNUM + (code - 'S')); ++ asm_fprintf (f, "v%d", REGNO (x) - V0_REGNUM + (code - 'S')); + break; -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ -+ if (cfun->machine->uses_anonymous_args) -+ { -+ /* Restore pretend args. Refer arm_expand_prologue on how to save -+ pretend_args in stack. */ -+ int num_regs = crtl->args.pretend_args_size / 4; -+ saved_regs_mask = (0xf0 >> num_regs) & 0xf; -+ for (j = 0, i = 0; j < num_regs; i++) -+ if (saved_regs_mask & (1 << i)) -+ { -+ rtx reg = gen_rtx_REG (SImode, i); -+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); -+ j++; -+ } -+ REG_NOTES (tmp) = dwarf; -+ } -+ arm_add_cfa_adjust_cfa_note (tmp, crtl->args.pretend_args_size, -+ stack_pointer_rtx, stack_pointer_rtx); -+ } -+ - if (!really_return) - return; + case 'X': +- /* Print integer constant in hex. */ ++ /* Print bottom 16 bits of integer constant in hex. */ + if (GET_CODE (x) != CONST_INT) + { + output_operand_lossage ("invalid operand for '%%%c'", code); + return; + } +- asm_fprintf (f, "0x%wx", UINTVAL (x)); ++ asm_fprintf (f, "0x%wx", UINTVAL (x) & 0xffff); + break; -@@ -24229,7 +25354,22 @@ - { - const char *fpu_name; - if (arm_selected_arch) -- asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name); -+ { -+ const char* pos = strchr (arm_selected_arch->name, '+'); -+ if (pos) -+ { -+ char buf[15]; -+ gcc_assert (strlen (arm_selected_arch->name) -+ <= sizeof (buf) / sizeof (*pos)); -+ strncpy (buf, arm_selected_arch->name, -+ (pos - arm_selected_arch->name) * sizeof (*pos)); -+ buf[pos - arm_selected_arch->name] = '\0'; -+ asm_fprintf (asm_out_file, "\t.arch %s\n", buf); -+ asm_fprintf (asm_out_file, "\t.arch_extension %s\n", pos + 1); -+ } -+ else -+ asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name); -+ } - else if (strncmp (arm_selected_cpu->name, "generic", 7) == 0) - asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_cpu->name + 8); - else -@@ -25086,7 +26226,7 @@ - { - /* Neon also supports V2SImode, etc. listed in the clause below. */ - if (TARGET_NEON && (mode == V2SFmode || mode == V4SImode || mode == V8HImode -- || mode == V16QImode || mode == V4SFmode || mode == V2DImode)) -+ || mode == V4HFmode || mode == V16QImode || mode == V4SFmode || mode == V2DImode)) - return true; + case 'w': +@@ -3383,20 +3532,19 @@ + if (x == const0_rtx + || (CONST_DOUBLE_P (x) && aarch64_float_const_zero_rtx_p (x))) + { +- asm_fprintf (f, "%s%czr", REGISTER_PREFIX, code); ++ asm_fprintf (f, "%czr", code); + break; + } - if ((TARGET_NEON || TARGET_IWMMXT) -@@ -25249,9 +26389,8 @@ + if (REG_P (x) && GP_REGNUM_P (REGNO (x))) + { +- asm_fprintf (f, "%s%c%d", REGISTER_PREFIX, code, +- REGNO (x) - R0_REGNUM); ++ asm_fprintf (f, "%c%d", code, REGNO (x) - R0_REGNUM); + break; + } - nregs = GET_MODE_SIZE (GET_MODE (rtl)) / 8; - p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs)); -- regno = (regno - FIRST_VFP_REGNUM) / 2; - for (i = 0; i < nregs; i++) -- XVECEXP (p, 0, i) = gen_rtx_REG (DImode, 256 + regno + i); -+ XVECEXP (p, 0, i) = gen_rtx_REG (DImode, regno + i); + if (REG_P (x) && REGNO (x) == SP_REGNUM) + { +- asm_fprintf (f, "%s%ssp", REGISTER_PREFIX, code == 'w' ? "w" : ""); ++ asm_fprintf (f, "%ssp", code == 'w' ? "w" : ""); + break; + } - return p; - } -@@ -25501,9 +26640,17 @@ - handled_one = true; +@@ -3504,6 +3652,10 @@ + asm_fprintf (asm_out_file, ":tprel:"); break; -+ /* The INSN is generated in epilogue. It is set as RTX_FRAME_RELATED_P -+ to get correct dwarf information for shrink-wrap. We should not -+ emit unwind information for it because these are used either for -+ pretend arguments or notes to adjust sp and restore registers from -+ stack. */ -+ case REG_CFA_ADJUST_CFA: -+ case REG_CFA_RESTORE: -+ return; ++ case SYMBOL_TINY_GOT: ++ gcc_unreachable (); ++ break; + - case REG_CFA_DEF_CFA: - case REG_CFA_EXPRESSION: -- case REG_CFA_ADJUST_CFA: - case REG_CFA_OFFSET: - /* ??? Only handling here what we actually emit. */ - gcc_unreachable (); -@@ -25901,6 +27048,7 @@ - case cortexa7: - case cortexa8: - case cortexa9: -+ case cortexa53: - case fa726te: - case marvell_pj4: - return 2; -@@ -25929,11 +27077,13 @@ - { V8QImode, "__builtin_neon_uqi", "16__simd64_uint8_t" }, - { V4HImode, "__builtin_neon_hi", "16__simd64_int16_t" }, - { V4HImode, "__builtin_neon_uhi", "17__simd64_uint16_t" }, -+ { V4HFmode, "__builtin_neon_hf", "18__simd64_float16_t" }, - { V2SImode, "__builtin_neon_si", "16__simd64_int32_t" }, - { V2SImode, "__builtin_neon_usi", "17__simd64_uint32_t" }, - { V2SFmode, "__builtin_neon_sf", "18__simd64_float32_t" }, - { V8QImode, "__builtin_neon_poly8", "16__simd64_poly8_t" }, - { V4HImode, "__builtin_neon_poly16", "17__simd64_poly16_t" }, + default: + break; + } +@@ -3533,6 +3685,10 @@ + asm_fprintf (asm_out_file, ":tprel_lo12_nc:"); + break; + ++ case SYMBOL_TINY_GOT: ++ asm_fprintf (asm_out_file, ":got:"); ++ break; + - /* 128-bit containerized types. */ - { V16QImode, "__builtin_neon_qi", "16__simd128_int8_t" }, - { V16QImode, "__builtin_neon_uqi", "17__simd128_uint8_t" }, -@@ -26027,6 +27177,60 @@ - return !TARGET_THUMB1; + default: + break; + } +@@ -3647,13 +3803,6 @@ + output_addr_const (f, x); + } + +-void +-aarch64_function_profiler (FILE *f ATTRIBUTE_UNUSED, +- int labelno ATTRIBUTE_UNUSED) +-{ +- sorry ("function profiling"); +-} +- + bool + aarch64_label_mentioned_p (rtx x) + { +@@ -4601,6 +4750,101 @@ + return aarch64_tune_params->memmov_cost; } -+tree -+arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) ++/* Vectorizer cost model target hooks. */ ++ ++/* Implement targetm.vectorize.builtin_vectorization_cost. */ ++static int ++aarch64_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, ++ tree vectype, ++ int misalign ATTRIBUTE_UNUSED) +{ -+ enum machine_mode in_mode, out_mode; -+ int in_n, out_n; ++ unsigned elements; + -+ if (TREE_CODE (type_out) != VECTOR_TYPE -+ || TREE_CODE (type_in) != VECTOR_TYPE -+ || !(TARGET_NEON && TARGET_FPU_ARMV8 && flag_unsafe_math_optimizations)) -+ return NULL_TREE; ++ switch (type_of_cost) ++ { ++ case scalar_stmt: ++ return aarch64_tune_params->vec_costs->scalar_stmt_cost; + -+ out_mode = TYPE_MODE (TREE_TYPE (type_out)); -+ out_n = TYPE_VECTOR_SUBPARTS (type_out); -+ in_mode = TYPE_MODE (TREE_TYPE (type_in)); -+ in_n = TYPE_VECTOR_SUBPARTS (type_in); ++ case scalar_load: ++ return aarch64_tune_params->vec_costs->scalar_load_cost; + -+/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the -+ decl of the vectorized builtin for the appropriate vector mode. -+ NULL_TREE is returned if no such builtin is available. */ -+#undef ARM_CHECK_BUILTIN_MODE -+#define ARM_CHECK_BUILTIN_MODE(C) \ -+ (out_mode == SFmode && out_n == C \ -+ && in_mode == SFmode && in_n == C) ++ case scalar_store: ++ return aarch64_tune_params->vec_costs->scalar_store_cost; + -+#undef ARM_FIND_VRINT_VARIANT -+#define ARM_FIND_VRINT_VARIANT(N) \ -+ (ARM_CHECK_BUILTIN_MODE (2) \ -+ ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \ -+ : (ARM_CHECK_BUILTIN_MODE (4) \ -+ ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \ -+ : NULL_TREE)) ++ case vector_stmt: ++ return aarch64_tune_params->vec_costs->vec_stmt_cost; + -+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) ++ case vector_load: ++ return aarch64_tune_params->vec_costs->vec_align_load_cost; ++ ++ case vector_store: ++ return aarch64_tune_params->vec_costs->vec_store_cost; ++ ++ case vec_to_scalar: ++ return aarch64_tune_params->vec_costs->vec_to_scalar_cost; ++ ++ case scalar_to_vec: ++ return aarch64_tune_params->vec_costs->scalar_to_vec_cost; ++ ++ case unaligned_load: ++ return aarch64_tune_params->vec_costs->vec_unalign_load_cost; ++ ++ case unaligned_store: ++ return aarch64_tune_params->vec_costs->vec_unalign_store_cost; ++ ++ case cond_branch_taken: ++ return aarch64_tune_params->vec_costs->cond_taken_branch_cost; ++ ++ case cond_branch_not_taken: ++ return aarch64_tune_params->vec_costs->cond_not_taken_branch_cost; ++ ++ case vec_perm: ++ case vec_promote_demote: ++ return aarch64_tune_params->vec_costs->vec_stmt_cost; ++ ++ case vec_construct: ++ elements = TYPE_VECTOR_SUBPARTS (vectype); ++ return elements / 2 + 1; ++ ++ default: ++ gcc_unreachable (); ++ } ++} ++ ++/* Implement targetm.vectorize.add_stmt_cost. */ ++static unsigned ++aarch64_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, ++ struct _stmt_vec_info *stmt_info, int misalign, ++ enum vect_cost_model_location where) ++{ ++ unsigned *cost = (unsigned *) data; ++ unsigned retval = 0; ++ ++ if (flag_vect_cost_model) + { -+ enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); -+ switch (fn) -+ { -+ case BUILT_IN_FLOORF: -+ return ARM_FIND_VRINT_VARIANT (vrintm); -+ case BUILT_IN_CEILF: -+ return ARM_FIND_VRINT_VARIANT (vrintp); -+ case BUILT_IN_TRUNCF: -+ return ARM_FIND_VRINT_VARIANT (vrintz); -+ case BUILT_IN_ROUNDF: -+ return ARM_FIND_VRINT_VARIANT (vrinta); -+ default: -+ return NULL_TREE; -+ } ++ tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; ++ int stmt_cost = ++ aarch64_builtin_vectorization_cost (kind, vectype, misalign); ++ ++ /* Statements in an inner loop relative to the loop being ++ vectorized are weighted more heavily. The value here is ++ a function (linear for now) of the loop nest level. */ ++ if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) ++ { ++ loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info); ++ struct loop *loop = LOOP_VINFO_LOOP (loop_info); ++ unsigned nest_level = loop_depth (loop); ++ ++ count *= nest_level; ++ } ++ ++ retval = (unsigned) (count * stmt_cost); ++ cost[where] += retval; + } -+ return NULL_TREE; ++ ++ return retval; +} -+#undef ARM_CHECK_BUILTIN_MODE -+#undef ARM_FIND_VRINT_VARIANT + - /* The AAPCS sets the maximum alignment of a vector to 64 bits. */ - static HOST_WIDE_INT - arm_vector_alignment (const_tree type) -@@ -26257,40 +27461,72 @@ - emit_insn (gen_memory_barrier ()); - } + static void initialize_aarch64_code_model (void); --/* Emit the load-exclusive and store-exclusive instructions. */ -+/* Emit the load-exclusive and store-exclusive instructions. -+ Use acquire and release versions if necessary. */ + /* Parse the architecture extension string. */ +@@ -4956,6 +5200,7 @@ - static void --arm_emit_load_exclusive (enum machine_mode mode, rtx rval, rtx mem) -+arm_emit_load_exclusive (enum machine_mode mode, rtx rval, rtx mem, bool acq) - { - rtx (*gen) (rtx, rtx); + /* Return the method that should be used to access SYMBOL_REF or + LABEL_REF X in context CONTEXT. */ ++ + enum aarch64_symbol_type + aarch64_classify_symbol (rtx x, + enum aarch64_symbol_context context ATTRIBUTE_UNUSED) +@@ -4969,6 +5214,8 @@ -- switch (mode) -+ if (acq) - { -- case QImode: gen = gen_arm_load_exclusiveqi; break; -- case HImode: gen = gen_arm_load_exclusivehi; break; -- case SImode: gen = gen_arm_load_exclusivesi; break; -- case DImode: gen = gen_arm_load_exclusivedi; break; -- default: -- gcc_unreachable (); -+ switch (mode) -+ { -+ case QImode: gen = gen_arm_load_acquire_exclusiveqi; break; -+ case HImode: gen = gen_arm_load_acquire_exclusivehi; break; -+ case SImode: gen = gen_arm_load_acquire_exclusivesi; break; -+ case DImode: gen = gen_arm_load_acquire_exclusivedi; break; -+ default: -+ gcc_unreachable (); -+ } + case AARCH64_CMODEL_TINY_PIC: + case AARCH64_CMODEL_TINY: ++ return SYMBOL_TINY_ABSOLUTE; ++ + case AARCH64_CMODEL_SMALL_PIC: + case AARCH64_CMODEL_SMALL: + return SYMBOL_SMALL_ABSOLUTE; +@@ -4978,71 +5225,47 @@ + } } -+ else -+ { -+ switch (mode) -+ { -+ case QImode: gen = gen_arm_load_exclusiveqi; break; -+ case HImode: gen = gen_arm_load_exclusivehi; break; -+ case SImode: gen = gen_arm_load_exclusivesi; break; -+ case DImode: gen = gen_arm_load_exclusivedi; break; -+ default: -+ gcc_unreachable (); -+ } + +- gcc_assert (GET_CODE (x) == SYMBOL_REF); +- +- switch (aarch64_cmodel) ++ if (GET_CODE (x) == SYMBOL_REF) + { +- case AARCH64_CMODEL_LARGE: +- return SYMBOL_FORCE_TO_MEM; +- +- case AARCH64_CMODEL_TINY: +- case AARCH64_CMODEL_SMALL: +- +- /* This is needed to get DFmode, TImode constants to be loaded off +- the constant pool. Is it necessary to dump TImode values into +- the constant pool. We don't handle TImode constant loads properly +- yet and hence need to use the constant pool. */ +- if (CONSTANT_POOL_ADDRESS_P (x)) ++ if (aarch64_cmodel == AARCH64_CMODEL_LARGE ++ || CONSTANT_POOL_ADDRESS_P (x)) + return SYMBOL_FORCE_TO_MEM; + + if (aarch64_tls_symbol_p (x)) + return aarch64_classify_tls_symbol (x); + +- if (SYMBOL_REF_WEAK (x)) +- return SYMBOL_FORCE_TO_MEM; ++ switch (aarch64_cmodel) ++ { ++ case AARCH64_CMODEL_TINY: ++ if (SYMBOL_REF_WEAK (x)) ++ return SYMBOL_FORCE_TO_MEM; ++ return SYMBOL_TINY_ABSOLUTE; + +- return SYMBOL_SMALL_ABSOLUTE; ++ case AARCH64_CMODEL_SMALL: ++ if (SYMBOL_REF_WEAK (x)) ++ return SYMBOL_FORCE_TO_MEM; ++ return SYMBOL_SMALL_ABSOLUTE; + +- case AARCH64_CMODEL_TINY_PIC: +- case AARCH64_CMODEL_SMALL_PIC: ++ case AARCH64_CMODEL_TINY_PIC: ++ if (!aarch64_symbol_binds_local_p (x)) ++ return SYMBOL_TINY_GOT; ++ return SYMBOL_TINY_ABSOLUTE; + +- if (CONSTANT_POOL_ADDRESS_P (x)) +- return SYMBOL_FORCE_TO_MEM; ++ case AARCH64_CMODEL_SMALL_PIC: ++ if (!aarch64_symbol_binds_local_p (x)) ++ return SYMBOL_SMALL_GOT; ++ return SYMBOL_SMALL_ABSOLUTE; + +- if (aarch64_tls_symbol_p (x)) +- return aarch64_classify_tls_symbol (x); ++ default: ++ gcc_unreachable (); ++ } + } - emit_insn (gen (rval, mem)); +- if (!aarch64_symbol_binds_local_p (x)) +- return SYMBOL_SMALL_GOT; +- +- return SYMBOL_SMALL_ABSOLUTE; +- +- default: +- gcc_unreachable (); +- } + /* By default push everything into the constant pool. */ + return SYMBOL_FORCE_TO_MEM; } - static void --arm_emit_store_exclusive (enum machine_mode mode, rtx bval, rtx rval, rtx mem) -+arm_emit_store_exclusive (enum machine_mode mode, rtx bval, rtx rval, -+ rtx mem, bool rel) +-/* Return true if X is a symbolic constant that can be used in context +- CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */ +- + bool +-aarch64_symbolic_constant_p (rtx x, enum aarch64_symbol_context context, +- enum aarch64_symbol_type *symbol_type) +-{ +- rtx offset; +- split_const (x, &x, &offset); +- if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) +- *symbol_type = aarch64_classify_symbol (x, context); +- else +- return false; +- +- /* No checking of offset at this point. */ +- return true; +-} +- +-bool + aarch64_constant_address_p (rtx x) { - rtx (*gen) (rtx, rtx, rtx); + return (CONSTANT_P (x) && memory_address_p (DImode, x)); +@@ -5092,8 +5315,7 @@ + /* This could probably go away because + we now decompose CONST_INTs according to expand_mov_immediate. */ + if ((GET_CODE (x) == CONST_VECTOR +- && aarch64_simd_valid_immediate (x, mode, false, +- NULL, NULL, NULL, NULL, NULL) != -1) ++ && aarch64_simd_valid_immediate (x, mode, false, NULL)) + || CONST_INT_P (x) || aarch64_valid_floating_const (mode, x)) + return !targetm.cannot_force_const_mem (mode, x); -- switch (mode) -+ if (rel) - { -- case QImode: gen = gen_arm_store_exclusiveqi; break; -- case HImode: gen = gen_arm_store_exclusivehi; break; -- case SImode: gen = gen_arm_store_exclusivesi; break; -- case DImode: gen = gen_arm_store_exclusivedi; break; -- default: -- gcc_unreachable (); -+ switch (mode) -+ { -+ case QImode: gen = gen_arm_store_release_exclusiveqi; break; -+ case HImode: gen = gen_arm_store_release_exclusivehi; break; -+ case SImode: gen = gen_arm_store_release_exclusivesi; break; -+ case DImode: gen = gen_arm_store_release_exclusivedi; break; -+ default: -+ gcc_unreachable (); -+ } - } -+ else +@@ -5924,32 +6146,57 @@ + return false; + } + +-/* Return quad mode as the preferred SIMD mode. */ ++/* Return appropriate SIMD container ++ for MODE within a vector of WIDTH bits. */ + static enum machine_mode +-aarch64_preferred_simd_mode (enum machine_mode mode) ++aarch64_simd_container_mode (enum machine_mode mode, unsigned width) + { ++ gcc_assert (width == 64 || width == 128); + if (TARGET_SIMD) +- switch (mode) +- { +- case DFmode: +- return V2DFmode; +- case SFmode: +- return V4SFmode; +- case SImode: +- return V4SImode; +- case HImode: +- return V8HImode; +- case QImode: +- return V16QImode; +- case DImode: +- return V2DImode; +- break; +- +- default:; +- } + { -+ switch (mode) -+ { -+ case QImode: gen = gen_arm_store_exclusiveqi; break; -+ case HImode: gen = gen_arm_store_exclusivehi; break; -+ case SImode: gen = gen_arm_store_exclusivesi; break; -+ case DImode: gen = gen_arm_store_exclusivedi; break; -+ default: -+ gcc_unreachable (); -+ } ++ if (width == 128) ++ switch (mode) ++ { ++ case DFmode: ++ return V2DFmode; ++ case SFmode: ++ return V4SFmode; ++ case SImode: ++ return V4SImode; ++ case HImode: ++ return V8HImode; ++ case QImode: ++ return V16QImode; ++ case DImode: ++ return V2DImode; ++ default: ++ break; ++ } ++ else ++ switch (mode) ++ { ++ case SFmode: ++ return V2SFmode; ++ case SImode: ++ return V2SImode; ++ case HImode: ++ return V4HImode; ++ case QImode: ++ return V8QImode; ++ default: ++ break; ++ } + } - - emit_insn (gen (bval, rval, mem)); + return word_mode; } -@@ -26325,6 +27561,15 @@ - mod_f = operands[7]; - mode = GET_MODE (mem); -+ /* Normally the succ memory model must be stronger than fail, but in the -+ unlikely event of fail being ACQUIRE and succ being RELEASE we need to -+ promote succ to ACQ_REL so that we don't lose the acquire semantics. */ -+ -+ if (TARGET_HAVE_LDACQ -+ && INTVAL (mod_f) == MEMMODEL_ACQUIRE -+ && INTVAL (mod_s) == MEMMODEL_RELEASE) -+ mod_s = GEN_INT (MEMMODEL_ACQ_REL); ++/* Return 128-bit container as the preferred SIMD mode for MODE. */ ++static enum machine_mode ++aarch64_preferred_simd_mode (enum machine_mode mode) ++{ ++ return aarch64_simd_container_mode (mode, 128); ++} + - switch (mode) - { - case QImode: -@@ -26399,8 +27644,20 @@ - scratch = operands[7]; - mode = GET_MODE (mem); + /* Return the bitmask of possible vector sizes for the vectorizer + to iterate over. */ + static unsigned int +@@ -6037,7 +6284,7 @@ + } -- arm_pre_atomic_barrier (mod_s); -+ bool use_acquire = TARGET_HAVE_LDACQ -+ && !(mod_s == MEMMODEL_RELAXED -+ || mod_s == MEMMODEL_CONSUME -+ || mod_s == MEMMODEL_RELEASE); + /* Return the equivalent letter for size. */ +-static unsigned char ++static char + sizetochar (int size) + { + switch (size) +@@ -6084,15 +6331,10 @@ + return aarch64_float_const_representable_p (x0); + } -+ bool use_release = TARGET_HAVE_LDACQ -+ && !(mod_s == MEMMODEL_RELAXED -+ || mod_s == MEMMODEL_CONSUME -+ || mod_s == MEMMODEL_ACQUIRE); -+ -+ /* Checks whether a barrier is needed and emits one accordingly. */ -+ if (!(use_acquire || use_release)) -+ arm_pre_atomic_barrier (mod_s); -+ - label1 = NULL_RTX; - if (!is_weak) +-/* TODO: This function returns values similar to those +- returned by neon_valid_immediate in gcc/config/arm/arm.c +- but the API here is different enough that these magic numbers +- are not used. It should be sufficient to return true or false. */ +-static int +-aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, int inverse, +- rtx *modconst, int *elementwidth, +- unsigned char *elementchar, +- int *mvn, int *shift) ++/* Return true for valid and false for invalid. */ ++bool ++aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse, ++ struct simd_immediate_info *info) + { + #define CHECK(STRIDE, ELSIZE, CLASS, TEST, SHIFT, NEG) \ + matches = 1; \ +@@ -6103,7 +6345,6 @@ + { \ + immtype = (CLASS); \ + elsize = (ELSIZE); \ +- elchar = sizetochar (elsize); \ + eshift = (SHIFT); \ + emvn = (NEG); \ + break; \ +@@ -6112,36 +6353,25 @@ + unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op); + unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode)); + unsigned char bytes[16]; +- unsigned char elchar = 0; + int immtype = -1, matches; + unsigned int invmask = inverse ? 0xff : 0; + int eshift, emvn; + + if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) { -@@ -26409,7 +27666,7 @@ +- bool simd_imm_zero = aarch64_simd_imm_zero_p (op, mode); +- int elem_width = GET_MODE_BITSIZE (GET_MODE (CONST_VECTOR_ELT (op, 0))); ++ if (! (aarch64_simd_imm_zero_p (op, mode) ++ || aarch64_vect_float_const_representable_p (op))) ++ return false; + +- if (!(simd_imm_zero +- || aarch64_vect_float_const_representable_p (op))) +- return -1; ++ if (info) ++ { ++ info->value = CONST_VECTOR_ELT (op, 0); ++ info->element_width = GET_MODE_BITSIZE (GET_MODE (info->value)); ++ info->mvn = false; ++ info->shift = 0; ++ } + +- if (modconst) +- *modconst = CONST_VECTOR_ELT (op, 0); +- +- if (elementwidth) +- *elementwidth = elem_width; +- +- if (elementchar) +- *elementchar = sizetochar (elem_width); +- +- if (shift) +- *shift = 0; +- +- if (simd_imm_zero) +- return 19; +- else +- return 18; ++ return true; } - label2 = gen_label_rtx (); -- arm_emit_load_exclusive (mode, rval, mem); -+ arm_emit_load_exclusive (mode, rval, mem, use_acquire); + /* Splat vector constant out into a byte vector. */ +@@ -6215,16 +6445,16 @@ + CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1], 8, 1); + + CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1] +- && bytes[i + 2] == 0 && bytes[i + 3] == 0, 0, 0); ++ && bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0); - cond = arm_gen_compare_reg (NE, rval, oldval, scratch); - x = gen_rtx_NE (VOIDmode, cond, const0_rtx); -@@ -26417,7 +27674,7 @@ - gen_rtx_LABEL_REF (Pmode, label2), pc_rtx); - emit_unlikely_jump (gen_rtx_SET (VOIDmode, pc_rtx, x)); + CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1] +- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 0, 1); ++ && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1); -- arm_emit_store_exclusive (mode, scratch, mem, newval); -+ arm_emit_store_exclusive (mode, scratch, mem, newval, use_release); + CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff +- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 0, 0); ++ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0); - /* Weak or strong, we want EQ to be true for success, so that we - match the flags that we got from the compare above. */ -@@ -26436,7 +27693,9 @@ - if (mod_f != MEMMODEL_RELAXED) - emit_label (label2); + CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0 +- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 0, 1); ++ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1); -- arm_post_atomic_barrier (mod_s); -+ /* Checks whether a barrier is needed and emits one accordingly. */ -+ if (!(use_acquire || use_release)) -+ arm_post_atomic_barrier (mod_s); + CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0); - if (mod_f == MEMMODEL_RELAXED) - emit_label (label2); -@@ -26451,8 +27710,20 @@ - enum machine_mode wmode = (mode == DImode ? DImode : SImode); - rtx label, x; +@@ -6233,31 +6463,20 @@ + } + while (0); -- arm_pre_atomic_barrier (model); -+ bool use_acquire = TARGET_HAVE_LDACQ -+ && !(model == MEMMODEL_RELAXED -+ || model == MEMMODEL_CONSUME -+ || model == MEMMODEL_RELEASE); +- /* TODO: Currently the assembler cannot handle types 12 to 15. +- And there is no way to specify cmode through the compiler. +- Disable them till there is support in the assembler. */ +- if (immtype == -1 +- || (immtype >= 12 && immtype <= 15) +- || immtype == 18) +- return -1; ++ if (immtype == -1) ++ return false; -+ bool use_release = TARGET_HAVE_LDACQ -+ && !(model == MEMMODEL_RELAXED -+ || model == MEMMODEL_CONSUME -+ || model == MEMMODEL_ACQUIRE); -+ -+ /* Checks whether a barrier is needed and emits one accordingly. */ -+ if (!(use_acquire || use_release)) -+ arm_pre_atomic_barrier (model); -+ - label = gen_label_rtx (); - emit_label (label); ++ if (info) ++ { ++ info->element_width = elsize; ++ info->mvn = emvn != 0; ++ info->shift = eshift; -@@ -26464,7 +27735,7 @@ - old_out = new_out; - value = simplify_gen_subreg (wmode, value, mode, 0); +- if (elementwidth) +- *elementwidth = elsize; ++ unsigned HOST_WIDE_INT imm = 0; -- arm_emit_load_exclusive (mode, old_out, mem); -+ arm_emit_load_exclusive (mode, old_out, mem, use_acquire); +- if (elementchar) +- *elementchar = elchar; ++ if (immtype >= 12 && immtype <= 15) ++ info->msl = true; - switch (code) - { -@@ -26512,12 +27783,15 @@ - break; - } +- if (mvn) +- *mvn = emvn; +- +- if (shift) +- *shift = eshift; +- +- if (modconst) +- { +- unsigned HOST_WIDE_INT imm = 0; +- + /* Un-invert bytes of recognized vector, if necessary. */ + if (invmask != 0) + for (i = 0; i < idx; i++) +@@ -6272,68 +6491,27 @@ + imm |= (unsigned HOST_WIDE_INT) (bytes[i] ? 0xff : 0) + << (i * BITS_PER_UNIT); -- arm_emit_store_exclusive (mode, cond, mem, gen_lowpart (mode, new_out)); -+ arm_emit_store_exclusive (mode, cond, mem, gen_lowpart (mode, new_out), -+ use_release); +- *modconst = GEN_INT (imm); +- } ++ ++ info->value = GEN_INT (imm); ++ } + else +- { +- unsigned HOST_WIDE_INT imm = 0; ++ { ++ for (i = 0; i < elsize / BITS_PER_UNIT; i++) ++ imm |= (unsigned HOST_WIDE_INT) bytes[i] << (i * BITS_PER_UNIT); - x = gen_rtx_NE (VOIDmode, cond, const0_rtx); - emit_unlikely_jump (gen_cbranchsi4 (x, cond, const0_rtx, label)); +- for (i = 0; i < elsize / BITS_PER_UNIT; i++) +- imm |= (unsigned HOST_WIDE_INT) bytes[i] << (i * BITS_PER_UNIT); +- + /* Construct 'abcdefgh' because the assembler cannot handle +- generic constants. */ +- gcc_assert (shift != NULL && mvn != NULL); +- if (*mvn) ++ generic constants. */ ++ if (info->mvn) + imm = ~imm; +- imm = (imm >> *shift) & 0xff; +- *modconst = GEN_INT (imm); +- } ++ imm = (imm >> info->shift) & 0xff; ++ info->value = GEN_INT (imm); ++ } + } -- arm_post_atomic_barrier (model); -+ /* Checks whether a barrier is needed and emits one accordingly. */ -+ if (!(use_acquire || use_release)) -+ arm_post_atomic_barrier (model); +- return immtype; ++ return true; + #undef CHECK } - - #define MAX_VECT_LEN 16 -@@ -27457,4 +28731,12 @@ +-/* Return TRUE if rtx X is legal for use as either a AdvSIMD MOVI instruction +- (or, implicitly, MVNI) immediate. Write back width per element +- to *ELEMENTWIDTH, and a modified constant (whatever should be output +- for a MOVI instruction) in *MODCONST. */ +-int +-aarch64_simd_immediate_valid_for_move (rtx op, enum machine_mode mode, +- rtx *modconst, int *elementwidth, +- unsigned char *elementchar, +- int *mvn, int *shift) +-{ +- rtx tmpconst; +- int tmpwidth; +- unsigned char tmpwidthc; +- int tmpmvn = 0, tmpshift = 0; +- int retval = aarch64_simd_valid_immediate (op, mode, 0, &tmpconst, +- &tmpwidth, &tmpwidthc, +- &tmpmvn, &tmpshift); +- +- if (retval == -1) +- return 0; +- +- if (modconst) +- *modconst = tmpconst; +- +- if (elementwidth) +- *elementwidth = tmpwidth; +- +- if (elementchar) +- *elementchar = tmpwidthc; +- +- if (mvn) +- *mvn = tmpmvn; +- +- if (shift) +- *shift = tmpshift; +- +- return 1; +-} +- + static bool + aarch64_const_vec_all_same_int_p (rtx x, + HOST_WIDE_INT minval, +@@ -6395,6 +6573,25 @@ + return true; } -+/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ -+ -+static unsigned HOST_WIDE_INT -+arm_asan_shadow_offset (void) ++bool ++aarch64_mov_operand_p (rtx x, ++ enum aarch64_symbol_context context, ++ enum machine_mode mode) +{ -+ return (unsigned HOST_WIDE_INT) 1 << 29; -+} -+ - #include "gt-arm.h" ---- a/src/gcc/config/arm/t-aprofile -+++ b/src/gcc/config/arm/t-aprofile -@@ -0,0 +1,177 @@ -+# Copyright (C) 2012-2013 Free Software Foundation, Inc. -+# -+# This file is part of GCC. -+# -+# GCC is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 3, or (at your option) -+# any later version. -+# -+# GCC is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with GCC; see the file COPYING3. If not see -+# . -+ -+# This is a target makefile fragment that attempts to get -+# multilibs built for the range of CPU's, FPU's and ABI's that -+# are relevant for the A-profile architecture. It should -+# not be used in conjunction with another make file fragment and -+# assumes --with-arch, --with-cpu, --with-fpu, --with-float, --with-mode -+# have their default values during the configure step. We enforce -+# this during the top-level configury. -+ -+MULTILIB_OPTIONS = -+MULTILIB_DIRNAMES = -+MULTILIB_EXCEPTIONS = -+MULTILIB_MATCHES = -+MULTILIB_REUSE = -+ -+# We have the following hierachy: -+# ISA: A32 (.) or T32 (thumb) -+# Architecture: ARMv7-A (v7-a), ARMv7VE (v7ve), or ARMv8-A (v8-a). -+# FPU: VFPv3-D16 (fpv3), NEONv1 (simdv1), VFPv4-D16 (fpv4), -+# NEON-VFPV4 (simdvfpv4), NEON for ARMv8 (simdv8), or None (.). -+# Float-abi: Soft (.), softfp (softfp), or hard (hardfp). -+ -+# We use the option -mcpu=cortex-a7 because we do not yet have march=armv7ve -+# or march=armv7a+virt as a command line option for the compiler. -+MULTILIB_OPTIONS += mthumb -+MULTILIB_DIRNAMES += thumb -+ -+MULTILIB_OPTIONS += march=armv7-a/mcpu=cortex-a7/march=armv8-a -+MULTILIB_DIRNAMES += v7-a v7ve v8-a -+ -+MULTILIB_OPTIONS += mfpu=vfpv3-d16/mfpu=neon/mfpu=vfpv4-d16/mfpu=neon-vfpv4/mfpu=neon-fp-armv8 -+MULTILIB_DIRNAMES += fpv3 simdv1 fpv4 simdvfpv4 simdv8 -+ -+MULTILIB_OPTIONS += mfloat-abi=softfp/mfloat-abi=hard -+MULTILIB_DIRNAMES += softfp hard -+ -+# We don't build no-float libraries with an FPU. -+MULTILIB_EXCEPTIONS += *mfpu=vfpv3-d16 -+MULTILIB_EXCEPTIONS += *mfpu=neon -+MULTILIB_EXCEPTIONS += *mfpu=vfpv4-d16 -+MULTILIB_EXCEPTIONS += *mfpu=neon-vfpv4 -+MULTILIB_EXCEPTIONS += *mfpu=neon-fp-armv8 -+ -+# We don't build libraries requiring an FPU at the CPU/Arch/ISA level. -+MULTILIB_EXCEPTIONS += mfloat-abi=* -+MULTILIB_EXCEPTIONS += mfpu=* -+MULTILIB_EXCEPTIONS += mthumb/mfloat-abi=* -+MULTILIB_EXCEPTIONS += mthumb/mfpu=* -+MULTILIB_EXCEPTIONS += *march=armv7-a/mfloat-abi=* -+MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/mfloat-abi=* -+MULTILIB_EXCEPTIONS += *march=armv8-a/mfloat-abi=* -+ -+# Ensure the correct FPU variants apply to the correct base architectures. -+MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/*mfpu=vfpv3-d16* -+MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/*mfpu=neon/* -+MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=vfpv3-d16* -+MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=neon/* -+MULTILIB_EXCEPTIONS += *march=armv7-a/*mfpu=vfpv4-d16* -+MULTILIB_EXCEPTIONS += *march=armv7-a/*mfpu=neon-vfpv4* -+MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=vfpv4-d16* -+MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=neon-vfpv4* -+MULTILIB_EXCEPTIONS += *march=armv7-a/*mfpu=neon-fp-armv8* -+MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/*mfpu=neon-fp-armv8* -+ -+# CPU Matches -+MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a8 -+MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a9 -+MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a5 -+MULTILIB_MATCHES += mcpu?cortex-a7=mcpu?cortex-a15 -+MULTILIB_MATCHES += march?armv8-a=mcpu?cortex-a53 -+ -+# FPU matches -+MULTILIB_MATCHES += mfpu?vfpv3-d16=mfpu?vfpv3 -+MULTILIB_MATCHES += mfpu?vfpv3-d16=mfpu?vfpv3-fp16 -+MULTILIB_MATCHES += mfpu?vfpv3-d16=mfpu?vfpv3-fp16-d16 -+MULTILIB_MATCHES += mfpu?vfpv4-d16=mfpu?vfpv4 -+MULTILIB_MATCHES += mfpu?neon-fp-armv8=mfpu?crypto-neon-fp-armv8 -+ ++ if (GET_CODE (x) == HIGH ++ && aarch64_valid_symref (XEXP (x, 0), GET_MODE (XEXP (x, 0)))) ++ return true; + -+# Map all requests for vfpv3 with a later CPU to vfpv3-d16 v7-a. -+# So if new CPUs are added above at the newer architecture levels, -+# do something to map them below here. -+# We take the approach of mapping down to v7-a regardless of what -+# the fp option is if the integer architecture brings things down. -+# This applies to any similar combination at the v7ve and v8-a arch -+# levels. ++ if (CONST_INT_P (x) && aarch64_move_imm (INTVAL (x), mode)) ++ return true; + -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.softfp -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.softfp -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.softfp -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7-a/mfpu.fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7-a/mfpu.fp-armv8/mfloat-abi.softfp -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7-a/mfpu.vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7-a/mfpu.vfpv4/mfloat-abi.softfp ++ if (GET_CODE (x) == SYMBOL_REF && mode == DImode && CONSTANT_ADDRESS_P (x)) ++ return true; + ++ return aarch64_classify_symbolic_expression (x, context) ++ == SYMBOL_TINY_ABSOLUTE; ++} + -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=mcpu.cortex-a7/mfpu.neon/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.neon/mfloat-abi.softfp -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv8-a/mfpu.neon/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv8-a/mfpu.neon/mfloat-abi.softfp -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.softfp -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.softfp + /* Return a const_int vector of VAL. */ + rtx + aarch64_simd_gen_const_vector_dup (enum machine_mode mode, int val) +@@ -6409,6 +6606,19 @@ + return gen_rtx_CONST_VECTOR (mode, v); + } + ++/* Check OP is a legal scalar immediate for the MOVI instruction. */ + ++bool ++aarch64_simd_scalar_immediate_valid_for_move (rtx op, enum machine_mode mode) ++{ ++ enum machine_mode vmode; + -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.softfp -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv4/mfloat-abi.softfp -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.hard -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.softfp ++ gcc_assert (!VECTOR_MODE_P (mode)); ++ vmode = aarch64_preferred_simd_mode (mode); ++ rtx op_v = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (op)); ++ return aarch64_simd_valid_immediate (op_v, vmode, false, NULL); ++} + + /* Construct and return a PARALLEL RTX vector. */ + rtx + aarch64_simd_vect_par_cnst_half (enum machine_mode mode, bool high) +@@ -6634,8 +6844,7 @@ + gcc_unreachable (); + + if (const_vec != NULL_RTX +- && aarch64_simd_immediate_valid_for_move (const_vec, mode, NULL, NULL, +- NULL, NULL, NULL)) ++ && aarch64_simd_valid_immediate (const_vec, mode, false, NULL)) + /* Load using MOVI/MVNI. */ + return const_vec; + else if ((const_dup = aarch64_simd_dup_constant (vals)) != NULL_RTX) +@@ -7193,49 +7402,80 @@ + } + + char* +-aarch64_output_simd_mov_immediate (rtx *const_vector, ++aarch64_output_simd_mov_immediate (rtx const_vector, + enum machine_mode mode, + unsigned width) + { +- int is_valid; +- unsigned char widthc; +- int lane_width_bits; ++ bool is_valid; + static char templ[40]; +- int shift = 0, mvn = 0; + const char *mnemonic; ++ const char *shift_op; + unsigned int lane_count = 0; ++ char element_char; + +- is_valid = +- aarch64_simd_immediate_valid_for_move (*const_vector, mode, +- const_vector, &lane_width_bits, +- &widthc, &mvn, &shift); ++ struct simd_immediate_info info = { NULL_RTX, 0, 0, false, false }; + -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.softfp -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.softfp ++ /* This will return true to show const_vector is legal for use as either ++ a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will ++ also update INFO to show how the immediate should be generated. */ ++ is_valid = aarch64_simd_valid_immediate (const_vector, mode, false, &info); + gcc_assert (is_valid); + ++ element_char = sizetochar (info.element_width); ++ lane_count = width / info.element_width; + + mode = GET_MODE_INNER (mode); + if (mode == SFmode || mode == DFmode) + { +- bool zero_p = +- aarch64_float_const_zero_rtx_p (*const_vector); +- gcc_assert (shift == 0); +- mnemonic = zero_p ? "movi" : "fmov"; ++ gcc_assert (info.shift == 0 && ! info.mvn); ++ if (aarch64_float_const_zero_rtx_p (info.value)) ++ info.value = GEN_INT (0); ++ else ++ { ++#define buf_size 20 ++ REAL_VALUE_TYPE r; ++ REAL_VALUE_FROM_CONST_DOUBLE (r, info.value); ++ char float_buf[buf_size] = {'\0'}; ++ real_to_decimal_for_mode (float_buf, &r, buf_size, buf_size, 1, mode); ++#undef buf_size + ++ if (lane_count == 1) ++ snprintf (templ, sizeof (templ), "fmov\t%%d0, %s", float_buf); ++ else ++ snprintf (templ, sizeof (templ), "fmov\t%%0.%d%c, %s", ++ lane_count, element_char, float_buf); ++ return templ; ++ } + } +- else +- mnemonic = mvn ? "mvni" : "movi"; + +- gcc_assert (lane_width_bits != 0); +- lane_count = width / lane_width_bits; ++ mnemonic = info.mvn ? "mvni" : "movi"; ++ shift_op = info.msl ? "msl" : "lsl"; + + if (lane_count == 1) +- snprintf (templ, sizeof (templ), "%s\t%%d0, %%1", mnemonic); +- else if (shift) +- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, %%1, lsl %d", +- mnemonic, lane_count, widthc, shift); ++ snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX, ++ mnemonic, UINTVAL (info.value)); ++ else if (info.shift) ++ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX ++ ", %s %d", mnemonic, lane_count, element_char, ++ UINTVAL (info.value), shift_op, info.shift); + else +- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, %%1", +- mnemonic, lane_count, widthc); ++ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX, ++ mnemonic, lane_count, element_char, UINTVAL (info.value)); + return templ; + } + ++char* ++aarch64_output_scalar_simd_mov_immediate (rtx immediate, ++ enum machine_mode mode) ++{ ++ enum machine_mode vmode; + -+# And again for mthumb. ++ gcc_assert (!VECTOR_MODE_P (mode)); ++ vmode = aarch64_simd_container_mode (mode, 64); ++ rtx v_op = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (immediate)); ++ return aarch64_output_simd_mov_immediate (v_op, vmode, 64); ++} + -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.fp-armv8/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.vfpv4/mfloat-abi.softfp + /* Split operands into moves from op[1] + op[2] into op[0]. */ + + void +@@ -7860,6 +8100,9 @@ + #undef TARGET_EXPAND_BUILTIN_VA_START + #define TARGET_EXPAND_BUILTIN_VA_START aarch64_expand_builtin_va_start + ++#undef TARGET_FOLD_BUILTIN ++#define TARGET_FOLD_BUILTIN aarch64_fold_builtin + + #undef TARGET_FUNCTION_ARG + #define TARGET_FUNCTION_ARG aarch64_function_arg + +@@ -7881,6 +8124,9 @@ + #undef TARGET_FRAME_POINTER_REQUIRED + #define TARGET_FRAME_POINTER_REQUIRED aarch64_frame_pointer_required + ++#undef TARGET_GIMPLE_FOLD_BUILTIN ++#define TARGET_GIMPLE_FOLD_BUILTIN aarch64_gimple_fold_builtin + -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.neon/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.neon/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.neon/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.neon/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.softfp + #undef TARGET_GIMPLIFY_VA_ARG_EXPR + #define TARGET_GIMPLIFY_VA_ARG_EXPR aarch64_gimplify_va_arg_expr + +@@ -7960,6 +8206,13 @@ + #undef TARGET_ARRAY_MODE_SUPPORTED_P + #define TARGET_ARRAY_MODE_SUPPORTED_P aarch64_array_mode_supported_p + ++#undef TARGET_VECTORIZE_ADD_STMT_COST ++#define TARGET_VECTORIZE_ADD_STMT_COST aarch64_add_stmt_cost + ++#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST ++#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \ ++ aarch64_builtin_vectorization_cost + -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv4/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.softfp + #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE + #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE aarch64_preferred_simd_mode + +--- a/src/gcc/config/aarch64/iterators.md ++++ b/src/gcc/config/aarch64/iterators.md +@@ -83,6 +83,12 @@ + ;; Vector Float modes. + (define_mode_iterator VDQF [V2SF V4SF V2DF]) + ++;; Modes suitable to use as the return type of a vcond expression. ++(define_mode_iterator VDQF_COND [V2SF V2SI V4SF V4SI V2DF V2DI]) + ++;; All Float modes. ++(define_mode_iterator VALLF [V2SF V4SF V2DF SF DF]) + -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.softfp -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.hard -+MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.softfp ---- a/src/gcc/config/arm/arm.h -+++ b/src/gcc/config/arm/arm.h -@@ -49,8 +49,14 @@ - builtin_define ("__ARM_FEATURE_QBIT"); \ - if (TARGET_ARM_SAT) \ - builtin_define ("__ARM_FEATURE_SAT"); \ -+ if (TARGET_CRYPTO) \ -+ builtin_define ("__ARM_FEATURE_CRYPTO"); \ - if (unaligned_access) \ - builtin_define ("__ARM_FEATURE_UNALIGNED"); \ -+ if (TARGET_CRC32) \ -+ builtin_define ("__ARM_FEATURE_CRC32"); \ -+ if (TARGET_32BIT) \ -+ builtin_define ("__ARM_32BIT_STATE"); \ - if (TARGET_ARM_FEATURE_LDREX) \ - builtin_define_with_int_value ( \ - "__ARM_FEATURE_LDREX", TARGET_ARM_FEATURE_LDREX); \ -@@ -183,6 +189,11 @@ + ;; Vector Float modes with 2 elements. + (define_mode_iterator V2F [V2SF V2DF]) - #define ARM_INVERSE_CONDITION_CODE(X) ((arm_cc) (((int)X) ^ 1)) +@@ -122,9 +128,15 @@ + ;; Vector modes except double int. + (define_mode_iterator VDQIF [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF V2DF]) -+/* The maximaum number of instructions that is beneficial to -+ conditionally execute. */ -+#undef MAX_CONDITIONAL_EXECUTE -+#define MAX_CONDITIONAL_EXECUTE arm_max_conditional_execute () ++;; Vector modes for Q and H types. ++(define_mode_iterator VDQQH [V8QI V16QI V4HI V8HI]) + - extern int arm_target_label; - extern int arm_ccfsm_state; - extern GTY(()) rtx arm_target_insn; -@@ -269,6 +280,8 @@ - #define TARGET_LDRD (arm_arch5e && ARM_DOUBLEWORD_ALIGN \ - && !TARGET_THUMB1) - -+#define TARGET_CRC32 (arm_arch_crc) -+ - /* The following two macros concern the ability to execute coprocessor - instructions for VFPv3 or NEON. TARGET_VFP3/TARGET_VFPD32 are currently - only ever tested when we know we are generating for VFP hardware; we need -@@ -350,10 +363,16 @@ - #define TARGET_HAVE_LDREXD (((arm_arch6k && TARGET_ARM) || arm_arch7) \ - && arm_arch_notm) + ;; Vector modes for H and S types. + (define_mode_iterator VDQHS [V4HI V8HI V2SI V4SI]) -+/* Nonzero if this chip supports load-acquire and store-release. */ -+#define TARGET_HAVE_LDACQ (TARGET_ARM_ARCH >= 8) ++;; Vector modes for Q, H and S types. ++(define_mode_iterator VDQQHS [V8QI V16QI V4HI V8HI V2SI V4SI]) + - /* Nonzero if integer division instructions supported. */ - #define TARGET_IDIV ((TARGET_ARM && arm_arch_arm_hwdiv) \ - || (TARGET_THUMB2 && arm_arch_thumb_hwdiv)) + ;; Vector and scalar integer modes for H and S + (define_mode_iterator VSDQ_HSI [V4HI V8HI V2SI V4SI HI SI]) -+/* Should NEON be used for 64-bits bitops. */ -+#define TARGET_PREFER_NEON_64BITS (prefer_neon_for_64bits) -+ - /* True iff the full BPABI is being used. If TARGET_BPABI is true, - then TARGET_AAPCS_BASED must be true -- but the converse does not - hold. TARGET_BPABI implies the use of the BPABI runtime library, -@@ -539,6 +558,13 @@ - /* Nonzero if chip supports integer division instruction in Thumb mode. */ - extern int arm_arch_thumb_hwdiv; +@@ -160,10 +172,15 @@ + [ + UNSPEC_ASHIFT_SIGNED ; Used in aarch-simd.md. + UNSPEC_ASHIFT_UNSIGNED ; Used in aarch64-simd.md. ++ UNSPEC_FMAX ; Used in aarch64-simd.md. ++ UNSPEC_FMAXNMV ; Used in aarch64-simd.md. + UNSPEC_FMAXV ; Used in aarch64-simd.md. ++ UNSPEC_FMIN ; Used in aarch64-simd.md. ++ UNSPEC_FMINNMV ; Used in aarch64-simd.md. + UNSPEC_FMINV ; Used in aarch64-simd.md. + UNSPEC_FADDV ; Used in aarch64-simd.md. +- UNSPEC_ADDV ; Used in aarch64-simd.md. ++ UNSPEC_SADDV ; Used in aarch64-simd.md. ++ UNSPEC_UADDV ; Used in aarch64-simd.md. + UNSPEC_SMAXV ; Used in aarch64-simd.md. + UNSPEC_SMINV ; Used in aarch64-simd.md. + UNSPEC_UMAXV ; Used in aarch64-simd.md. +@@ -213,13 +230,6 @@ + UNSPEC_URSHL ; Used in aarch64-simd.md. + UNSPEC_SQRSHL ; Used in aarch64-simd.md. + UNSPEC_UQRSHL ; Used in aarch64-simd.md. +- UNSPEC_CMEQ ; Used in aarch64-simd.md. +- UNSPEC_CMLE ; Used in aarch64-simd.md. +- UNSPEC_CMLT ; Used in aarch64-simd.md. +- UNSPEC_CMGE ; Used in aarch64-simd.md. +- UNSPEC_CMGT ; Used in aarch64-simd.md. +- UNSPEC_CMHS ; Used in aarch64-simd.md. +- UNSPEC_CMHI ; Used in aarch64-simd.md. + UNSPEC_SSLI ; Used in aarch64-simd.md. + UNSPEC_USLI ; Used in aarch64-simd.md. + UNSPEC_SSRI ; Used in aarch64-simd.md. +@@ -227,10 +237,6 @@ + UNSPEC_SSHLL ; Used in aarch64-simd.md. + UNSPEC_USHLL ; Used in aarch64-simd.md. + UNSPEC_ADDP ; Used in aarch64-simd.md. +- UNSPEC_CMTST ; Used in aarch64-simd.md. +- UNSPEC_FMAX ; Used in aarch64-simd.md. +- UNSPEC_FMIN ; Used in aarch64-simd.md. +- UNSPEC_BSL ; Used in aarch64-simd.md. + UNSPEC_TBL ; Used in vector permute patterns. + UNSPEC_CONCAT ; Used in vector permute patterns. + UNSPEC_ZIP1 ; Used in vector permute patterns. +@@ -249,8 +255,12 @@ + ;; 32-bit version and "%x0" in the 64-bit version. + (define_mode_attr w [(QI "w") (HI "w") (SI "w") (DI "x") (SF "s") (DF "d")]) -+/* Nonzero if we should use Neon to handle 64-bits operations rather -+ than core registers. */ -+extern int prefer_neon_for_64bits; -+ -+/* Nonzero if chip supports the ARMv8 CRC instructions. */ -+extern int arm_arch_crc; ++;; For constraints used in scalar immediate vector moves ++(define_mode_attr hq [(HI "h") (QI "q")]) + - #ifndef TARGET_DEFAULT - #define TARGET_DEFAULT (MASK_APCS_FRAME) - #endif -@@ -630,6 +656,8 @@ + ;; For scalar usage of vector/FP registers + (define_mode_attr v [(QI "b") (HI "h") (SI "s") (DI "d") ++ (SF "s") (DF "d") + (V8QI "") (V16QI "") + (V4HI "") (V8HI "") + (V2SI "") (V4SI "") +@@ -305,7 +315,8 @@ + (V4SF ".4s") (V2DF ".2d") + (DI "") (SI "") + (HI "") (QI "") +- (TI "")]) ++ (TI "") (SF "") ++ (DF "")]) + + ;; Register suffix narrowed modes for VQN. + (define_mode_attr Vmntype [(V8HI ".8b") (V4SI ".4h") +@@ -380,7 +391,8 @@ + ;; Double modes of vector modes (lower case). + (define_mode_attr Vdbl [(V8QI "v16qi") (V4HI "v8hi") + (V2SI "v4si") (V2SF "v4sf") +- (SI "v2si") (DI "v2di")]) ++ (SI "v2si") (DI "v2di") ++ (DF "v2df")]) - #define BIGGEST_ALIGNMENT (ARM_DOUBLEWORD_ALIGN ? DOUBLEWORD_ALIGNMENT : 32) + ;; Narrowed modes for VDN. + (define_mode_attr VNARROWD [(V4HI "V8QI") (V2SI "V4HI") +@@ -435,6 +447,15 @@ + (V2SF "s") (V4SF "s") + (V2DF "d")]) -+#define MALLOC_ABI_ALIGNMENT BIGGEST_ALIGNMENT ++;; Corresponding core element mode for each vector mode. This is a ++;; variation on mapping FP modes to GP regs. ++(define_mode_attr vwcore [(V8QI "w") (V16QI "w") ++ (V4HI "w") (V8HI "w") ++ (V2SI "w") (V4SI "w") ++ (DI "x") (V2DI "x") ++ (V2SF "w") (V4SF "w") ++ (V2DF "x")]) + - /* XXX Blah -- this macro is used directly by libobjc. Since it - supports no vector modes, cut out the complexity and fall back - on BIGGEST_FIELD_ALIGNMENT. */ -@@ -1040,7 +1068,7 @@ - /* Modes valid for Neon D registers. */ - #define VALID_NEON_DREG_MODE(MODE) \ - ((MODE) == V2SImode || (MODE) == V4HImode || (MODE) == V8QImode \ -- || (MODE) == V2SFmode || (MODE) == DImode) -+ || (MODE) == V4HFmode || (MODE) == V2SFmode || (MODE) == DImode) + ;; Double vector types for ALLX. + (define_mode_attr Vallxd [(QI "8b") (HI "4h") (SI "2s")]) - /* Modes valid for Neon Q registers. */ - #define VALID_NEON_QREG_MODE(MODE) \ -@@ -1130,6 +1158,7 @@ - STACK_REG, - BASE_REGS, - HI_REGS, -+ CALLER_SAVE_REGS, - GENERAL_REGS, - CORE_REGS, - VFP_D0_D7_REGS, -@@ -1156,6 +1185,7 @@ - "STACK_REG", \ - "BASE_REGS", \ - "HI_REGS", \ -+ "CALLER_SAVE_REGS", \ - "GENERAL_REGS", \ - "CORE_REGS", \ - "VFP_D0_D7_REGS", \ -@@ -1181,6 +1211,7 @@ - { 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ - { 0x000020FF, 0x00000000, 0x00000000, 0x00000000 }, /* BASE_REGS */ \ - { 0x00005F00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \ -+ { 0x0000100F, 0x00000000, 0x00000000, 0x00000000 }, /* CALLER_SAVE_REGS */ \ - { 0x00005FFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \ - { 0x00007FFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \ - { 0xFFFF0000, 0x00000000, 0x00000000, 0x00000000 }, /* VFP_D0_D7_REGS */ \ -@@ -1643,7 +1674,7 @@ - frame. */ - #define EXIT_IGNORE_STACK 1 +@@ -444,7 +465,8 @@ + (V2SI "V2SI") (V4SI "V4SI") + (DI "DI") (V2DI "V2DI") + (V2SF "V2SI") (V4SF "V4SI") +- (V2DF "V2DI")]) ++ (V2DF "V2DI") (DF "DI") ++ (SF "SI")]) + + ;; Lower case mode of results of comparison operations. + (define_mode_attr v_cmp_result [(V8QI "v8qi") (V16QI "v16qi") +@@ -452,7 +474,8 @@ + (V2SI "v2si") (V4SI "v4si") + (DI "di") (V2DI "v2di") + (V2SF "v2si") (V4SF "v4si") +- (V2DF "v2di")]) ++ (V2DF "v2di") (DF "di") ++ (SF "si")]) + + ;; Vm for lane instructions is restricted to FP_LO_REGS. + (define_mode_attr vwx [(V4HI "x") (V8HI "x") (HI "x") +@@ -528,9 +551,14 @@ + ;; Iterator for integer conversions + (define_code_iterator FIXUORS [fix unsigned_fix]) --#define EPILOGUE_USES(REGNO) ((REGNO) == LR_REGNUM) -+#define EPILOGUE_USES(REGNO) (epilogue_completed && (REGNO) == LR_REGNUM) ++;; Iterator for float conversions ++(define_code_iterator FLOATUORS [float unsigned_float]) ++ + ;; Code iterator for variants of vector max and min. + (define_code_iterator MAXMIN [smax smin umax umin]) - /* Determine if the epilogue should be output as RTL. - You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ ---- a/src/gcc/config/arm/cortex-a8.md -+++ b/src/gcc/config/arm/cortex-a8.md -@@ -85,22 +85,19 @@ - ;; (source read in E2 and destination available at the end of that cycle). - (define_insn_reservation "cortex_a8_alu" 2 - (and (eq_attr "tune" "cortexa8") -- (ior (and (and (eq_attr "type" "alu_reg,simple_alu_imm") -- (eq_attr "neon_type" "none")) -- (not (eq_attr "insn" "mov,mvn"))) -- (eq_attr "insn" "clz"))) -+ (ior (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") -+ (eq_attr "neon_type" "none")) -+ (eq_attr "type" "clz"))) - "cortex_a8_default") ++(define_code_iterator FMAXMIN [smax smin]) ++ + ;; Code iterator for variants of vector max and min. + (define_code_iterator ADDSUB [plus minus]) - (define_insn_reservation "cortex_a8_alu_shift" 2 - (and (eq_attr "tune" "cortexa8") -- (and (eq_attr "type" "simple_alu_shift,alu_shift") -- (not (eq_attr "insn" "mov,mvn")))) -+ (eq_attr "type" "extend,arlo_shift")) - "cortex_a8_default") +@@ -543,6 +571,15 @@ + ;; Code iterator for signed variants of vector saturating binary ops. + (define_code_iterator SBINQOPS [ss_plus ss_minus]) - (define_insn_reservation "cortex_a8_alu_shift_reg" 2 - (and (eq_attr "tune" "cortexa8") -- (and (eq_attr "type" "alu_shift_reg") -- (not (eq_attr "insn" "mov,mvn")))) -+ (eq_attr "type" "arlo_shift_reg")) - "cortex_a8_default") ++;; Comparison operators for CM. ++(define_code_iterator COMPARISONS [lt le eq ge gt]) ++ ++;; Unsigned comparison operators. ++(define_code_iterator UCOMPARISONS [ltu leu geu gtu]) ++ ++;; Unsigned comparison operators. ++(define_code_iterator FAC_COMPARISONS [lt le ge gt]) ++ + ;; ------------------------------------------------------------------- + ;; Code Attributes + ;; ------------------------------------------------------------------- +@@ -555,6 +592,10 @@ + (zero_extend "zero_extend") + (sign_extract "extv") + (zero_extract "extzv") ++ (fix "fix") ++ (unsigned_fix "fixuns") ++ (float "float") ++ (unsigned_float "floatuns") + (and "and") + (ior "ior") + (xor "xor") +@@ -571,12 +612,37 @@ + (eq "eq") + (ne "ne") + (lt "lt") +- (ge "ge")]) ++ (ge "ge") ++ (le "le") ++ (gt "gt") ++ (ltu "ltu") ++ (leu "leu") ++ (geu "geu") ++ (gtu "gtu")]) + ++;; For comparison operators we use the FCM* and CM* instructions. ++;; As there are no CMLE or CMLT instructions which act on 3 vector ++;; operands, we must use CMGE or CMGT and swap the order of the ++;; source operands. ++ ++(define_code_attr n_optab [(lt "gt") (le "ge") (eq "eq") (ge "ge") (gt "gt") ++ (ltu "hi") (leu "hs") (geu "hs") (gtu "hi")]) ++(define_code_attr cmp_1 [(lt "2") (le "2") (eq "1") (ge "1") (gt "1") ++ (ltu "2") (leu "2") (geu "1") (gtu "1")]) ++(define_code_attr cmp_2 [(lt "1") (le "1") (eq "2") (ge "2") (gt "2") ++ (ltu "1") (leu "1") (geu "2") (gtu "2")]) ++ ++(define_code_attr CMP [(lt "LT") (le "LE") (eq "EQ") (ge "GE") (gt "GT") ++ (ltu "LTU") (leu "LEU") (geu "GEU") (gtu "GTU")]) ++ ++(define_code_attr fix_trunc_optab [(fix "fix_trunc") ++ (unsigned_fix "fixuns_trunc")]) ++ + ;; Optab prefix for sign/zero-extending operations + (define_code_attr su_optab [(sign_extend "") (zero_extend "u") + (div "") (udiv "u") + (fix "") (unsigned_fix "u") ++ (float "s") (unsigned_float "u") + (ss_plus "s") (us_plus "u") + (ss_minus "s") (us_minus "u")]) - ;; Move instructions. -@@ -107,8 +104,8 @@ +@@ -601,7 +667,9 @@ + (define_code_attr su [(sign_extend "s") (zero_extend "u") + (sign_extract "s") (zero_extract "u") + (fix "s") (unsigned_fix "u") +- (div "s") (udiv "u")]) ++ (div "s") (udiv "u") ++ (smax "s") (umax "u") ++ (smin "s") (umin "u")]) - (define_insn_reservation "cortex_a8_mov" 1 - (and (eq_attr "tune" "cortexa8") -- (and (eq_attr "type" "alu_reg,simple_alu_imm,simple_alu_shift,alu_shift,alu_shift_reg") -- (eq_attr "insn" "mov,mvn"))) -+ (eq_attr "type" "mov_imm,mov_reg,mov_shift,mov_shift_reg,\ -+ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg")) - "cortex_a8_default") + ;; Emit cbz/cbnz depending on comparison type. + (define_code_attr cbz [(eq "cbz") (ne "cbnz") (lt "cbnz") (ge "cbz")]) +@@ -610,10 +678,10 @@ + (define_code_attr tbz [(eq "tbz") (ne "tbnz") (lt "tbnz") (ge "tbz")]) - ;; Exceptions to the default latencies for data processing instructions. -@@ -139,22 +136,22 @@ + ;; Max/min attributes. +-(define_code_attr maxmin [(smax "smax") +- (smin "smin") +- (umax "umax") +- (umin "umin")]) ++(define_code_attr maxmin [(smax "max") ++ (smin "min") ++ (umax "max") ++ (umin "min")]) - (define_insn_reservation "cortex_a8_mul" 6 - (and (eq_attr "tune" "cortexa8") -- (eq_attr "insn" "mul,smulxy,smmul")) -+ (eq_attr "type" "mul,smulxy,smmul")) - "cortex_a8_multiply_2") + ;; MLA/MLS attributes. + (define_code_attr as [(ss_plus "a") (ss_minus "s")]) +@@ -635,8 +703,11 @@ + (define_int_iterator MAXMINV [UNSPEC_UMAXV UNSPEC_UMINV + UNSPEC_SMAXV UNSPEC_SMINV]) - (define_insn_reservation "cortex_a8_mla" 6 - (and (eq_attr "tune" "cortexa8") -- (eq_attr "insn" "mla,smlaxy,smlawy,smmla,smlad,smlsd")) -+ (eq_attr "type" "mla,smlaxy,smlawy,smmla,smlad,smlsd")) - "cortex_a8_multiply_2") +-(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV]) ++(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV ++ UNSPEC_FMAXNMV UNSPEC_FMINNMV]) - (define_insn_reservation "cortex_a8_mull" 7 - (and (eq_attr "tune" "cortexa8") -- (eq_attr "insn" "smull,umull,smlal,umlal,umaal,smlalxy")) -+ (eq_attr "type" "smull,umull,smlal,umlal,umaal,smlalxy")) - "cortex_a8_multiply_3") ++(define_int_iterator SUADDV [UNSPEC_SADDV UNSPEC_UADDV]) ++ + (define_int_iterator HADDSUB [UNSPEC_SHADD UNSPEC_UHADD + UNSPEC_SRHADD UNSPEC_URHADD + UNSPEC_SHSUB UNSPEC_UHSUB +@@ -649,7 +720,7 @@ + (define_int_iterator ADDSUBHN2 [UNSPEC_ADDHN2 UNSPEC_RADDHN2 + UNSPEC_SUBHN2 UNSPEC_RSUBHN2]) - (define_insn_reservation "cortex_a8_smulwy" 5 - (and (eq_attr "tune" "cortexa8") -- (eq_attr "insn" "smulwy,smuad,smusd")) -+ (eq_attr "type" "smulwy,smuad,smusd")) - "cortex_a8_multiply") +-(define_int_iterator FMAXMIN [UNSPEC_FMAX UNSPEC_FMIN]) ++(define_int_iterator FMAXMIN_UNS [UNSPEC_FMAX UNSPEC_FMIN]) - ;; smlald and smlsld are multiply-accumulate instructions but do not -@@ -162,7 +159,7 @@ - ;; cannot go in cortex_a8_mla above. (See below for bypass details.) - (define_insn_reservation "cortex_a8_smlald" 6 - (and (eq_attr "tune" "cortexa8") -- (eq_attr "insn" "smlald,smlsld")) -+ (eq_attr "type" "smlald,smlsld")) - "cortex_a8_multiply_2") + (define_int_iterator VQDMULH [UNSPEC_SQDMULH UNSPEC_SQRDMULH]) - ;; A multiply with a single-register result or an MLA, followed by an ---- a/src/gcc/config/arm/arm-fixed.md -+++ b/src/gcc/config/arm/arm-fixed.md -@@ -19,12 +19,13 @@ - ;; This file contains ARM instructions that support fixed-point operations. +@@ -680,35 +751,44 @@ + UNSPEC_SQSHRN UNSPEC_UQSHRN + UNSPEC_SQRSHRN UNSPEC_UQRSHRN]) - (define_insn "add3" -- [(set (match_operand:FIXED 0 "s_register_operand" "=r") -- (plus:FIXED (match_operand:FIXED 1 "s_register_operand" "r") -- (match_operand:FIXED 2 "s_register_operand" "r")))] -+ [(set (match_operand:FIXED 0 "s_register_operand" "=l,r") -+ (plus:FIXED (match_operand:FIXED 1 "s_register_operand" "l,r") -+ (match_operand:FIXED 2 "s_register_operand" "l,r")))] - "TARGET_32BIT" - "add%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "yes,no")]) +-(define_int_iterator VCMP_S [UNSPEC_CMEQ UNSPEC_CMGE UNSPEC_CMGT +- UNSPEC_CMLE UNSPEC_CMLT]) +- +-(define_int_iterator VCMP_U [UNSPEC_CMHS UNSPEC_CMHI UNSPEC_CMTST]) +- + (define_int_iterator PERMUTE [UNSPEC_ZIP1 UNSPEC_ZIP2 + UNSPEC_TRN1 UNSPEC_TRN2 + UNSPEC_UZP1 UNSPEC_UZP2]) - (define_insn "add3" - [(set (match_operand:ADDSUB 0 "s_register_operand" "=r") -@@ -32,7 +33,8 @@ - (match_operand:ADDSUB 2 "s_register_operand" "r")))] - "TARGET_INT_SIMD" - "sadd%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + (define_int_iterator FRINT [UNSPEC_FRINTZ UNSPEC_FRINTP UNSPEC_FRINTM +- UNSPEC_FRINTI UNSPEC_FRINTX UNSPEC_FRINTA]) ++ UNSPEC_FRINTN UNSPEC_FRINTI UNSPEC_FRINTX ++ UNSPEC_FRINTA]) - (define_insn "usadd3" - [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r") -@@ -40,7 +42,8 @@ - (match_operand:UQADDSUB 2 "s_register_operand" "r")))] - "TARGET_INT_SIMD" - "uqadd%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + (define_int_iterator FCVT [UNSPEC_FRINTZ UNSPEC_FRINTP UNSPEC_FRINTM +- UNSPEC_FRINTA]) ++ UNSPEC_FRINTA UNSPEC_FRINTN]) - (define_insn "ssadd3" - [(set (match_operand:QADDSUB 0 "s_register_operand" "=r") -@@ -48,15 +51,17 @@ - (match_operand:QADDSUB 2 "s_register_operand" "r")))] - "TARGET_INT_SIMD" - "qadd%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) ++(define_int_iterator FRECP [UNSPEC_FRECPE UNSPEC_FRECPX]) ++ + ;; ------------------------------------------------------------------- + ;; Int Iterators Attributes. + ;; ------------------------------------------------------------------- +-(define_int_attr maxminv [(UNSPEC_UMAXV "umax") +- (UNSPEC_UMINV "umin") +- (UNSPEC_SMAXV "smax") +- (UNSPEC_SMINV "smin")]) ++(define_int_attr maxmin_uns [(UNSPEC_UMAXV "umax") ++ (UNSPEC_UMINV "umin") ++ (UNSPEC_SMAXV "smax") ++ (UNSPEC_SMINV "smin") ++ (UNSPEC_FMAX "smax_nan") ++ (UNSPEC_FMAXNMV "smax") ++ (UNSPEC_FMAXV "smax_nan") ++ (UNSPEC_FMIN "smin_nan") ++ (UNSPEC_FMINNMV "smin") ++ (UNSPEC_FMINV "smin_nan")]) - (define_insn "sub3" -- [(set (match_operand:FIXED 0 "s_register_operand" "=r") -- (minus:FIXED (match_operand:FIXED 1 "s_register_operand" "r") -- (match_operand:FIXED 2 "s_register_operand" "r")))] -+ [(set (match_operand:FIXED 0 "s_register_operand" "=l,r") -+ (minus:FIXED (match_operand:FIXED 1 "s_register_operand" "l,r") -+ (match_operand:FIXED 2 "s_register_operand" "l,r")))] - "TARGET_32BIT" - "sub%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "yes,no")]) +-(define_int_attr fmaxminv [(UNSPEC_FMAXV "max") +- (UNSPEC_FMINV "min")]) ++(define_int_attr maxmin_uns_op [(UNSPEC_UMAXV "umax") ++ (UNSPEC_UMINV "umin") ++ (UNSPEC_SMAXV "smax") ++ (UNSPEC_SMINV "smin") ++ (UNSPEC_FMAX "fmax") ++ (UNSPEC_FMAXNMV "fmaxnm") ++ (UNSPEC_FMAXV "fmax") ++ (UNSPEC_FMIN "fmin") ++ (UNSPEC_FMINNMV "fminnm") ++ (UNSPEC_FMINV "fmin")]) - (define_insn "sub3" - [(set (match_operand:ADDSUB 0 "s_register_operand" "=r") -@@ -64,7 +69,8 @@ - (match_operand:ADDSUB 2 "s_register_operand" "r")))] - "TARGET_INT_SIMD" - "ssub%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) +-(define_int_attr fmaxmin [(UNSPEC_FMAX "fmax") +- (UNSPEC_FMIN "fmin")]) +- + (define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u") + (UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur") + (UNSPEC_SHSUB "s") (UNSPEC_UHSUB "u") +@@ -719,6 +799,7 @@ + (UNSPEC_SUBHN2 "") (UNSPEC_RSUBHN2 "r") + (UNSPEC_SQXTN "s") (UNSPEC_UQXTN "u") + (UNSPEC_USQADD "us") (UNSPEC_SUQADD "su") ++ (UNSPEC_SADDV "s") (UNSPEC_UADDV "u") + (UNSPEC_SSLI "s") (UNSPEC_USLI "u") + (UNSPEC_SSRI "s") (UNSPEC_USRI "u") + (UNSPEC_USRA "u") (UNSPEC_SSRA "s") +@@ -768,12 +849,6 @@ + (UNSPEC_RADDHN2 "add") + (UNSPEC_RSUBHN2 "sub")]) + +-(define_int_attr cmp [(UNSPEC_CMGE "ge") (UNSPEC_CMGT "gt") +- (UNSPEC_CMLE "le") (UNSPEC_CMLT "lt") +- (UNSPEC_CMEQ "eq") +- (UNSPEC_CMHS "hs") (UNSPEC_CMHI "hi") +- (UNSPEC_CMTST "tst")]) +- + (define_int_attr offsetlr [(UNSPEC_SSLI "1") (UNSPEC_USLI "1") + (UNSPEC_SSRI "0") (UNSPEC_USRI "0")]) - (define_insn "ussub3" - [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r") -@@ -73,7 +79,8 @@ - (match_operand:UQADDSUB 2 "s_register_operand" "r")))] - "TARGET_INT_SIMD" - "uqsub%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) +@@ -783,15 +858,18 @@ + (UNSPEC_FRINTM "floor") + (UNSPEC_FRINTI "nearbyint") + (UNSPEC_FRINTX "rint") +- (UNSPEC_FRINTA "round")]) ++ (UNSPEC_FRINTA "round") ++ (UNSPEC_FRINTN "frintn")]) - (define_insn "sssub3" - [(set (match_operand:QADDSUB 0 "s_register_operand" "=r") -@@ -81,7 +88,8 @@ - (match_operand:QADDSUB 2 "s_register_operand" "r")))] - "TARGET_INT_SIMD" - "qsub%?\\t%0, %1, %2" -- [(set_attr "predicable" "yes")]) -+ [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + ;; frint suffix for floating-point rounding instructions. + (define_int_attr frint_suffix [(UNSPEC_FRINTZ "z") (UNSPEC_FRINTP "p") + (UNSPEC_FRINTM "m") (UNSPEC_FRINTI "i") +- (UNSPEC_FRINTX "x") (UNSPEC_FRINTA "a")]) ++ (UNSPEC_FRINTX "x") (UNSPEC_FRINTA "a") ++ (UNSPEC_FRINTN "n")]) - ;; Fractional multiplies. + (define_int_attr fcvt_pattern [(UNSPEC_FRINTZ "btrunc") (UNSPEC_FRINTA "round") +- (UNSPEC_FRINTP "ceil") (UNSPEC_FRINTM "floor")]) ++ (UNSPEC_FRINTP "ceil") (UNSPEC_FRINTM "floor") ++ (UNSPEC_FRINTN "frintn")]) -@@ -96,7 +104,7 @@ - rtx tmp1 = gen_reg_rtx (HImode); - rtx tmp2 = gen_reg_rtx (HImode); - rtx tmp3 = gen_reg_rtx (SImode); -- -+ - emit_insn (gen_extendqihi2 (tmp1, gen_lowpart (QImode, operands[1]))); - emit_insn (gen_extendqihi2 (tmp2, gen_lowpart (QImode, operands[2]))); - emit_insn (gen_mulhisi3 (tmp3, tmp1, tmp2)); -@@ -132,7 +140,7 @@ - rtx tmp1 = gen_reg_rtx (DImode); - rtx tmp2 = gen_reg_rtx (SImode); - rtx tmp3 = gen_reg_rtx (SImode); -- -+ - /* s.31 * s.31 -> s.62 multiplication. */ - emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2]))); -@@ -154,7 +162,7 @@ - rtx tmp1 = gen_reg_rtx (DImode); - rtx tmp2 = gen_reg_rtx (SImode); - rtx tmp3 = gen_reg_rtx (SImode); -- -+ - emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2]))); - emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (15))); -@@ -173,13 +181,13 @@ - rtx tmp1 = gen_reg_rtx (DImode); - rtx tmp2 = gen_reg_rtx (SImode); - rtx tmp3 = gen_reg_rtx (SImode); -- -+ - emit_insn (gen_umulsidi3 (tmp1, gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2]))); - emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (16))); - emit_insn (gen_ashlsi3 (tmp3, gen_highpart (SImode, tmp1), GEN_INT (16))); - emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3)); -- + (define_int_attr perm_insn [(UNSPEC_ZIP1 "zip") (UNSPEC_ZIP2 "zip") + (UNSPEC_TRN1 "trn") (UNSPEC_TRN2 "trn") +@@ -800,3 +878,5 @@ + (define_int_attr perm_hilo [(UNSPEC_ZIP1 "1") (UNSPEC_ZIP2 "2") + (UNSPEC_TRN1 "1") (UNSPEC_TRN2 "2") + (UNSPEC_UZP1 "1") (UNSPEC_UZP2 "2")]) + - DONE; - }) ++(define_int_attr frecp_suffix [(UNSPEC_FRECPE "e") (UNSPEC_FRECPX "x")]) +--- a/src/gcc/config/aarch64/aarch64.h ++++ b/src/gcc/config/aarch64/aarch64.h +@@ -151,6 +151,7 @@ + #define AARCH64_FL_FP (1 << 1) /* Has FP. */ + #define AARCH64_FL_CRYPTO (1 << 2) /* Has crypto. */ + #define AARCH64_FL_SLOWMUL (1 << 3) /* A slow multiply core. */ ++#define AARCH64_FL_CRC (1 << 4) /* Has CRC. */ + + /* Has FP and SIMD. */ + #define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD) +@@ -163,6 +164,7 @@ + + /* Macros to test ISA flags. */ + extern unsigned long aarch64_isa_flags; ++#define AARCH64_ISA_CRC (aarch64_isa_flags & AARCH64_FL_CRC) + #define AARCH64_ISA_CRYPTO (aarch64_isa_flags & AARCH64_FL_CRYPTO) + #define AARCH64_ISA_FP (aarch64_isa_flags & AARCH64_FL_FP) + #define AARCH64_ISA_SIMD (aarch64_isa_flags & AARCH64_FL_SIMD) +@@ -521,12 +523,6 @@ + #endif + + +-/* Which ABI to use. */ +-enum arm_abi_type +-{ +- ARM_ABI_AAPCS64 +-}; +- + enum arm_pcs + { + ARM_PCS_AAPCS64, /* Base standard AAPCS for 64 bit. */ +@@ -534,11 +530,7 @@ + }; -@@ -209,7 +217,7 @@ - } - /* We have: -- 31 high word 0 31 low word 0 -+ 31 high word 0 31 low word 0 +-extern enum arm_abi_type arm_abi; + extern enum arm_pcs arm_pcs_variant; +-#ifndef ARM_DEFAULT_ABI +-#define ARM_DEFAULT_ABI ARM_ABI_AAPCS64 +-#endif - [ S i i .... i i i ] [ i f f f ... f f ] - | -@@ -221,9 +229,18 @@ - output_asm_insn ("ssat\\t%R3, #15, %R3", operands); - output_asm_insn ("mrs\\t%4, APSR", operands); - output_asm_insn ("tst\\t%4, #1<<27", operands); -- if (TARGET_THUMB2) -- output_asm_insn ("it\\tne", operands); -- output_asm_insn ("mvnne\\t%Q3, %R3, asr #32", operands); -+ if (arm_restrict_it) -+ { -+ output_asm_insn ("mvn\\t%4, %R3, asr #32", operands); -+ output_asm_insn ("it\\tne", operands); -+ output_asm_insn ("movne\\t%Q3, %4", operands); -+ } -+ else -+ { -+ if (TARGET_THUMB2) -+ output_asm_insn ("it\\tne", operands); -+ output_asm_insn ("mvnne\\t%Q3, %R3, asr #32", operands); -+ } - output_asm_insn ("mov\\t%0, %Q3, lsr #15", operands); - output_asm_insn ("orr\\t%0, %0, %R3, asl #17", operands); - return ""; -@@ -231,7 +248,9 @@ - [(set_attr "conds" "clob") - (set (attr "length") - (if_then_else (eq_attr "is_thumb" "yes") -- (const_int 38) -+ (if_then_else (match_test "arm_restrict_it") -+ (const_int 40) -+ (const_int 38)) - (const_int 32)))]) + #ifndef ARM_DEFAULT_PCS + #define ARM_DEFAULT_PCS ARM_PCS_AAPCS64 +@@ -709,6 +701,8 @@ - ;; Same goes for this. -@@ -257,7 +276,7 @@ - } + #define SELECT_CC_MODE(OP, X, Y) aarch64_select_cc_mode (OP, X, Y) - /* We have: -- 31 high word 0 31 low word 0 -+ 31 high word 0 31 low word 0 ++#define REVERSIBLE_CC_MODE(MODE) 1 ++ + #define REVERSE_CONDITION(CODE, MODE) \ + (((MODE) == CCFPmode || (MODE) == CCFPEmode) \ + ? reverse_condition_maybe_unordered (CODE) \ +@@ -758,9 +752,23 @@ + #define PRINT_OPERAND_ADDRESS(STREAM, X) \ + aarch64_print_operand_address (STREAM, X) - [ i i i .... i i i ] [ f f f f ... f f ] - | -@@ -269,9 +288,18 @@ - output_asm_insn ("usat\\t%R3, #16, %R3", operands); - output_asm_insn ("mrs\\t%4, APSR", operands); - output_asm_insn ("tst\\t%4, #1<<27", operands); -- if (TARGET_THUMB2) -- output_asm_insn ("it\\tne", operands); -- output_asm_insn ("sbfxne\\t%Q3, %R3, #15, #1", operands); -+ if (arm_restrict_it) -+ { -+ output_asm_insn ("sbfx\\t%4, %R3, #15, #1", operands); -+ output_asm_insn ("it\\tne", operands); -+ output_asm_insn ("movne\\t%Q3, %4", operands); -+ } -+ else -+ { -+ if (TARGET_THUMB2) -+ output_asm_insn ("it\\tne", operands); -+ output_asm_insn ("sbfxne\\t%Q3, %R3, #15, #1", operands); -+ } - output_asm_insn ("lsr\\t%0, %Q3, #16", operands); - output_asm_insn ("orr\\t%0, %0, %R3, asl #16", operands); - return ""; -@@ -279,7 +307,9 @@ - [(set_attr "conds" "clob") - (set (attr "length") - (if_then_else (eq_attr "is_thumb" "yes") -- (const_int 38) -+ (if_then_else (match_test "arm_restrict_it") -+ (const_int 40) -+ (const_int 38)) - (const_int 32)))]) +-#define FUNCTION_PROFILER(STREAM, LABELNO) \ +- aarch64_function_profiler (STREAM, LABELNO) ++#define MCOUNT_NAME "_mcount" - (define_expand "mulha3" -@@ -289,7 +319,7 @@ - "TARGET_DSP_MULTIPLY && arm_arch_thumb2" - { - rtx tmp = gen_reg_rtx (SImode); -- ++#define NO_PROFILE_COUNTERS 1 + - emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]), - gen_lowpart (HImode, operands[2]))); - emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp, GEN_INT (16), -@@ -307,7 +337,7 @@ - rtx tmp1 = gen_reg_rtx (SImode); - rtx tmp2 = gen_reg_rtx (SImode); - rtx tmp3 = gen_reg_rtx (SImode); -- ++/* Emit rtl for profiling. Output assembler code to FILE ++ to call "_mcount" for profiling a function entry. */ ++#define PROFILE_HOOK(LABEL) \ ++{ \ ++ rtx fun,lr; \ ++ lr = get_hard_reg_initial_val (Pmode, LR_REGNUM); \ ++ fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \ ++ emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lr, Pmode); \ ++} + - /* 8.8 * 8.8 -> 16.16 multiply. */ - emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1]))); - emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2]))); -@@ -326,7 +356,7 @@ - { - rtx tmp = gen_reg_rtx (SImode); - rtx rshift; -- ++/* All the work done in PROFILE_HOOK, but still required. */ ++#define FUNCTION_PROFILER(STREAM, LABELNO) do { } while (0) + - emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]), - gen_lowpart (HImode, operands[2]))); + /* For some reason, the Linux headers think they know how to define + these macros. They don't!!! */ + #undef ASM_APP_ON +--- a/src/gcc/config/arm/arm1020e.md ++++ b/src/gcc/config/arm/arm1020e.md +@@ -66,13 +66,14 @@ + ;; ALU operations with no shifted operand + (define_insn_reservation "1020alu_op" 1 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "type" "alu_reg,simple_alu_imm")) ++ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ ++ mov_imm,mov_reg,mvn_imm,mvn_reg")) + "1020a_e,1020a_m,1020a_w") -@@ -348,12 +378,12 @@ - rtx tmp2 = gen_reg_rtx (SImode); - rtx tmp3 = gen_reg_rtx (SImode); - rtx rshift_tmp = gen_reg_rtx (SImode); -- -+ - /* Note: there's no smul[bt][bt] equivalent for unsigned multiplies. Use a - normal 32x32->32-bit multiply instead. */ - emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1]))); - emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2]))); -- -+ - emit_insn (gen_mulsi3 (tmp3, tmp1, tmp2)); + ;; ALU operations with a shift-by-constant operand + (define_insn_reservation "1020alu_shift_op" 1 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "type" "simple_alu_shift,alu_shift")) ++ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + "1020a_e,1020a_m,1020a_w") - /* The operand to "usat" is signed, so we cannot use the "..., asr #8" -@@ -374,9 +404,9 @@ - "TARGET_32BIT && arm_arch6" - "ssat%?\\t%0, #16, %2%S1" - [(set_attr "predicable" "yes") -- (set_attr "insn" "sat") -+ (set_attr "predicable_short_it" "no") - (set_attr "shift" "1") -- (set_attr "type" "alu_shift")]) -+ (set_attr "type" "arlo_shift")]) + ;; ALU operations with a shift-by-register operand +@@ -81,7 +82,7 @@ + ;; the execute stage. + (define_insn_reservation "1020alu_shift_reg_op" 2 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "type" "alu_shift_reg")) ++ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + "1020a_e*2,1020a_m,1020a_w") - (define_insn "arm_usatsihi" - [(set (match_operand:HI 0 "s_register_operand" "=r") -@@ -384,4 +414,5 @@ - "TARGET_INT_SIMD" - "usat%?\\t%0, #16, %1" - [(set_attr "predicable" "yes") -- (set_attr "insn" "sat")]) -+ (set_attr "predicable_short_it" "no")] -+) ---- a/src/gcc/config/arm/crypto.def -+++ b/src/gcc/config/arm/crypto.def -@@ -0,0 +1,34 @@ -+/* Cryptographic instruction builtin definitions. -+ Copyright (C) 2013-2014 Free Software Foundation, Inc. -+ Contributed by ARM Ltd. -+ This file is part of GCC. -+ -+ GCC is free software; you can redistribute it and/or modify it -+ under the terms of the GNU General Public License as published -+ by the Free Software Foundation; either version 3, or (at your -+ option) any later version. -+ -+ GCC is distributed in the hope that it will be useful, but WITHOUT -+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -+ License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with GCC; see the file COPYING3. If not see -+ . */ -+ -+CRYPTO2 (aesd, AESD, v16uqi, v16uqi, v16uqi) -+CRYPTO2 (aese, AESE, v16uqi, v16uqi, v16uqi) -+CRYPTO1 (aesimc, AESIMC, v16uqi, v16uqi) -+CRYPTO1 (aesmc, AESMC, v16uqi, v16uqi) -+CRYPTO1 (sha1h, SHA1H, v4usi, v4usi) -+CRYPTO2 (sha1su1, SHA1SU1, v4usi, v4usi, v4usi) -+CRYPTO2 (sha256su0, SHA256SU0, v4usi, v4usi, v4usi) -+CRYPTO3 (sha1c, SHA1C, v4usi, v4usi, v4usi, v4usi) -+CRYPTO3 (sha1m, SHA1M, v4usi, v4usi, v4usi, v4usi) -+CRYPTO3 (sha1p, SHA1P, v4usi, v4usi, v4usi, v4usi) -+CRYPTO3 (sha1su0, SHA1SU0, v4usi, v4usi, v4usi, v4usi) -+CRYPTO3 (sha256h, SHA256H, v4usi, v4usi, v4usi, v4usi) -+CRYPTO3 (sha256h2, SHA256H2, v4usi, v4usi, v4usi, v4usi) -+CRYPTO3 (sha256su1, SHA256SU1, v4usi, v4usi, v4usi, v4usi) -+CRYPTO2 (vmullp64, VMULLP64, uti, udi, udi) ---- a/src/gcc/config/arm/unspecs.md -+++ b/src/gcc/config/arm/unspecs.md -@@ -139,6 +139,10 @@ - VUNSPEC_ATOMIC_OP ; Represent an atomic operation. - VUNSPEC_LL ; Represent a load-register-exclusive. - VUNSPEC_SC ; Represent a store-register-exclusive. -+ VUNSPEC_LAX ; Represent a load-register-acquire-exclusive. -+ VUNSPEC_SLX ; Represent a store-register-release-exclusive. -+ VUNSPEC_LDA ; Represent a store-register-acquire. -+ VUNSPEC_STL ; Represent a store-register-release. - ]) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +@@ -96,7 +97,7 @@ + ;; until after the memory stage. + (define_insn_reservation "1020mult1" 2 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "insn" "smulxy,smulwy")) ++ (eq_attr "type" "smulxy,smulwy")) + "1020a_e,1020a_m,1020a_w") - ;; Enumerators for NEON unspecs. -@@ -145,6 +149,27 @@ - (define_c_enum "unspec" [ - UNSPEC_ASHIFT_SIGNED - UNSPEC_ASHIFT_UNSIGNED -+ UNSPEC_CRC32B -+ UNSPEC_CRC32H -+ UNSPEC_CRC32W -+ UNSPEC_CRC32CB -+ UNSPEC_CRC32CH -+ UNSPEC_CRC32CW -+ UNSPEC_AESD -+ UNSPEC_AESE -+ UNSPEC_AESIMC -+ UNSPEC_AESMC -+ UNSPEC_SHA1C -+ UNSPEC_SHA1M -+ UNSPEC_SHA1P -+ UNSPEC_SHA1H -+ UNSPEC_SHA1SU0 -+ UNSPEC_SHA1SU1 -+ UNSPEC_SHA256H -+ UNSPEC_SHA256H2 -+ UNSPEC_SHA256SU0 -+ UNSPEC_SHA256SU1 -+ UNSPEC_VMULLP64 - UNSPEC_LOAD_COUNT - UNSPEC_VABD - UNSPEC_VABDL ---- a/src/gcc/config/arm/cortex-m4.md -+++ b/src/gcc/config/arm/cortex-m4.md -@@ -31,7 +31,12 @@ - ;; ALU and multiply is one cycle. - (define_insn_reservation "cortex_m4_alu" 1 - (and (eq_attr "tune" "cortexm4") -- (eq_attr "type" "alu_reg,simple_alu_imm,simple_alu_shift,alu_shift,alu_shift_reg,mult")) -+ (ior (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,\ -+ arlo_shift,arlo_shift_reg,\ -+ mov_imm,mov_reg,mov_shift,mov_shift_reg,\ -+ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg") -+ (ior (eq_attr "mul32" "yes") -+ (eq_attr "mul64" "yes")))) - "cortex_m4_ex") + ;; The "smlaxy" and "smlawx" instructions require two iterations through +@@ -104,7 +105,7 @@ + ;; the execute stage. + (define_insn_reservation "1020mult2" 2 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "insn" "smlaxy,smlalxy,smlawx")) ++ (eq_attr "type" "smlaxy,smlalxy,smlawx")) + "1020a_e*2,1020a_m,1020a_w") - ;; Byte, half-word and word load is two cycles. ---- a/src/gcc/config/arm/linux-eabi.h -+++ b/src/gcc/config/arm/linux-eabi.h -@@ -84,10 +84,14 @@ - LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ - LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) + ;; The "smlalxy", "mul", and "mla" instructions require two iterations +@@ -112,7 +113,7 @@ + ;; the memory stage. + (define_insn_reservation "1020mult3" 3 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "insn" "smlalxy,mul,mla")) ++ (eq_attr "type" "smlalxy,mul,mla")) + "1020a_e*2,1020a_m,1020a_w") -+#undef ASAN_CC1_SPEC -+#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}" -+ - #undef CC1_SPEC - #define CC1_SPEC \ -- LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ -- GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) -+ LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ -+ GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ -+ ANDROID_CC1_SPEC) + ;; The "muls" and "mlas" instructions loop in the execute stage for +@@ -120,7 +121,7 @@ + ;; available after three iterations. + (define_insn_reservation "1020mult4" 3 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "insn" "muls,mlas")) ++ (eq_attr "type" "muls,mlas")) + "1020a_e*4,1020a_m,1020a_w") - #define CC1PLUS_SPEC \ - LINUX_OR_ANDROID_CC ("", ANDROID_CC1PLUS_SPEC) -@@ -95,7 +99,7 @@ - #undef LIB_SPEC - #define LIB_SPEC \ - LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \ -- GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC) -+ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC " " ANDROID_LIB_SPEC) + ;; Long multiply instructions that produce two registers of +@@ -135,7 +136,7 @@ + ;; available after the memory cycle. + (define_insn_reservation "1020mult5" 4 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "insn" "umull,umlal,smull,smlal")) ++ (eq_attr "type" "umull,umlal,smull,smlal")) + "1020a_e*3,1020a_m,1020a_w") - #undef STARTFILE_SPEC - #define STARTFILE_SPEC \ ---- a/src/gcc/config/arm/arm-cores.def -+++ b/src/gcc/config/arm/arm-cores.def -@@ -129,9 +129,11 @@ - ARM_CORE("cortex-a8", cortexa8, 7A, FL_LDSCHED, cortex) - ARM_CORE("cortex-a9", cortexa9, 7A, FL_LDSCHED, cortex_a9) - ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15) -+ARM_CORE("cortex-a53", cortexa53, 8A, FL_LDSCHED, cortex_a5) - ARM_CORE("cortex-r4", cortexr4, 7R, FL_LDSCHED, cortex) - ARM_CORE("cortex-r4f", cortexr4f, 7R, FL_LDSCHED, cortex) - ARM_CORE("cortex-r5", cortexr5, 7R, FL_LDSCHED | FL_ARM_DIV, cortex) -+ARM_CORE("cortex-r7", cortexr7, 7R, FL_LDSCHED | FL_ARM_DIV, cortex) - ARM_CORE("cortex-m4", cortexm4, 7EM, FL_LDSCHED, cortex) - ARM_CORE("cortex-m3", cortexm3, 7M, FL_LDSCHED, cortex) - ARM_CORE("cortex-m1", cortexm1, 6M, FL_LDSCHED, v6m) ---- a/src/gcc/config/arm/cortex-r4.md -+++ b/src/gcc/config/arm/cortex-r4.md -@@ -78,24 +78,22 @@ - ;; for the purposes of the dual-issue constraints above. - (define_insn_reservation "cortex_r4_alu" 2 - (and (eq_attr "tune_cortexr4" "yes") -- (and (eq_attr "type" "alu_reg,simple_alu_imm") -- (not (eq_attr "insn" "mov")))) -+ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,mvn_imm,mvn_reg")) - "cortex_r4_alu") + ;; The "umulls", "umlals", "smulls", and "smlals" instructions loop in +@@ -143,7 +144,7 @@ + ;; The value result is available after four iterations. + (define_insn_reservation "1020mult6" 4 + (and (eq_attr "tune" "arm1020e,arm1022e") +- (eq_attr "insn" "umulls,umlals,smulls,smlals")) ++ (eq_attr "type" "umulls,umlals,smulls,smlals")) + "1020a_e*5,1020a_m,1020a_w") - (define_insn_reservation "cortex_r4_mov" 2 - (and (eq_attr "tune_cortexr4" "yes") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +--- a/src/gcc/config/arm/cortex-a15.md ++++ b/src/gcc/config/arm/cortex-a15.md +@@ -61,14 +61,16 @@ + ;; Simple ALU without shift + (define_insn_reservation "cortex_a15_alu" 2 + (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "alu_reg,simple_alu_imm") -- (eq_attr "insn" "mov"))) -+ (eq_attr "type" "mov_imm,mov_reg")) - "cortex_r4_mov") ++ (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ ++ mov_imm,mov_reg,\ ++ mvn_imm,mvn_reg") + (eq_attr "neon_type" "none"))) + "ca15_issue1,(ca15_sx1,ca15_sx1_alu)|(ca15_sx2,ca15_sx2_alu)") - (define_insn_reservation "cortex_r4_alu_shift" 2 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "type" "simple_alu_shift,alu_shift")) -+ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) - "cortex_r4_alu") + ;; ALU ops with immediate shift + (define_insn_reservation "cortex_a15_alu_shift" 3 + (and (eq_attr "tune" "cortexa15") +- (and (eq_attr "type" "simple_alu_shift,alu_shift") ++ (and (eq_attr "type" "extend,arlo_shift,,mov_shift,mvn_shift") + (eq_attr "neon_type" "none"))) + "ca15_issue1,(ca15_sx1,ca15_sx1+ca15_sx1_shf,ca15_sx1_alu)\ + |(ca15_sx2,ca15_sx2+ca15_sx2_shf,ca15_sx2_alu)") +@@ -76,7 +78,7 @@ + ;; ALU ops with register controlled shift + (define_insn_reservation "cortex_a15_alu_shift_reg" 3 + (and (eq_attr "tune" "cortexa15") +- (and (eq_attr "type" "alu_shift_reg") ++ (and (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg") + (eq_attr "neon_type" "none"))) + "(ca15_issue2,ca15_sx1+ca15_sx2,ca15_sx1_shf,ca15_sx2_alu)\ + |(ca15_issue1,(ca15_issue1+ca15_sx2,ca15_sx1+ca15_sx2_shf)\ +@@ -87,28 +89,26 @@ + ;; 32-bit multiplies + (define_insn_reservation "cortex_a15_mult32" 3 + (and (eq_attr "tune" "cortexa15") +- (and (eq_attr "type" "mult") +- (and (eq_attr "neon_type" "none") +- (eq_attr "mul64" "no")))) ++ (and (eq_attr "mul32" "yes") ++ (eq_attr "neon_type" "none"))) + "ca15_issue1,ca15_mx") - (define_insn_reservation "cortex_r4_alu_shift_reg" 2 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "type" "alu_shift_reg")) -+ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) - "cortex_r4_alu_shift_reg") + ;; 64-bit multiplies + (define_insn_reservation "cortex_a15_mult64" 4 + (and (eq_attr "tune" "cortexa15") +- (and (eq_attr "type" "mult") +- (and (eq_attr "neon_type" "none") +- (eq_attr "mul64" "yes")))) ++ (and (eq_attr "mul64" "yes") ++ (eq_attr "neon_type" "none"))) + "ca15_issue1,ca15_mx*2") - ;; An ALU instruction followed by an ALU instruction with no early dep. -@@ -128,32 +126,32 @@ + ;; Integer divide + (define_insn_reservation "cortex_a15_udiv" 9 + (and (eq_attr "tune" "cortexa15") +- (eq_attr "insn" "udiv")) ++ (eq_attr "type" "udiv")) + "ca15_issue1,ca15_mx") - (define_insn_reservation "cortex_r4_mul_4" 4 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "mul,smmul")) -+ (eq_attr "type" "mul,smmul")) - "cortex_r4_mul_2") + (define_insn_reservation "cortex_a15_sdiv" 10 + (and (eq_attr "tune" "cortexa15") +- (eq_attr "insn" "sdiv")) ++ (eq_attr "type" "sdiv")) + "ca15_issue1,ca15_mx") - (define_insn_reservation "cortex_r4_mul_3" 3 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "smulxy,smulwy,smuad,smusd")) -+ (eq_attr "type" "smulxy,smulwy,smuad,smusd")) - "cortex_r4_mul") + ;; Block all issue pipes for a cycle +--- a/src/gcc/config/arm/arm-tables.opt ++++ b/src/gcc/config/arm/arm-tables.opt +@@ -250,6 +250,9 @@ + Enum(processor_type) String(cortex-a15) Value(cortexa15) + + EnumValue ++Enum(processor_type) String(cortex-a53) Value(cortexa53) ++ ++EnumValue + Enum(processor_type) String(cortex-r4) Value(cortexr4) + + EnumValue +@@ -259,6 +262,9 @@ + Enum(processor_type) String(cortex-r5) Value(cortexr5) + + EnumValue ++Enum(processor_type) String(cortex-r7) Value(cortexr7) ++ ++EnumValue + Enum(processor_type) String(cortex-m4) Value(cortexm4) + + EnumValue +--- a/src/gcc/config/arm/arm1026ejs.md ++++ b/src/gcc/config/arm/arm1026ejs.md +@@ -66,13 +66,14 @@ + ;; ALU operations with no shifted operand + (define_insn_reservation "alu_op" 1 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "type" "alu_reg,simple_alu_imm")) ++ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ ++ mov_imm,mov_reg,mvn_imm,mvn_reg")) + "a_e,a_m,a_w") + + ;; ALU operations with a shift-by-constant operand + (define_insn_reservation "alu_shift_op" 1 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "type" "simple_alu_shift,alu_shift")) ++ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + "a_e,a_m,a_w") + + ;; ALU operations with a shift-by-register operand +@@ -81,7 +82,7 @@ + ;; the execute stage. + (define_insn_reservation "alu_shift_reg_op" 2 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "type" "alu_shift_reg")) ++ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + "a_e*2,a_m,a_w") + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +@@ -96,7 +97,7 @@ + ;; until after the memory stage. + (define_insn_reservation "mult1" 2 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "insn" "smulxy,smulwy")) ++ (eq_attr "type" "smulxy,smulwy")) + "a_e,a_m,a_w") + + ;; The "smlaxy" and "smlawx" instructions require two iterations through +@@ -104,7 +105,7 @@ + ;; the execute stage. + (define_insn_reservation "mult2" 2 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "insn" "smlaxy,smlalxy,smlawx")) ++ (eq_attr "type" "smlaxy,smlalxy,smlawx")) + "a_e*2,a_m,a_w") + + ;; The "smlalxy", "mul", and "mla" instructions require two iterations +@@ -112,7 +113,7 @@ + ;; the memory stage. + (define_insn_reservation "mult3" 3 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "insn" "smlalxy,mul,mla")) ++ (eq_attr "type" "smlalxy,mul,mla")) + "a_e*2,a_m,a_w") + + ;; The "muls" and "mlas" instructions loop in the execute stage for +@@ -120,7 +121,7 @@ + ;; available after three iterations. + (define_insn_reservation "mult4" 3 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "insn" "muls,mlas")) ++ (eq_attr "type" "muls,mlas")) + "a_e*4,a_m,a_w") + + ;; Long multiply instructions that produce two registers of +@@ -135,7 +136,7 @@ + ;; available after the memory cycle. + (define_insn_reservation "mult5" 4 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "insn" "umull,umlal,smull,smlal")) ++ (eq_attr "type" "umull,umlal,smull,smlal")) + "a_e*3,a_m,a_w") - (define_insn_reservation "cortex_r4_mla_4" 4 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "mla,smmla")) -+ (eq_attr "type" "mla,smmla")) - "cortex_r4_mul_2") + ;; The "umulls", "umlals", "smulls", and "smlals" instructions loop in +@@ -143,7 +144,7 @@ + ;; The value result is available after four iterations. + (define_insn_reservation "mult6" 4 + (and (eq_attr "tune" "arm1026ejs") +- (eq_attr "insn" "umulls,umlals,smulls,smlals")) ++ (eq_attr "type" "umulls,umlals,smulls,smlals")) + "a_e*5,a_m,a_w") - (define_insn_reservation "cortex_r4_mla_3" 3 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "smlaxy,smlawy,smlad,smlsd")) -+ (eq_attr "type" "smlaxy,smlawy,smlad,smlsd")) - "cortex_r4_mul") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +--- a/src/gcc/config/arm/linux-elf.h ++++ b/src/gcc/config/arm/linux-elf.h +@@ -44,9 +44,9 @@ - (define_insn_reservation "cortex_r4_smlald" 3 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "smlald,smlsld")) -+ (eq_attr "type" "smlald,smlsld")) - "cortex_r4_mul") + #define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p" - (define_insn_reservation "cortex_r4_mull" 4 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "smull,umull,umlal,umaal")) -+ (eq_attr "type" "smull,umull,umlal,umaal")) - "cortex_r4_mul_2") ++/* We do not have any MULTILIB_OPTIONS specified, so there are no ++ MULTILIB_DEFAULTS. */ + #undef MULTILIB_DEFAULTS +-#define MULTILIB_DEFAULTS \ +- { "marm", "mlittle-endian", "mfloat-abi=hard", "mno-thumb-interwork" } - ;; A multiply or an MLA with a single-register result, followed by an -@@ -196,12 +194,12 @@ - ;; This gives a latency of nine for udiv and ten for sdiv. - (define_insn_reservation "cortex_r4_udiv" 9 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "udiv")) -+ (eq_attr "type" "udiv")) - "cortex_r4_div_9") + /* Now we define the strings used to build the spec file. */ + #undef LIB_SPEC +--- a/src/gcc/config/arm/arm1136jfs.md ++++ b/src/gcc/config/arm/arm1136jfs.md +@@ -75,13 +75,14 @@ + ;; ALU operations with no shifted operand + (define_insn_reservation "11_alu_op" 2 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "type" "alu_reg,simple_alu_imm")) ++ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ ++ mov_imm,mov_reg,mvn_imm,mvn_reg")) + "e_1,e_2,e_3,e_wb") - (define_insn_reservation "cortex_r4_sdiv" 10 - (and (eq_attr "tune_cortexr4" "yes") -- (eq_attr "insn" "sdiv")) -+ (eq_attr "type" "sdiv")) - "cortex_r4_div_10") + ;; ALU operations with a shift-by-constant operand + (define_insn_reservation "11_alu_shift_op" 2 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "type" "simple_alu_shift,alu_shift")) ++ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + "e_1,e_2,e_3,e_wb") - ;; Branches. We assume correct prediction. ---- a/src/gcc/config/arm/arm-tune.md -+++ b/src/gcc/config/arm/arm-tune.md -@@ -1,5 +1,5 @@ - ;; -*- buffer-read-only: t -*- - ;; Generated automatically by gentune.sh from arm-cores.def - (define_attr "tune" -- "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,fa526,fa626,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,genericv7a,cortexa5,cortexa7,cortexa8,cortexa9,cortexa15,cortexr4,cortexr4f,cortexr5,cortexm4,cortexm3,cortexm1,cortexm0,cortexm0plus,marvell_pj4" -+ "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,fa526,fa626,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,genericv7a,cortexa5,cortexa7,cortexa8,cortexa9,cortexa15,cortexa53,cortexr4,cortexr4f,cortexr5,cortexr7,cortexm4,cortexm3,cortexm1,cortexm0,cortexm0plus,marvell_pj4" - (const (symbol_ref "((enum attr_tune) arm_tune)"))) ---- a/src/gcc/config/arm/arm_acle.h -+++ b/src/gcc/config/arm/arm_acle.h -@@ -0,0 +1,100 @@ -+/* ARM Non-NEON ACLE intrinsics include file. -+ -+ Copyright (C) 2013-2014 Free Software Foundation, Inc. -+ Contributed by ARM Ltd. -+ -+ This file is part of GCC. -+ -+ GCC is free software; you can redistribute it and/or modify it -+ under the terms of the GNU General Public License as published -+ by the Free Software Foundation; either version 3, or (at your -+ option) any later version. -+ -+ GCC is distributed in the hope that it will be useful, but WITHOUT -+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -+ License for more details. -+ -+ Under Section 7 of GPL version 3, you are granted additional -+ permissions described in the GCC Runtime Library Exception, version -+ 3.1, as published by the Free Software Foundation. -+ -+ You should have received a copy of the GNU General Public License and -+ a copy of the GCC Runtime Library Exception along with this program; -+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -+ . */ -+ -+#ifndef _GCC_ARM_ACLE_H -+#define _GCC_ARM_ACLE_H -+ -+#include -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#ifdef __ARM_FEATURE_CRC32 -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32b (uint32_t __a, uint8_t __b) -+{ -+ return __builtin_arm_crc32b (__a, __b); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32h (uint32_t __a, uint16_t __b) -+{ -+ return __builtin_arm_crc32h (__a, __b); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32w (uint32_t __a, uint32_t __b) -+{ -+ return __builtin_arm_crc32w (__a, __b); -+} -+ -+#ifdef __ARM_32BIT_STATE -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32d (uint32_t __a, uint64_t __b) -+{ -+ uint32_t __d; -+ -+ __d = __crc32w (__crc32w (__a, __b & 0xffffffffULL), __b >> 32); -+ return __d; -+} -+#endif -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32cb (uint32_t __a, uint8_t __b) -+{ -+ return __builtin_arm_crc32cb (__a, __b); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32ch (uint32_t __a, uint16_t __b) -+{ -+ return __builtin_arm_crc32ch (__a, __b); -+} -+ -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32cw (uint32_t __a, uint32_t __b) -+{ -+ return __builtin_arm_crc32cw (__a, __b); -+} -+ -+#ifdef __ARM_32BIT_STATE -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+__crc32cd (uint32_t __a, uint64_t __b) -+{ -+ uint32_t __d; -+ -+ __d = __crc32cw (__crc32cw (__a, __b & 0xffffffffULL), __b >> 32); -+ return __d; -+} -+#endif -+ -+#endif -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- a/src/gcc/config/arm/arm-protos.h -+++ b/src/gcc/config/arm/arm-protos.h -@@ -24,12 +24,13 @@ + ;; ALU operations with a shift-by-register operand +@@ -90,7 +91,7 @@ + ;; the shift stage. + (define_insn_reservation "11_alu_shift_reg_op" 3 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "type" "alu_shift_reg")) ++ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + "e_1*2,e_2,e_3,e_wb") - extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *); - extern int use_return_insn (int, rtx); -+extern bool use_simple_return_p (void); - extern enum reg_class arm_regno_class (int); - extern void arm_load_pic_register (unsigned long); - extern int arm_volatile_func (void); - extern void arm_expand_prologue (void); - extern void arm_expand_epilogue (bool); --extern void thumb2_expand_return (void); -+extern void thumb2_expand_return (bool); - extern const char *arm_strip_name_encoding (const char *); - extern void arm_asm_output_labelref (FILE *, const char *); - extern void thumb2_asm_output_opcode (FILE *); -@@ -78,6 +79,7 @@ - extern void neon_pairwise_reduce (rtx, rtx, enum machine_mode, - rtx (*) (rtx, rtx, rtx)); - extern rtx neon_make_constant (rtx); -+extern tree arm_builtin_vectorized_function (tree, tree, tree); - extern void neon_expand_vector_init (rtx, rtx); - extern void neon_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT); - extern void neon_const_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT); -@@ -117,7 +119,9 @@ - extern rtx arm_gen_store_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *); - extern bool offset_ok_for_ldrd_strd (HOST_WIDE_INT); - extern bool operands_ok_ldrd_strd (rtx, rtx, rtx, HOST_WIDE_INT, bool, bool); -+extern bool gen_operands_ldrd_strd (rtx *, bool, bool, bool); - extern int arm_gen_movmemqi (rtx *); -+extern bool gen_movmem_ldrd_strd (rtx *); - extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx); - extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx, - HOST_WIDE_INT); -@@ -224,6 +228,8 @@ + ;; alu_ops can start sooner, if there is no shifter dependency +@@ -129,13 +130,13 @@ + ;; Multiply and multiply-accumulate results are available after four stages. + (define_insn_reservation "11_mult1" 4 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "insn" "mul,mla")) ++ (eq_attr "type" "mul,mla")) + "e_1*2,e_2,e_3,e_wb") - extern void arm_order_regs_for_local_alloc (void); + ;; The *S variants set the condition flags, which requires three more cycles. + (define_insn_reservation "11_mult2" 4 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "insn" "muls,mlas")) ++ (eq_attr "type" "muls,mlas")) + "e_1*2,e_2,e_3,e_wb") -+extern int arm_max_conditional_execute (); -+ - /* Vectorizer cost model implementation. */ - struct cpu_vec_costs { - const int scalar_stmt_cost; /* Cost of any scalar operation, excluding -@@ -253,8 +259,7 @@ - bool (*rtx_costs) (rtx, RTX_CODE, RTX_CODE, int *, bool); - bool (*sched_adjust_cost) (rtx, rtx, rtx, int *); - int constant_limit; -- /* Maximum number of instructions to conditionalise in -- arm_final_prescan_insn. */ -+ /* Maximum number of instructions to conditionalise. */ - int max_insns_skipped; - int num_prefetch_slots; - int l1_cache_size; -@@ -269,6 +274,8 @@ - bool logical_op_non_short_circuit[2]; - /* Vectorizer costs. */ - const struct cpu_vec_costs* vec_costs; -+ /* Prefer Neon for 64-bit bitops. */ -+ bool prefer_neon_for_64bits; - }; + (define_bypass 3 "11_mult1,11_mult2" +@@ -160,13 +161,13 @@ + ;; the two multiply-accumulate instructions. + (define_insn_reservation "11_mult3" 5 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "insn" "smull,umull,smlal,umlal")) ++ (eq_attr "type" "smull,umull,smlal,umlal")) + "e_1*3,e_2,e_3,e_wb*2") - extern const struct tune_params *current_tune; ---- a/src/gcc/config/arm/vfp.md -+++ b/src/gcc/config/arm/vfp.md -@@ -18,31 +18,6 @@ - ;; along with GCC; see the file COPYING3. If not see - ;; . */ + ;; The *S variants set the condition flags, which requires three more cycles. + (define_insn_reservation "11_mult4" 5 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "insn" "smulls,umulls,smlals,umlals")) ++ (eq_attr "type" "smulls,umulls,smlals,umlals")) + "e_1*3,e_2,e_3,e_wb*2") --;; The VFP "type" attributes differ from those used in the FPA model. --;; fcpys Single precision cpy. --;; ffariths Single precision abs, neg. --;; ffarithd Double precision abs, neg, cpy. --;; fadds Single precision add/sub. --;; faddd Double precision add/sub. --;; fconsts Single precision load immediate. --;; fconstd Double precision load immediate. --;; fcmps Single precision comparison. --;; fcmpd Double precision comparison. --;; fmuls Single precision multiply. --;; fmuld Double precision multiply. --;; fmacs Single precision multiply-accumulate. --;; fmacd Double precision multiply-accumulate. --;; ffmas Single precision fused multiply-accumulate. --;; ffmad Double precision fused multiply-accumulate. --;; fdivs Single precision sqrt or division. --;; fdivd Double precision sqrt or division. --;; f_flag fmstat operation --;; f_load[sd] Floating point load from memory. --;; f_store[sd] Floating point store to memory. --;; f_2_r Transfer vfp to arm reg. --;; r_2_f Transfer arm to vfp reg. --;; f_cvt Convert floating<->integral -- - ;; SImode moves - ;; ??? For now do not allow loading constants into vfp regs. This causes - ;; problems because small constants get converted into adds. -@@ -78,9 +53,8 @@ - } - " - [(set_attr "predicable" "yes") -- (set_attr "type" "*,*,simple_alu_imm,simple_alu_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") -+ (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") - (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") -- (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*") - (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*") - (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")] - ) -@@ -87,9 +61,12 @@ + (define_bypass 4 "11_mult3,11_mult4" +@@ -190,7 +191,8 @@ + ;; cycles. + (define_insn_reservation "11_mult5" 3 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "insn" "smulxy,smlaxy,smulwy,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx")) ++ (eq_attr "type" "smulxy,smlaxy,smulwy,smlawy,smuad,smuadx,smlad,smladx,\ ++ smusd,smusdx,smlsd,smlsdx")) + "e_1,e_2,e_3,e_wb") - ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split - ;; high/low register alternatives for loads and stores here. -+;; The l/Py alternative should come after r/I to ensure that the short variant -+;; is chosen with length 2 when the instruction is predicated for -+;; arm_restrict_it. - (define_insn "*thumb2_movsi_vfp" -- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") -- (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] -+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") -+ (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] - "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT - && ( s_register_operand (operands[0], SImode) - || s_register_operand (operands[1], SImode))" -@@ -96,25 +73,27 @@ - "* - switch (which_alternative) - { -- case 0: case 1: -+ case 0: -+ case 1: -+ case 2: - return \"mov%?\\t%0, %1\"; -- case 2: -+ case 3: - return \"mvn%?\\t%0, #%B1\"; -- case 3: -+ case 4: - return \"movw%?\\t%0, %1\"; -- case 4: - case 5: -+ case 6: - return \"ldr%?\\t%0, %1\"; -- case 6: - case 7: -+ case 8: - return \"str%?\\t%1, %0\"; -- case 8: -+ case 9: - return \"fmsr%?\\t%0, %1\\t%@ int\"; -- case 9: -+ case 10: - return \"fmrs%?\\t%0, %1\\t%@ int\"; -- case 10: -+ case 11: - return \"fcpys%?\\t%0, %1\\t%@ int\"; -- case 11: case 12: -+ case 12: case 13: - return output_move_vfp (operands); - default: - gcc_unreachable (); -@@ -121,11 +100,12 @@ - } - " - [(set_attr "predicable" "yes") -- (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") -- (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") -- (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*") -- (set_attr "pool_range" "*,*,*,*,1018,4094,*,*,*,*,*,1018,*") -- (set_attr "neg_pool_range" "*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] -+ (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no") -+ (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_reg,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") -+ (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4") -+ (set_attr "neon_type" "*,*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") -+ (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*") -+ (set_attr "neg_pool_range" "*,*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] - ) + (define_bypass 2 "11_mult5" +@@ -211,14 +213,14 @@ + ;; The same idea, then the 32-bit result is added to a 64-bit quantity. + (define_insn_reservation "11_mult6" 4 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "insn" "smlalxy")) ++ (eq_attr "type" "smlalxy")) + "e_1*2,e_2,e_3,e_wb*2") + ;; Signed 32x32 multiply, then the most significant 32 bits are extracted + ;; and are available after the memory stage. + (define_insn_reservation "11_mult7" 4 + (and (eq_attr "tune" "arm1136js,arm1136jfs") +- (eq_attr "insn" "smmul,smmulr")) ++ (eq_attr "type" "smmul,smmulr")) + "e_1*2,e_2,e_3,e_wb") -@@ -132,8 +112,8 @@ - ;; DImode moves + (define_bypass 3 "11_mult6,11_mult7" +--- a/src/gcc/config/arm/marvell-pj4.md ++++ b/src/gcc/config/arm/marvell-pj4.md +@@ -41,64 +41,68 @@ - (define_insn "*movdi_vfp" -- [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,r,w,w, Uv") -- (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))] -+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,r,w,w, Uv") -+ (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,q,r,w,w,Uvi,w"))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune != cortexa8 - && ( register_operand (operands[0], DImode) - || register_operand (operands[1], DImode)) -@@ -375,9 +355,8 @@ - " - [(set_attr "predicable" "yes") - (set_attr "type" -- "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") -+ "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg") - (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") -- (set_attr "insn" "*,*,*,*,*,*,*,*,mov") - (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*") - (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")] - ) -@@ -412,15 +391,14 @@ - } - " - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" -- "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") -+ "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg") - (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") -- (set_attr "insn" "*,*,*,*,*,*,*,*,mov") - (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*") - (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] - ) + (define_insn_reservation "pj4_alu_e1" 1 + (and (eq_attr "tune" "marvell_pj4") +- (eq_attr "type" "simple_alu_imm,alu_reg") +- (not (eq_attr "conds" "set")) +- (eq_attr "insn" "mov,mvn")) ++ (eq_attr "type" "mov_imm,mov_reg,mvn_imm,mvn_reg") ++ (not (eq_attr "conds" "set"))) + "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") -- - ;; DFmode moves + (define_insn_reservation "pj4_alu_e1_conds" 4 + (and (eq_attr "tune" "marvell_pj4") +- (eq_attr "type" "simple_alu_imm,alu_reg") +- (eq_attr "conds" "set") +- (eq_attr "insn" "mov,mvn")) ++ (eq_attr "type" "mov_imm,mov_reg,mvn_imm,mvn_reg") ++ (eq_attr "conds" "set")) + "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") - (define_insn "*movdf_vfp" -@@ -550,7 +528,7 @@ - [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") - (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] -- "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP" -+ "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP && !arm_restrict_it" - "@ - it\\t%D3\;fcpys%D3\\t%0, %2 - it\\t%d3\;fcpys%d3\\t%0, %1 -@@ -598,7 +576,7 @@ - [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") - (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] -- "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" -+ "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && !arm_restrict_it" - "@ - it\\t%D3\;fcpyd%D3\\t%P0, %P2 - it\\t%d3\;fcpyd%d3\\t%P0, %P1 -@@ -624,6 +602,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fabss%?\\t%0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "ffariths")] - ) + (define_insn_reservation "pj4_alu" 1 + (and (eq_attr "tune" "marvell_pj4") +- (eq_attr "type" "simple_alu_imm,alu_reg") +- (not (eq_attr "conds" "set")) +- (not (eq_attr "insn" "mov,mvn"))) ++ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") ++ (not (eq_attr "conds" "set"))) + "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") -@@ -633,6 +612,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fabsd%?\\t%P0, %P1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "ffarithd")] - ) + (define_insn_reservation "pj4_alu_conds" 4 + (and (eq_attr "tune" "marvell_pj4") +- (eq_attr "type" "simple_alu_imm,alu_reg") +- (eq_attr "conds" "set") +- (not (eq_attr "insn" "mov,mvn"))) ++ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") ++ (eq_attr "conds" "set")) + "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") -@@ -644,6 +624,7 @@ - fnegs%?\\t%0, %1 - eor%?\\t%0, %1, #-2147483648" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "ffariths")] - ) + (define_insn_reservation "pj4_shift" 1 + (and (eq_attr "tune" "marvell_pj4") +- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift") ++ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ ++ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg") + (not (eq_attr "conds" "set")) + (eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") -@@ -689,6 +670,7 @@ - } - " - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "length" "4,4,8") - (set_attr "type" "ffarithd")] - ) -@@ -703,6 +685,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fadds%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fadds")] - ) + (define_insn_reservation "pj4_shift_conds" 4 + (and (eq_attr "tune" "marvell_pj4") +- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift") ++ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ ++ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg") + (eq_attr "conds" "set") + (eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") + + (define_insn_reservation "pj4_alu_shift" 1 + (and (eq_attr "tune" "marvell_pj4") + (not (eq_attr "conds" "set")) +- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift")) ++ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ ++ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")) + "pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)") -@@ -713,6 +696,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "faddd%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "faddd")] - ) + (define_insn_reservation "pj4_alu_shift_conds" 4 + (and (eq_attr "tune" "marvell_pj4") + (eq_attr "conds" "set") +- (eq_attr "type" "alu_shift,alu_shift_reg,simple_alu_shift")) ++ (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ ++ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")) + "pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)") -@@ -724,6 +708,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fsubs%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fadds")] - ) + (define_bypass 2 "pj4_alu_shift,pj4_shift" + "pj4_ir_mul,pj4_ir_div,pj4_core_to_vfp") -@@ -734,6 +719,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fsubd%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "faddd")] - ) + (define_insn_reservation "pj4_ir_mul" 3 +- (and (eq_attr "tune" "marvell_pj4") (eq_attr "type" "mult")) "pj4_is,pj4_mul,nothing*2,pj4_cp") ++ (and (eq_attr "tune" "marvell_pj4") ++ (ior (eq_attr "mul32" "yes") ++ (eq_attr "mul64" "yes"))) ++ "pj4_is,pj4_mul,nothing*2,pj4_cp") -@@ -747,6 +733,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fdivs%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fdivs")] - ) + (define_insn_reservation "pj4_ir_div" 20 +- (and (eq_attr "tune" "marvell_pj4") (eq_attr "insn" "udiv,sdiv")) "pj4_is,pj4_div*19,pj4_cp") ++ (and (eq_attr "tune" "marvell_pj4") ++ (eq_attr "type" "udiv,sdiv")) "pj4_is,pj4_div*19,pj4_cp") -@@ -757,6 +744,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fdivd%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fdivd")] - ) + ;; Branches and calls. -@@ -770,6 +758,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fmuls%?\\t%0, %1, %2" +--- a/src/gcc/config/arm/thumb2.md ++++ b/src/gcc/config/arm/thumb2.md +@@ -60,105 +60,230 @@ + "TARGET_THUMB2" + "bic%?\\t%0, %1, %2%S4" [(set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") - (set_attr "type" "fmuls")] + (set_attr "shift" "2") +- (set_attr "type" "alu_shift")] ++ (set_attr "type" "arlo_shift")] ) -@@ -780,6 +769,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fmuld%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmuld")] +-(define_insn "*thumb2_smaxsi3" +- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +- (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") +- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ++;; We use the '0' constraint for operand 1 because reload should ++;; be smart enough to generate an appropriate move for the r/r/r case. ++(define_insn_and_split "*thumb2_smaxsi3" ++ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") ++ (smax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") ++ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_THUMB2" +- "@ +- cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2 +- cmp\\t%1, %2\;it\\tge\;movge\\t%0, %1 +- cmp\\t%1, %2\;ite\\tge\;movge\\t%0, %1\;movlt\\t%0, %2" ++ "TARGET_THUMB2" ++ "#" ++ ; cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2 ++ "TARGET_THUMB2 && reload_completed" ++ [(set (reg:CC CC_REGNUM) ++ (compare:CC (match_dup 1) (match_dup 2))) ++ (cond_exec (lt:SI (reg:CC CC_REGNUM) (const_int 0)) ++ (set (match_dup 0) ++ (match_dup 2)))] ++ "" + [(set_attr "conds" "clob") +- (set_attr "length" "10,10,14")] ++ (set_attr "enabled_for_depr_it" "yes,yes,no") ++ (set_attr "length" "6,6,10")] ) -@@ -790,6 +780,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fnmuls%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmuls")] +-(define_insn "*thumb2_sminsi3" +- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +- (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") +- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ++(define_insn_and_split "*thumb2_sminsi3" ++ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") ++ (smin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") ++ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" +- "@ +- cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2 +- cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %1 +- cmp\\t%1, %2\;ite\\tlt\;movlt\\t%0, %1\;movge\\t%0, %2" ++ "#" ++ ; cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2 ++ "TARGET_THUMB2 && reload_completed" ++ [(set (reg:CC CC_REGNUM) ++ (compare:CC (match_dup 1) (match_dup 2))) ++ (cond_exec (ge:SI (reg:CC CC_REGNUM) (const_int 0)) ++ (set (match_dup 0) ++ (match_dup 2)))] ++ "" + [(set_attr "conds" "clob") +- (set_attr "length" "10,10,14")] ++ (set_attr "enabled_for_depr_it" "yes,yes,no") ++ (set_attr "length" "6,6,10")] ) -@@ -800,6 +791,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fnmuld%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmuld")] +-(define_insn "*thumb32_umaxsi3" +- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +- (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") +- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) +- (clobber (reg:CC CC_REGNUM))] ++(define_insn_and_split "*thumb32_umaxsi3" ++ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") ++ (umax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") ++ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) ++ (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" +- "@ +- cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2 +- cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %1 +- cmp\\t%1, %2\;ite\\tcs\;movcs\\t%0, %1\;movcc\\t%0, %2" ++ "#" ++ ; cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2 ++ "TARGET_THUMB2 && reload_completed" ++ [(set (reg:CC CC_REGNUM) ++ (compare:CC (match_dup 1) (match_dup 2))) ++ (cond_exec (ltu:SI (reg:CC CC_REGNUM) (const_int 0)) ++ (set (match_dup 0) ++ (match_dup 2)))] ++ "" + [(set_attr "conds" "clob") +- (set_attr "length" "10,10,14")] ++ (set_attr "length" "6,6,10") ++ (set_attr "enabled_for_depr_it" "yes,yes,no")] ) -@@ -815,6 +807,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fmacs%?\\t%0, %2, %3" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacs")] +-(define_insn "*thumb2_uminsi3" +- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +- (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") +- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ++(define_insn_and_split "*thumb2_uminsi3" ++ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") ++ (umin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0") ++ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" +- "@ +- cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2 +- cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %1 +- cmp\\t%1, %2\;ite\\tcc\;movcc\\t%0, %1\;movcs\\t%0, %2" ++ "#" ++ ; cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2 ++ "TARGET_THUMB2 && reload_completed" ++ [(set (reg:CC CC_REGNUM) ++ (compare:CC (match_dup 1) (match_dup 2))) ++ (cond_exec (geu:SI (reg:CC CC_REGNUM) (const_int 0)) ++ (set (match_dup 0) ++ (match_dup 2)))] ++ "" + [(set_attr "conds" "clob") +- (set_attr "length" "10,10,14")] ++ (set_attr "length" "6,6,10") ++ (set_attr "enabled_for_depr_it" "yes,yes,no")] ) -@@ -826,6 +819,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fmacd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacd")] + ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands. +-(define_insn "*thumb2_negdi2" ++(define_insn_and_split "*thumb2_negdi2" + [(set (match_operand:DI 0 "s_register_operand" "=&r,r") + (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" +- "negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1" ++ "#" ; negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1 ++ "&& reload_completed" ++ [(parallel [(set (reg:CC CC_REGNUM) ++ (compare:CC (const_int 0) (match_dup 1))) ++ (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) ++ (set (match_dup 2) (minus:SI (minus:SI (match_dup 3) ++ (ashift:SI (match_dup 3) ++ (const_int 1))) ++ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] ++ { ++ operands[2] = gen_highpart (SImode, operands[0]); ++ operands[0] = gen_lowpart (SImode, operands[0]); ++ operands[3] = gen_highpart (SImode, operands[1]); ++ operands[1] = gen_lowpart (SImode, operands[1]); ++ } + [(set_attr "conds" "clob") + (set_attr "length" "8")] ) -@@ -838,6 +832,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fmscs%?\\t%0, %2, %3" - [(set_attr "predicable" "yes") +-(define_insn "*thumb2_abssi2" +- [(set (match_operand:SI 0 "s_register_operand" "=r,&r") +- (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) ++(define_insn_and_split "*thumb2_abssi2" ++ [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r") ++ (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" +- "@ +- cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0 +- eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31" +- [(set_attr "conds" "clob,*") ++ "#" ++ ; eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31 ++ ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0 ++ ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0 ++ "&& reload_completed" ++ [(const_int 0)] ++ { ++ if (REGNO(operands[0]) == REGNO(operands[1])) ++ { ++ rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); ++ ++ emit_insn (gen_rtx_SET (VOIDmode, ++ cc_reg, ++ gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, ++ (gen_rtx_LT (SImode, ++ cc_reg, ++ const0_rtx)), ++ (gen_rtx_SET (VOIDmode, ++ operands[0], ++ (gen_rtx_MINUS (SImode, ++ const0_rtx, ++ operands[1])))))); ++ } ++ else ++ { ++ emit_insn (gen_rtx_SET (VOIDmode, ++ operands[0], ++ gen_rtx_XOR (SImode, ++ gen_rtx_ASHIFTRT (SImode, ++ operands[1], ++ GEN_INT (31)), ++ operands[1]))); ++ emit_insn (gen_rtx_SET (VOIDmode, ++ operands[0], ++ gen_rtx_MINUS (SImode, ++ operands[0], ++ gen_rtx_ASHIFTRT (SImode, ++ operands[1], ++ GEN_INT (31))))); ++ } ++ DONE; ++ } ++ [(set_attr "conds" "*,clob,clob") + (set_attr "shift" "1") +- (set_attr "predicable" "no, yes") ++ (set_attr "predicable" "yes,no,no") + (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacs")] ++ (set_attr "enabled_for_depr_it" "yes,yes,no") + (set_attr "ce_count" "2") +- (set_attr "length" "10,8")] ++ (set_attr "length" "8,6,10")] ) -@@ -849,6 +844,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fmscd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") +-(define_insn "*thumb2_neg_abssi2" +- [(set (match_operand:SI 0 "s_register_operand" "=r,&r") +- (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) ++(define_insn_and_split "*thumb2_neg_abssi2" ++ [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r") ++ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0")))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" +- "@ +- cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0 +- eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31" +- [(set_attr "conds" "clob,*") ++ "#" ++ ; eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31 ++ ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0 ++ ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0 ++ "&& reload_completed" ++ [(const_int 0)] ++ { ++ if (REGNO(operands[0]) == REGNO(operands[1])) ++ { ++ rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); ++ ++ emit_insn (gen_rtx_SET (VOIDmode, ++ cc_reg, ++ gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, ++ (gen_rtx_GT (SImode, ++ cc_reg, ++ const0_rtx)), ++ (gen_rtx_SET (VOIDmode, ++ operands[0], ++ (gen_rtx_MINUS (SImode, ++ const0_rtx, ++ operands[1])))))); ++ } ++ else ++ { ++ emit_insn (gen_rtx_SET (VOIDmode, ++ operands[0], ++ gen_rtx_XOR (SImode, ++ gen_rtx_ASHIFTRT (SImode, ++ operands[1], ++ GEN_INT (31)), ++ operands[1]))); ++ emit_insn (gen_rtx_SET (VOIDmode, ++ operands[0], ++ gen_rtx_MINUS (SImode, ++ gen_rtx_ASHIFTRT (SImode, ++ operands[1], ++ GEN_INT (31)), ++ operands[0]))); ++ } ++ DONE; ++ } ++ [(set_attr "conds" "*,clob,clob") + (set_attr "shift" "1") +- (set_attr "predicable" "no, yes") ++ (set_attr "predicable" "yes,no,no") ++ (set_attr "enabled_for_depr_it" "yes,yes,no") + (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacd")] + (set_attr "ce_count" "2") +- (set_attr "length" "10,8")] ++ (set_attr "length" "8,6,10")] ) -@@ -861,6 +857,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fnmacs%?\\t%0, %2, %3" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacs")] + ;; We have two alternatives here for memory loads (and similarly for stores) +@@ -167,8 +292,8 @@ + ;; regs. The high register alternatives are not taken into account when + ;; choosing register preferences in order to reflect their expense. + (define_insn "*thumb2_movsi_insn" +- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l ,*hk,m,*m") +- (match_operand:SI 1 "general_operand" "rk ,I,K,j,mi,*mi,l,*hk"))] ++ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,l ,*hk,m,*m") ++ (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk"))] + "TARGET_THUMB2 && ! TARGET_IWMMXT + && !(TARGET_HARD_FLOAT && TARGET_VFP) + && ( register_operand (operands[0], SImode) +@@ -176,16 +301,19 @@ + "@ + mov%?\\t%0, %1 + mov%?\\t%0, %1 ++ mov%?\\t%0, %1 + mvn%?\\t%0, #%B1 + movw%?\\t%0, %1 + ldr%?\\t%0, %1 + ldr%?\\t%0, %1 + str%?\\t%1, %0 + str%?\\t%1, %0" +- [(set_attr "type" "*,*,simple_alu_imm,*,load1,load1,store1,store1") ++ [(set_attr "type" "*,arlo_imm,arlo_imm,arlo_imm,*,load1,load1,store1,store1") ++ (set_attr "length" "2,4,2,4,4,4,4,4,4") + (set_attr "predicable" "yes") +- (set_attr "pool_range" "*,*,*,*,1018,4094,*,*") +- (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")] ++ (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no") ++ (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*") ++ (set_attr "neg_pool_range" "*,*,*,*,*,0,0,*,*")] ) -@@ -872,6 +869,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fnmacd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacd")] + (define_insn "tls_load_dot_plus_four" +@@ -223,6 +351,21 @@ + (set_attr "neg_pool_range" "*,*,*,250")] ) -@@ -886,6 +884,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fnmscs%?\\t%0, %2, %3" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacs")] ++(define_insn "*thumb2_storewb_pairsi" ++ [(set (match_operand:SI 0 "register_operand" "=&kr") ++ (plus:SI (match_operand:SI 1 "register_operand" "0") ++ (match_operand:SI 2 "const_int_operand" "n"))) ++ (set (mem:SI (plus:SI (match_dup 0) (match_dup 2))) ++ (match_operand:SI 3 "register_operand" "r")) ++ (set (mem:SI (plus:SI (match_dup 0) ++ (match_operand:SI 5 "const_int_operand" "n"))) ++ (match_operand:SI 4 "register_operand" "r"))] ++ "TARGET_THUMB2 ++ && INTVAL (operands[5]) == INTVAL (operands[2]) + 4" ++ "strd\\t%3, %4, [%0, %2]!" ++ [(set_attr "type" "store2")] ++) ++ + (define_insn "*thumb2_cmpsi_neg_shiftsi" + [(set (reg:CC CC_REGNUM) + (compare:CC (match_operand:SI 0 "s_register_operand" "r") +@@ -233,57 +376,170 @@ + "cmn%?\\t%0, %1%S3" + [(set_attr "conds" "set") + (set_attr "shift" "1") +- (set_attr "type" "alu_shift")] ++ (set_attr "type" "arlo_shift")] ) -@@ -898,6 +897,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fnmscd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fmacd")] +-(define_insn "*thumb2_mov_scc" +- [(set (match_operand:SI 0 "s_register_operand" "=r") ++(define_insn_and_split "*thumb2_mov_scc" ++ [(set (match_operand:SI 0 "s_register_operand" "=l,r") + (match_operator:SI 1 "arm_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)]))] + "TARGET_THUMB2" +- "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1" ++ "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1" ++ "TARGET_THUMB2" ++ [(set (match_dup 0) ++ (if_then_else:SI (match_dup 1) ++ (const_int 1) ++ (const_int 0)))] ++ "" + [(set_attr "conds" "use") +- (set_attr "length" "10")] ++ (set_attr "enabled_for_depr_it" "yes,no") ++ (set_attr "length" "8,10")] ) -@@ -911,6 +911,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" - "vfma%?.\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "ffma")] +-(define_insn "*thumb2_mov_negscc" ++(define_insn_and_split "*thumb2_mov_negscc" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (neg:SI (match_operator:SI 1 "arm_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)])))] ++ "TARGET_THUMB2 && !arm_restrict_it" ++ "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" + "TARGET_THUMB2" +- "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" ++ [(set (match_dup 0) ++ (if_then_else:SI (match_dup 1) ++ (match_dup 3) ++ (const_int 0)))] ++ { ++ operands[3] = GEN_INT (~0); ++ } + [(set_attr "conds" "use") + (set_attr "length" "10")] ) -@@ -923,6 +924,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" - "vfms%?.\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "ffma")] +-(define_insn "*thumb2_mov_notscc" ++(define_insn_and_split "*thumb2_mov_negscc_strict_it" ++ [(set (match_operand:SI 0 "low_register_operand" "=l") ++ (neg:SI (match_operator:SI 1 "arm_comparison_operator" ++ [(match_operand 2 "cc_register" "") (const_int 0)])))] ++ "TARGET_THUMB2 && arm_restrict_it" ++ "#" ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\" ++ "&& reload_completed" ++ [(set (match_dup 0) ++ (match_dup 3)) ++ (cond_exec (match_dup 4) ++ (set (match_dup 0) ++ (const_int 0)))] ++ { ++ operands[3] = GEN_INT (~0); ++ enum machine_mode mode = GET_MODE (operands[2]); ++ enum rtx_code rc = GET_CODE (operands[1]); ++ ++ if (mode == CCFPmode || mode == CCFPEmode) ++ rc = reverse_condition_maybe_unordered (rc); ++ else ++ rc = reverse_condition (rc); ++ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); ++ ++ } ++ [(set_attr "conds" "use") ++ (set_attr "length" "8")] ++) ++ ++(define_insn_and_split "*thumb2_mov_notscc" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (not:SI (match_operator:SI 1 "arm_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)])))] ++ "TARGET_THUMB2 && !arm_restrict_it" ++ "#" ; "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1" + "TARGET_THUMB2" +- "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1" ++ [(set (match_dup 0) ++ (if_then_else:SI (match_dup 1) ++ (match_dup 3) ++ (match_dup 4)))] ++ { ++ operands[3] = GEN_INT (~1); ++ operands[4] = GEN_INT (~0); ++ } + [(set_attr "conds" "use") + (set_attr "length" "10")] ) -@@ -934,6 +936,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" - "vfnms%?.\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "ffma")] +-(define_insn "*thumb2_movsicc_insn" +- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") ++(define_insn_and_split "*thumb2_mov_notscc_strict_it" ++ [(set (match_operand:SI 0 "low_register_operand" "=l") ++ (not:SI (match_operator:SI 1 "arm_comparison_operator" ++ [(match_operand 2 "cc_register" "") (const_int 0)])))] ++ "TARGET_THUMB2 && arm_restrict_it" ++ "#" ; "mvn %0, #0 ; it%d1 ; lsl%d1 %0, %0, #1" ++ "&& reload_completed" ++ [(set (match_dup 0) ++ (match_dup 3)) ++ (cond_exec (match_dup 4) ++ (set (match_dup 0) ++ (ashift:SI (match_dup 0) ++ (const_int 1))))] ++ { ++ operands[3] = GEN_INT (~0); ++ operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]), ++ VOIDmode, operands[2], const0_rtx); ++ } ++ [(set_attr "conds" "use") ++ (set_attr "length" "8")] ++) ++ ++(define_insn_and_split "*thumb2_movsicc_insn" ++ [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r,r,r,r,r,r,r,r") + (if_then_else:SI + (match_operator 3 "arm_comparison_operator" + [(match_operand 4 "cc_register" "") (const_int 0)]) +- (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") +- (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] ++ (match_operand:SI 1 "arm_not_operand" "0 ,lPy,0 ,0,rI,K,rI,rI,K ,K,r") ++ (match_operand:SI 2 "arm_not_operand" "lPy,0 ,rI,K,0 ,0,rI,K ,rI,K,r")))] + "TARGET_THUMB2" + "@ + it\\t%D3\;mov%D3\\t%0, %2 ++ it\\t%d3\;mov%d3\\t%0, %1 ++ it\\t%D3\;mov%D3\\t%0, %2 + it\\t%D3\;mvn%D3\\t%0, #%B2 + it\\t%d3\;mov%d3\\t%0, %1 + it\\t%d3\;mvn%d3\\t%0, #%B1 +- ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 +- ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 +- ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 +- ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" +- [(set_attr "length" "6,6,6,6,10,10,10,10") ++ # ++ # ++ # ++ # ++ #" ++ ; alt 6: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 ++ ; alt 7: ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 ++ ; alt 8: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 ++ ; alt 9: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2 ++ ; alt 10: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2 ++ "&& reload_completed" ++ [(const_int 0)] ++ { ++ enum rtx_code rev_code; ++ enum machine_mode mode; ++ rtx rev_cond; ++ ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, ++ operands[3], ++ gen_rtx_SET (VOIDmode, ++ operands[0], ++ operands[1]))); ++ rev_code = GET_CODE (operands[3]); ++ mode = GET_MODE (operands[4]); ++ if (mode == CCFPmode || mode == CCFPEmode) ++ rev_code = reverse_condition_maybe_unordered (rev_code); ++ else ++ rev_code = reverse_condition (rev_code); ++ ++ rev_cond = gen_rtx_fmt_ee (rev_code, ++ VOIDmode, ++ gen_rtx_REG (mode, CC_REGNUM), ++ const0_rtx); ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, ++ rev_cond, ++ gen_rtx_SET (VOIDmode, ++ operands[0], ++ operands[2]))); ++ DONE; ++ } ++ [(set_attr "length" "4,4,6,6,6,6,10,10,10,10,6") ++ (set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,yes") + (set_attr "conds" "use")] ) -@@ -946,6 +949,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" - "vfnma%?.\\t%0, %1, %2" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "ffma")] - ) +@@ -333,28 +589,74 @@ + ;; addresses will have the thumb bit set correctly. -@@ -958,6 +962,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fcvtds%?\\t%P0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] - ) -@@ -967,6 +972,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fcvtsd%?\\t%0, %P1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] +-(define_insn "*thumb2_and_scc" +- [(set (match_operand:SI 0 "s_register_operand" "=r") ++(define_insn_and_split "*thumb2_and_scc" ++ [(set (match_operand:SI 0 "s_register_operand" "=Ts") + (and:SI (match_operator:SI 1 "arm_comparison_operator" +- [(match_operand 3 "cc_register" "") (const_int 0)]) +- (match_operand:SI 2 "s_register_operand" "r")))] ++ [(match_operand 2 "cc_register" "") (const_int 0)]) ++ (match_operand:SI 3 "s_register_operand" "r")))] + "TARGET_THUMB2" +- "ite\\t%D1\;mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1" ++ "#" ; "and\\t%0, %3, #1\;it\\t%D1\;mov%D1\\t%0, #0" ++ "&& reload_completed" ++ [(set (match_dup 0) ++ (and:SI (match_dup 3) (const_int 1))) ++ (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))] ++ { ++ enum machine_mode mode = GET_MODE (operands[2]); ++ enum rtx_code rc = GET_CODE (operands[1]); ++ ++ if (mode == CCFPmode || mode == CCFPEmode) ++ rc = reverse_condition_maybe_unordered (rc); ++ else ++ rc = reverse_condition (rc); ++ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); ++ } + [(set_attr "conds" "use") +- (set_attr "length" "10")] ++ (set (attr "length") (if_then_else (match_test "arm_restrict_it") ++ (const_int 8) ++ (const_int 10)))] ) -@@ -976,6 +982,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" - "vcvtb%?.f32.f16\\t%0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] +-(define_insn "*thumb2_ior_scc" ++(define_insn_and_split "*thumb2_ior_scc" + [(set (match_operand:SI 0 "s_register_operand" "=r,r") ++ (ior:SI (match_operator:SI 1 "arm_comparison_operator" ++ [(match_operand 2 "cc_register" "") (const_int 0)]) ++ (match_operand:SI 3 "s_register_operand" "0,?r")))] ++ "TARGET_THUMB2 && !arm_restrict_it" ++ "@ ++ it\\t%d1\;orr%d1\\t%0, %3, #1 ++ #" ++ ; alt 1: ite\\t%D1\;mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1 ++ "&& reload_completed ++ && REGNO (operands [0]) != REGNO (operands[3])" ++ [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3))) ++ (cond_exec (match_dup 4) (set (match_dup 0) ++ (ior:SI (match_dup 3) (const_int 1))))] ++ { ++ enum machine_mode mode = GET_MODE (operands[2]); ++ enum rtx_code rc = GET_CODE (operands[1]); ++ ++ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); ++ if (mode == CCFPmode || mode == CCFPEmode) ++ rc = reverse_condition_maybe_unordered (rc); ++ else ++ rc = reverse_condition (rc); ++ operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); ++ } ++ [(set_attr "conds" "use") ++ (set_attr "length" "6,10")] ++) ++ ++(define_insn "*thumb2_ior_scc_strict_it" ++ [(set (match_operand:SI 0 "s_register_operand" "=l,l") + (ior:SI (match_operator:SI 2 "arm_comparison_operator" + [(match_operand 3 "cc_register" "") (const_int 0)]) +- (match_operand:SI 1 "s_register_operand" "0,?r")))] +- "TARGET_THUMB2" ++ (match_operand:SI 1 "s_register_operand" "0,?l")))] ++ "TARGET_THUMB2 && arm_restrict_it" + "@ +- it\\t%d2\;orr%d2\\t%0, %1, #1 +- ite\\t%D2\;mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1" ++ it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1 ++ mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1" + [(set_attr "conds" "use") +- (set_attr "length" "6,10")] ++ (set_attr "length" "8")] ) -@@ -985,6 +992,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" - "vcvtb%?.f16.f32\\t%0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (define_insn "*thumb2_cond_move" +@@ -384,13 +686,20 @@ + output_asm_insn (\"it\\t%D4\", operands); + break; + case 2: +- output_asm_insn (\"ite\\t%D4\", operands); ++ if (arm_restrict_it) ++ output_asm_insn (\"it\\t%D4\", operands); ++ else ++ output_asm_insn (\"ite\\t%D4\", operands); + break; + default: + abort(); + } + if (which_alternative != 0) +- output_asm_insn (\"mov%D4\\t%0, %1\", operands); ++ { ++ output_asm_insn (\"mov%D4\\t%0, %1\", operands); ++ if (arm_restrict_it && which_alternative == 2) ++ output_asm_insn (\"it\\t%d4\", operands); ++ } + if (which_alternative != 1) + output_asm_insn (\"mov%d4\\t%0, %2\", operands); + return \"\"; +@@ -407,7 +716,7 @@ + (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) + (match_operand:SI 1 "s_register_operand" "0,?r")])) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_THUMB2" ++ "TARGET_THUMB2 && !arm_restrict_it" + "* + if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) + return \"%i5\\t%0, %1, %2, lsr #31\"; +@@ -436,9 +745,78 @@ + (set_attr "length" "14")] ) -@@ -994,6 +1002,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "ftosizs%?\\t%0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] ++(define_insn_and_split "*thumb2_cond_arith_strict_it" ++ [(set (match_operand:SI 0 "s_register_operand" "=l") ++ (match_operator:SI 5 "shiftable_operator_strict_it" ++ [(match_operator:SI 4 "arm_comparison_operator" ++ [(match_operand:SI 2 "s_register_operand" "r") ++ (match_operand:SI 3 "arm_rhs_operand" "rI")]) ++ (match_operand:SI 1 "s_register_operand" "0")])) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_THUMB2 && arm_restrict_it" ++ "#" ++ "&& reload_completed" ++ [(const_int 0)] ++ { ++ if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) ++ { ++ /* %i5 %0, %1, %2, lsr #31 */ ++ rtx shifted_op = gen_rtx_LSHIFTRT (SImode, operands[2], GEN_INT (31)); ++ rtx op = NULL_RTX; ++ ++ switch (GET_CODE (operands[5])) ++ { ++ case AND: ++ op = gen_rtx_AND (SImode, shifted_op, operands[1]); ++ break; ++ case PLUS: ++ op = gen_rtx_PLUS (SImode, shifted_op, operands[1]); ++ break; ++ default: gcc_unreachable (); ++ } ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], op)); ++ DONE; ++ } ++ ++ /* "cmp %2, %3" */ ++ emit_insn (gen_rtx_SET (VOIDmode, ++ gen_rtx_REG (CCmode, CC_REGNUM), ++ gen_rtx_COMPARE (CCmode, operands[2], operands[3]))); ++ ++ if (GET_CODE (operands[5]) == AND) ++ { ++ /* %i5 %0, %1, #1 ++ it%D4 ++ mov%D4 %0, #0 */ ++ enum rtx_code rc = reverse_condition (GET_CODE (operands[4])); ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_rtx_AND (SImode, operands[1], GEN_INT (1)))); ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, ++ gen_rtx_fmt_ee (rc, VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx), ++ gen_rtx_SET (VOIDmode, operands[0], const0_rtx))); ++ DONE; ++ } ++ else ++ { ++ /* it\\t%d4 ++ %i5%d4\\t%0, %1, #1 */ ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, gen_rtx_fmt_ee (GET_CODE (operands[4]), ++ VOIDmode, ++ gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx), ++ gen_rtx_SET(VOIDmode, operands[0], ++ gen_rtx_PLUS (SImode, ++ operands[1], ++ GEN_INT (1))))); ++ DONE; ++ } ++ FAIL; ++ } ++ [(set_attr "conds" "clob") ++ (set_attr "length" "12")] ++) ++ + (define_insn "*thumb2_cond_sub" +- [(set (match_operand:SI 0 "s_register_operand" "=r,r") +- (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") ++ [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") ++ (minus:SI (match_operand:SI 1 "s_register_operand" "0,?Ts") + (match_operator:SI 4 "arm_comparison_operator" + [(match_operand:SI 2 "s_register_operand" "r,r") + (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) +@@ -448,8 +826,16 @@ + output_asm_insn (\"cmp\\t%2, %3\", operands); + if (which_alternative != 0) + { +- output_asm_insn (\"ite\\t%D4\", operands); +- output_asm_insn (\"mov%D4\\t%0, %1\", operands); ++ if (arm_restrict_it) ++ { ++ output_asm_insn (\"mov\\t%0, %1\", operands); ++ output_asm_insn (\"it\\t%d4\", operands); ++ } ++ else ++ { ++ output_asm_insn (\"ite\\t%D4\", operands); ++ output_asm_insn (\"mov%D4\\t%0, %1\", operands); ++ } + } + else + output_asm_insn (\"it\\t%d4\", operands); +@@ -459,37 +845,82 @@ + (set_attr "length" "10,14")] ) -@@ -1003,6 +1012,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "ftosizd%?\\t%0, %P1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] - ) +-(define_insn "*thumb2_negscc" +- [(set (match_operand:SI 0 "s_register_operand" "=r") ++(define_insn_and_split "*thumb2_negscc" ++ [(set (match_operand:SI 0 "s_register_operand" "=Ts") + (neg:SI (match_operator 3 "arm_comparison_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_rhs_operand" "rI")]))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" +- "* +- if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) +- return \"asr\\t%0, %1, #31\"; ++ "#" ++ "&& reload_completed" ++ [(const_int 0)] ++ { ++ rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); -@@ -1013,6 +1023,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "ftouizs%?\\t%0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] - ) +- if (GET_CODE (operands[3]) == NE) +- return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\"; ++ if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) ++ { ++ /* Emit asr\\t%0, %1, #31 */ ++ emit_insn (gen_rtx_SET (VOIDmode, ++ operands[0], ++ gen_rtx_ASHIFTRT (SImode, ++ operands[1], ++ GEN_INT (31)))); ++ DONE; ++ } ++ else if (GET_CODE (operands[3]) == NE && !arm_restrict_it) ++ { ++ /* Emit subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0 */ ++ if (CONST_INT_P (operands[2])) ++ emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2], ++ GEN_INT (- INTVAL (operands[2])))); ++ else ++ emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2])); -@@ -1022,6 +1033,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "ftouizd%?\\t%0, %P1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] +- output_asm_insn (\"cmp\\t%1, %2\", operands); +- output_asm_insn (\"ite\\t%D3\", operands); +- output_asm_insn (\"mov%D3\\t%0, #0\", operands); +- return \"mvn%d3\\t%0, #0\"; +- " ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, ++ gen_rtx_NE (SImode, ++ cc_reg, ++ const0_rtx), ++ gen_rtx_SET (SImode, ++ operands[0], ++ GEN_INT (~0)))); ++ DONE; ++ } ++ else ++ { ++ /* Emit: cmp\\t%1, %2\;mvn\\t%0, #0\;it\\t%D3\;mov%D3\\t%0, #0\;*/ ++ enum rtx_code rc = reverse_condition (GET_CODE (operands[3])); ++ enum machine_mode mode = SELECT_CC_MODE (rc, operands[1], operands[2]); ++ rtx tmp1 = gen_rtx_REG (mode, CC_REGNUM); ++ ++ emit_insn (gen_rtx_SET (VOIDmode, ++ cc_reg, ++ gen_rtx_COMPARE (CCmode, operands[1], operands[2]))); ++ ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], GEN_INT (~0))); ++ ++ emit_insn (gen_rtx_COND_EXEC (VOIDmode, ++ gen_rtx_fmt_ee (rc, ++ VOIDmode, ++ tmp1, ++ const0_rtx), ++ gen_rtx_SET (VOIDmode, operands[0], const0_rtx))); ++ DONE; ++ } ++ FAIL; ++ } + [(set_attr "conds" "clob") + (set_attr "length" "14")] ) -@@ -1032,6 +1044,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fsitos%?\\t%0, %1" - [(set_attr "predicable" "yes") + (define_insn "*thumb2_movcond" +- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ++ [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts") + (if_then_else:SI + (match_operator 5 "arm_comparison_operator" + [(match_operand:SI 3 "s_register_operand" "r,r,r") + (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) +- (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") +- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ++ (match_operand:SI 1 "arm_rhs_operand" "0,TsI,?TsI") ++ (match_operand:SI 2 "arm_rhs_operand" "TsI,0,TsI"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2" + "* +@@ -544,12 +975,18 @@ + output_asm_insn (\"it\\t%d5\", operands); + break; + case 2: +- output_asm_insn (\"ite\\t%d5\", operands); ++ if (arm_restrict_it) ++ { ++ output_asm_insn (\"mov\\t%0, %1\", operands); ++ output_asm_insn (\"it\\t%D5\", operands); ++ } ++ else ++ output_asm_insn (\"ite\\t%d5\", operands); + break; + default: + abort(); + } +- if (which_alternative != 0) ++ if (which_alternative != 0 && !(arm_restrict_it && which_alternative == 2)) + output_asm_insn (\"mov%d5\\t%0, %1\", operands); + if (which_alternative != 1) + output_asm_insn (\"mov%D5\\t%0, %2\", operands); +@@ -570,8 +1007,9 @@ + "@ + sxtb%?\\t%0, %1 + ldr%(sb%)\\t%0, %1" +- [(set_attr "type" "simple_alu_shift,load_byte") ++ [(set_attr "type" "extend,load_byte") + (set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "pool_range" "*,4094") + (set_attr "neg_pool_range" "*,250")] ) - -@@ -1041,6 +1054,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fsitod%?\\t%P0, %1" - [(set_attr "predicable" "yes") +@@ -583,8 +1021,9 @@ + "@ + uxth%?\\t%0, %1 + ldr%(h%)\\t%0, %1" +- [(set_attr "type" "simple_alu_shift,load_byte") ++ [(set_attr "type" "extend,load_byte") + (set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "pool_range" "*,4094") + (set_attr "neg_pool_range" "*,250")] ) - -@@ -1051,6 +1065,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fuitos%?\\t%0, %1" - [(set_attr "predicable" "yes") +@@ -596,8 +1035,9 @@ + "@ + uxtb%(%)\\t%0, %1 + ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2" +- [(set_attr "type" "simple_alu_shift,load_byte") ++ [(set_attr "type" "extend,load_byte") + (set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "pool_range" "*,4094") + (set_attr "neg_pool_range" "*,250")] ) - -@@ -1060,6 +1075,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fuitod%?\\t%P0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] +@@ -688,8 +1128,8 @@ + (set_attr "shift" "1") + (set_attr "length" "2") + (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") +- (const_string "alu_shift") +- (const_string "alu_shift_reg")))] ++ (const_string "arlo_shift") ++ (const_string "arlo_shift_reg")))] ) -@@ -1072,6 +1088,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fsqrts%?\\t%0, %1" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fdivs")] + (define_insn "*thumb2_mov_shortim" +@@ -811,7 +1251,7 @@ + " + [(set_attr "conds" "set") + (set_attr "length" "2,2,4,4") +- (set_attr "type" "simple_alu_imm,*,simple_alu_imm,*")] ++ (set_attr "type" "arlo_imm,*,arlo_imm,*")] ) -@@ -1081,6 +1098,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" - "fsqrtd%?\\t%P0, %P1" + (define_insn "*thumb2_mulsi_short" +@@ -823,7 +1263,7 @@ + "mul%!\\t%0, %2, %0" [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fdivd")] - ) + (set_attr "length" "2") +- (set_attr "insn" "muls")]) ++ (set_attr "type" "muls")]) -@@ -1168,6 +1186,7 @@ - fcmps%?\\t%0, %1 - fcmpzs%?\\t%0" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fcmps")] - ) + (define_insn "*thumb2_mulsi_short_compare0" + [(set (reg:CC_NOOV CC_REGNUM) +@@ -836,7 +1276,7 @@ + "TARGET_THUMB2 && optimize_size" + "muls\\t%0, %2, %0" + [(set_attr "length" "2") +- (set_attr "insn" "muls")]) ++ (set_attr "type" "muls")]) -@@ -1180,6 +1199,7 @@ - fcmpes%?\\t%0, %1 - fcmpezs%?\\t%0" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fcmps")] - ) + (define_insn "*thumb2_mulsi_short_compare0_scratch" + [(set (reg:CC_NOOV CC_REGNUM) +@@ -848,7 +1288,7 @@ + "TARGET_THUMB2 && optimize_size" + "muls\\t%0, %2, %0" + [(set_attr "length" "2") +- (set_attr "insn" "muls")]) ++ (set_attr "type" "muls")]) -@@ -1192,6 +1212,7 @@ - fcmpd%?\\t%P0, %P1 - fcmpzd%?\\t%P0" - [(set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no") - (set_attr "type" "fcmpd")] + (define_insn "*thumb2_cbz" + [(set (pc) (if_then_else +@@ -922,7 +1362,8 @@ + (match_operand:SI 1 "s_register_operand" "r")))] + "TARGET_THUMB2" + "orn%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")] ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")] ) -@@ -1204,6 +1225,7 @@ - fcmped%?\\t%P0, %P1 - fcmpezd%?\\t%P0" + (define_insn "*orsi_not_shiftsi_si" +@@ -934,8 +1375,9 @@ + "TARGET_THUMB2" + "orn%?\\t%0, %1, %2%S4" [(set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") - (set_attr "type" "fcmpd")] - ) - -@@ -1264,6 +1286,7 @@ - "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 " - "vrint%?.\\t%0, %1" - [(set_attr "predicable" "") -+ (set_attr "predicable_short_it" "no") - (set_attr "conds" "") - (set_attr "type" "f_rint")] - ) ---- a/src/gcc/config/arm/t-linux-eabi -+++ b/src/gcc/config/arm/t-linux-eabi -@@ -18,6 +18,8 @@ - - # We do not build a Thumb multilib for Linux because the definition of - # CLEAR_INSN_CACHE in linux-gas.h does not work in Thumb mode. -+# If you set MULTILIB_OPTIONS to a non-empty value you should also set -+# MULTILIB_DEFAULTS in linux-elf.h. - MULTILIB_OPTIONS = - MULTILIB_DIRNAMES = - ---- a/src/gcc/config/arm/neon.md -+++ b/src/gcc/config/arm/neon.md -@@ -61,8 +61,7 @@ - } - } - [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*") -- (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu_reg,load2,store2") -- (set_attr "insn" "*,*,*,*,*,*,mov,*,*") -+ (set_attr "type" "*,f_stored,*,f_loadd,*,*,mov_reg,load2,store2") - (set_attr "length" "4,4,4,4,4,4,8,8,8") - (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*") - (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") -@@ -107,8 +106,7 @@ - } - [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\ - neon_mrrc,neon_mcr_2_mcrr,*,*,*") -- (set_attr "type" "*,*,*,*,*,*,alu_reg,load4,store4") -- (set_attr "insn" "*,*,*,*,*,*,mov,*,*") -+ (set_attr "type" "*,*,*,*,*,*,mov_reg,load4,store4") - (set_attr "length" "4,8,4,8,8,8,16,8,16") - (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*") - (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") -@@ -487,7 +485,7 @@ - [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*") - (set_attr "conds" "*,clob,clob,*,clob,clob,clob") - (set_attr "length" "*,8,8,*,8,8,8") -- (set_attr "arch" "nota8,*,*,onlya8,*,*,*")] -+ (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits,*,*,*")] - ) - - (define_insn "*sub3_neon" -@@ -524,7 +522,7 @@ - [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2") - (set_attr "conds" "*,clob,clob,clob,*") - (set_attr "length" "*,8,8,8,*") -- (set_attr "arch" "nota8,*,*,*,onlya8")] -+ (set_attr "arch" "neon_for_64bits,*,*,*,avoid_neon_for_64bits")] - ) - - (define_insn "*mul3_neon" -@@ -679,29 +677,6 @@ - [(set_attr "neon_type" "neon_int_1")] - ) - --(define_insn "iordi3_neon" -- [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w") -- (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0") -- (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r,w,Dl")))] -- "TARGET_NEON" --{ -- switch (which_alternative) -- { -- case 0: /* fall through */ -- case 4: return "vorr\t%P0, %P1, %P2"; -- case 1: /* fall through */ -- case 5: return neon_output_logic_immediate ("vorr", &operands[2], -- DImode, 0, VALID_NEON_QREG_MODE (DImode)); -- case 2: return "#"; -- case 3: return "#"; -- default: gcc_unreachable (); -- } --} -- [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1") -- (set_attr "length" "*,*,8,8,*,*") -- (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")] --) -- - ;; The concrete forms of the Neon immediate-logic instructions are vbic and - ;; vorr. We support the pseudo-instruction vand instead, because that - ;; corresponds to the canonical form the middle-end expects to use for -@@ -724,29 +699,6 @@ - [(set_attr "neon_type" "neon_int_1")] - ) - --(define_insn "anddi3_neon" -- [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w") -- (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0") -- (match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r,w,DL")))] -- "TARGET_NEON" --{ -- switch (which_alternative) -- { -- case 0: /* fall through */ -- case 4: return "vand\t%P0, %P1, %P2"; -- case 1: /* fall through */ -- case 5: return neon_output_logic_immediate ("vand", &operands[2], -- DImode, 1, VALID_NEON_QREG_MODE (DImode)); -- case 2: return "#"; -- case 3: return "#"; -- default: gcc_unreachable (); -- } --} -- [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1") -- (set_attr "length" "*,*,8,8,*,*") -- (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")] --) -- - (define_insn "orn3_neon" - [(set (match_operand:VDQ 0 "s_register_operand" "=w") - (ior:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w")) -@@ -828,21 +780,6 @@ - [(set_attr "neon_type" "neon_int_1")] - ) - --(define_insn "xordi3_neon" -- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w") -- (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w") -- (match_operand:DI 2 "s_register_operand" "w,r,r,w")))] -- "TARGET_NEON" -- "@ -- veor\t%P0, %P1, %P2 -- # -- # -- veor\t%P0, %P1, %P2" -- [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1") -- (set_attr "length" "*,8,8,*") -- (set_attr "arch" "nota8,*,*,onlya8")] --) -- - (define_insn "one_cmpl2" - [(set (match_operand:VDQ 0 "s_register_operand" "=w") - (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))] -@@ -1162,7 +1099,7 @@ - } - DONE; - }" -- [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8") -+ [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits") - (set_attr "opt" "*,*,speed,speed,*,*")] - ) - -@@ -1263,7 +1200,7 @@ - - DONE; - }" -- [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8") -+ [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits") - (set_attr "opt" "*,*,speed,speed,*,*")] + (set_attr "shift" "2") +- (set_attr "type" "alu_shift")] ++ (set_attr "type" "arlo_shift")] ) -@@ -3305,6 +3242,24 @@ - (const_string "neon_fp_vadd_qqq_vabs_qq")))] - ) + (define_peephole2 +--- a/src/gcc/config/arm/arm.c ++++ b/src/gcc/config/arm/arm.c +@@ -173,6 +173,7 @@ + static tree arm_builtin_decl (unsigned, bool); + static void emit_constant_insn (rtx cond, rtx pattern); + static rtx emit_set_insn (rtx, rtx); ++static rtx emit_multi_reg_push (unsigned long); + static int arm_arg_partial_bytes (cumulative_args_t, enum machine_mode, + tree, bool); + static rtx arm_function_arg (cumulative_args_t, enum machine_mode, +@@ -280,6 +281,7 @@ -+(define_insn "neon_vcvtv4sfv4hf" -+ [(set (match_operand:V4SF 0 "s_register_operand" "=w") -+ (unspec:V4SF [(match_operand:V4HF 1 "s_register_operand" "w")] -+ UNSPEC_VCVT))] -+ "TARGET_NEON && TARGET_FP16" -+ "vcvt.f32.f16\t%q0, %P1" -+ [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")] -+) -+ -+(define_insn "neon_vcvtv4hfv4sf" -+ [(set (match_operand:V4HF 0 "s_register_operand" "=w") -+ (unspec:V4HF [(match_operand:V4SF 1 "s_register_operand" "w")] -+ UNSPEC_VCVT))] -+ "TARGET_NEON && TARGET_FP16" -+ "vcvt.f16.f32\t%P0, %q1" -+ [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")] -+) -+ - (define_insn "neon_vcvt_n" - [(set (match_operand: 0 "s_register_operand" "=w") - (unspec: [(match_operand:VCVTF 1 "s_register_operand" "w") -@@ -4545,9 +4500,19 @@ - DONE; - }) + static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, + bool op0_preserve_value); ++static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); + + /* Table of machine attributes. */ + static const struct attribute_spec arm_attribute_table[] = +@@ -620,6 +622,13 @@ + #undef TARGET_CLASS_LIKELY_SPILLED_P + #define TARGET_CLASS_LIKELY_SPILLED_P arm_class_likely_spilled_p -+(define_expand "neon_vreinterpretti" -+ [(match_operand:TI 0 "s_register_operand" "") -+ (match_operand:VQXMOV 1 "s_register_operand" "")] -+ "TARGET_NEON" -+{ -+ neon_reinterpret (operands[0], operands[1]); -+ DONE; -+}) -+ ++#undef TARGET_VECTORIZE_BUILTINS ++#define TARGET_VECTORIZE_BUILTINS + - (define_expand "neon_vreinterpretv16qi" - [(match_operand:V16QI 0 "s_register_operand" "") -- (match_operand:VQX 1 "s_register_operand" "")] -+ (match_operand:VQXMOV 1 "s_register_operand" "")] - "TARGET_NEON" - { - neon_reinterpret (operands[0], operands[1]); -@@ -4556,7 +4521,7 @@ - - (define_expand "neon_vreinterpretv8hi" - [(match_operand:V8HI 0 "s_register_operand" "") -- (match_operand:VQX 1 "s_register_operand" "")] -+ (match_operand:VQXMOV 1 "s_register_operand" "")] - "TARGET_NEON" - { - neon_reinterpret (operands[0], operands[1]); -@@ -4565,7 +4530,7 @@ - - (define_expand "neon_vreinterpretv4si" - [(match_operand:V4SI 0 "s_register_operand" "") -- (match_operand:VQX 1 "s_register_operand" "")] -+ (match_operand:VQXMOV 1 "s_register_operand" "")] - "TARGET_NEON" - { - neon_reinterpret (operands[0], operands[1]); -@@ -4574,7 +4539,7 @@ - - (define_expand "neon_vreinterpretv4sf" - [(match_operand:V4SF 0 "s_register_operand" "") -- (match_operand:VQX 1 "s_register_operand" "")] -+ (match_operand:VQXMOV 1 "s_register_operand" "")] - "TARGET_NEON" - { - neon_reinterpret (operands[0], operands[1]); -@@ -4583,7 +4548,7 @@ - - (define_expand "neon_vreinterpretv2di" - [(match_operand:V2DI 0 "s_register_operand" "") -- (match_operand:VQX 1 "s_register_operand" "")] -+ (match_operand:VQXMOV 1 "s_register_operand" "")] - "TARGET_NEON" - { - neon_reinterpret (operands[0], operands[1]); -@@ -4660,21 +4625,22 @@ - ) - - (define_insn "neon_vld1_dup" -- [(set (match_operand:VDX 0 "s_register_operand" "=w") -- (vec_duplicate:VDX (match_operand: 1 "neon_struct_operand" "Um")))] -+ [(set (match_operand:VD 0 "s_register_operand" "=w") -+ (vec_duplicate:VD (match_operand: 1 "neon_struct_operand" "Um")))] - "TARGET_NEON" --{ -- if (GET_MODE_NUNITS (mode) > 1) -- return "vld1.\t{%P0[]}, %A1"; -- else -- return "vld1.\t%h0, %A1"; --} -- [(set (attr "neon_type") -- (if_then_else (gt (const_string "") (const_string "1")) -- (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes") -- (const_string "neon_vld1_1_2_regs")))] -+ "vld1.\t{%P0[]}, %A1" -+ [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] - ) - -+;; Special case for DImode. Treat it exactly like a simple load. -+(define_expand "neon_vld1_dupdi" -+ [(set (match_operand:DI 0 "s_register_operand" "") -+ (unspec:DI [(match_operand:DI 1 "neon_struct_operand" "")] -+ UNSPEC_VLD1))] -+ "TARGET_NEON" -+ "" -+) ++#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION ++#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ ++ arm_builtin_vectorized_function + - (define_insn "neon_vld1_dup" - [(set (match_operand:VQ 0 "s_register_operand" "=w") - (vec_duplicate:VQ (match_operand: 1 "neon_struct_operand" "Um")))] -@@ -5635,7 +5601,7 @@ - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" - { -- emit_insn (gen_and3 (operands[0], operands[1], operands[2])); -+ emit_insn (gen_and3 (operands[0], operands[1], operands[2])); - DONE; - }) - -@@ -5646,7 +5612,7 @@ - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" - { -- emit_insn (gen_ior3 (operands[0], operands[1], operands[2])); -+ emit_insn (gen_ior3 (operands[0], operands[1], operands[2])); - DONE; - }) - -@@ -5657,7 +5623,7 @@ - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" - { -- emit_insn (gen_xor3 (operands[0], operands[1], operands[2])); -+ emit_insn (gen_xor3 (operands[0], operands[1], operands[2])); - DONE; - }) - ---- a/src/gcc/config/arm/ldmstm.md -+++ b/src/gcc/config/arm/ldmstm.md -@@ -37,7 +37,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "ldm%(ia%)\t%5, {%1, %2, %3, %4}" - [(set_attr "type" "load4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) - - (define_insn "*thumb_ldm4_ia" - [(match_parallel 0 "load_multiple_operation" -@@ -74,7 +75,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" - "ldm%(ia%)\t%5!, {%1, %2, %3, %4}" - [(set_attr "type" "load4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) - - (define_insn "*thumb_ldm4_ia_update" - [(match_parallel 0 "load_multiple_operation" -@@ -108,7 +110,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "stm%(ia%)\t%5, {%1, %2, %3, %4}" - [(set_attr "type" "store4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) - - (define_insn "*stm4_ia_update" - [(match_parallel 0 "store_multiple_operation" -@@ -125,7 +128,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" - "stm%(ia%)\t%5!, {%1, %2, %3, %4}" - [(set_attr "type" "store4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) - - (define_insn "*thumb_stm4_ia_update" - [(match_parallel 0 "store_multiple_operation" -@@ -302,7 +306,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "ldm%(db%)\t%5, {%1, %2, %3, %4}" - [(set_attr "type" "load4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) - - (define_insn "*ldm4_db_update" - [(match_parallel 0 "load_multiple_operation" -@@ -323,7 +328,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" - "ldm%(db%)\t%5!, {%1, %2, %3, %4}" - [(set_attr "type" "load4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) - - (define_insn "*stm4_db" - [(match_parallel 0 "store_multiple_operation" -@@ -338,7 +344,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "stm%(db%)\t%5, {%1, %2, %3, %4}" - [(set_attr "type" "store4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + #undef TARGET_VECTOR_ALIGNMENT + #define TARGET_VECTOR_ALIGNMENT arm_vector_alignment - (define_insn "*stm4_db_update" - [(match_parallel 0 "store_multiple_operation" -@@ -355,7 +362,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" - "stm%(db%)\t%5!, {%1, %2, %3, %4}" - [(set_attr "type" "store4") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) +@@ -649,6 +658,13 @@ + #define TARGET_CANONICALIZE_COMPARISON \ + arm_canonicalize_comparison - (define_peephole2 - [(set (match_operand:SI 0 "s_register_operand" "") -@@ -477,7 +485,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "ldm%(ia%)\t%4, {%1, %2, %3}" - [(set_attr "type" "load3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) ++#undef TARGET_ASAN_SHADOW_OFFSET ++#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset ++ ++#undef MAX_INSN_PER_IT_BLOCK ++#define MAX_INSN_PER_IT_BLOCK (arm_restrict_it ? 1 : 4) ++ ++ + struct gcc_target targetm = TARGET_INITIALIZER; + + /* Obstack for minipool constant handling. */ +@@ -839,6 +855,10 @@ + int arm_arch_arm_hwdiv; + int arm_arch_thumb_hwdiv; - (define_insn "*thumb_ldm3_ia" - [(match_parallel 0 "load_multiple_operation" -@@ -508,7 +517,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "ldm%(ia%)\t%4!, {%1, %2, %3}" - [(set_attr "type" "load3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) ++/* Nonzero if we should use Neon to handle 64-bits operations rather ++ than core registers. */ ++int prefer_neon_for_64bits = 0; ++ + /* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, + we must report the mode of the memory reference from + TARGET_PRINT_OPERAND to TARGET_PRINT_OPERAND_ADDRESS. */ +@@ -936,6 +956,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*thumb_ldm3_ia_update" - [(match_parallel 0 "load_multiple_operation" -@@ -537,7 +547,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "stm%(ia%)\t%4, {%1, %2, %3}" - [(set_attr "type" "store3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + const struct tune_params arm_fastmul_tune = +@@ -950,6 +971,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*stm3_ia_update" - [(match_parallel 0 "store_multiple_operation" -@@ -552,7 +563,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "stm%(ia%)\t%4!, {%1, %2, %3}" - [(set_attr "type" "store3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + /* StrongARM has early execution of branches, so a sequence that is worth +@@ -967,6 +989,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*thumb_stm3_ia_update" - [(match_parallel 0 "store_multiple_operation" -@@ -704,7 +716,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "ldm%(db%)\t%4, {%1, %2, %3}" - [(set_attr "type" "load3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + const struct tune_params arm_xscale_tune = +@@ -981,6 +1004,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*ldm3_db_update" - [(match_parallel 0 "load_multiple_operation" -@@ -722,7 +735,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "ldm%(db%)\t%4!, {%1, %2, %3}" - [(set_attr "type" "load3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + const struct tune_params arm_9e_tune = +@@ -995,6 +1019,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*stm3_db" - [(match_parallel 0 "store_multiple_operation" -@@ -735,7 +749,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "stm%(db%)\t%4, {%1, %2, %3}" - [(set_attr "type" "store3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + const struct tune_params arm_v6t2_tune = +@@ -1009,6 +1034,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*stm3_db_update" - [(match_parallel 0 "store_multiple_operation" -@@ -750,7 +765,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" - "stm%(db%)\t%4!, {%1, %2, %3}" - [(set_attr "type" "store3") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + /* Generic Cortex tuning. Use more specific tunings if appropriate. */ +@@ -1024,6 +1050,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_peephole2 - [(set (match_operand:SI 0 "s_register_operand" "") -@@ -855,7 +871,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" - "ldm%(ia%)\t%3, {%1, %2}" - [(set_attr "type" "load2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + const struct tune_params arm_cortex_a15_tune = +@@ -1031,13 +1058,14 @@ + arm_9e_rtx_costs, + NULL, + 1, /* Constant limit. */ +- 5, /* Max cond insns. */ ++ 2, /* Max cond insns. */ + ARM_PREFETCH_NOT_BENEFICIAL, + false, /* Prefer constant pool. */ + arm_default_branch_cost, + true, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*thumb_ldm2_ia" - [(match_parallel 0 "load_multiple_operation" -@@ -880,7 +897,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "ldm%(ia%)\t%3!, {%1, %2}" - [(set_attr "type" "load2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + /* Branches can be dual-issued on Cortex-A5, so conditional execution is +@@ -1055,6 +1083,7 @@ + false, /* Prefer LDRD/STRD. */ + {false, false}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*thumb_ldm2_ia_update" - [(match_parallel 0 "load_multiple_operation" -@@ -904,7 +922,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" - "stm%(ia%)\t%3, {%1, %2}" - [(set_attr "type" "store2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + const struct tune_params arm_cortex_a9_tune = +@@ -1069,6 +1098,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*stm2_ia_update" - [(match_parallel 0 "store_multiple_operation" -@@ -917,7 +936,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "stm%(ia%)\t%3!, {%1, %2}" - [(set_attr "type" "store2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + /* The arm_v6m_tune is duplicated from arm_cortex_tune, rather than +@@ -1085,6 +1115,7 @@ + false, /* Prefer LDRD/STRD. */ + {false, false}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*thumb_stm2_ia_update" - [(match_parallel 0 "store_multiple_operation" -@@ -1044,7 +1064,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" - "ldm%(db%)\t%3, {%1, %2}" - [(set_attr "type" "load2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) + const struct tune_params arm_fa726te_tune = +@@ -1099,6 +1130,7 @@ + false, /* Prefer LDRD/STRD. */ + {true, true}, /* Prefer non short circuit. */ + &arm_default_vec_cost, /* Vectorizer costs. */ ++ false /* Prefer Neon for 64-bits bitops. */ + }; - (define_insn "*ldm2_db_update" - [(match_parallel 0 "load_multiple_operation" -@@ -1059,7 +1080,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "ldm%(db%)\t%3!, {%1, %2}" - [(set_attr "type" "load2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) - (define_insn "*stm2_db" - [(match_parallel 0 "store_multiple_operation" -@@ -1070,7 +1092,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" - "stm%(db%)\t%3, {%1, %2}" - [(set_attr "type" "store2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) +@@ -1842,7 +1874,12 @@ + arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0; + arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0; + arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0; ++ if (arm_restrict_it == 2) ++ arm_restrict_it = arm_arch8 && TARGET_THUMB2; - (define_insn "*stm2_db_update" - [(match_parallel 0 "store_multiple_operation" -@@ -1083,7 +1106,8 @@ - "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" - "stm%(db%)\t%3!, {%1, %2}" - [(set_attr "type" "store2") -- (set_attr "predicable" "yes")]) -+ (set_attr "predicable" "yes") -+ (set_attr "predicable_short_it" "no")]) ++ if (!TARGET_THUMB2) ++ arm_restrict_it = 0; ++ + /* If we are not using the default (ARM mode) section anchor offset + ranges, then set the correct ranges now. */ + if (TARGET_THUMB1) +@@ -2129,11 +2166,25 @@ + global_options.x_param_values, + global_options_set.x_param_values); - (define_peephole2 - [(set (match_operand:SI 0 "s_register_operand" "") ---- a/src/gcc/config/arm/arm_neon_builtins.def -+++ b/src/gcc/config/arm/arm_neon_builtins.def -@@ -0,0 +1,213 @@ -+/* NEON builtin definitions for ARM. -+ Copyright (C) 2013 -+ Free Software Foundation, Inc. -+ Contributed by ARM Ltd. ++ /* Use Neon to perform 64-bits operations rather than core ++ registers. */ ++ prefer_neon_for_64bits = current_tune->prefer_neon_for_64bits; ++ if (use_neon_for_64bits == 1) ++ prefer_neon_for_64bits = true; + -+ This file is part of GCC. + /* Use the alternative scheduling-pressure algorithm by default. */ + maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2, + global_options.x_param_values, + global_options_set.x_param_values); + ++ /* Disable shrink-wrap when optimizing function for size, since it tends to ++ generate additional returns. */ ++ if (optimize_function_for_size_p (cfun) && TARGET_THUMB2) ++ flag_shrink_wrap = false; ++ /* TBD: Dwarf info for apcs frame is not handled yet. */ ++ if (TARGET_APCS_FRAME) ++ flag_shrink_wrap = false; + -+ GCC is free software; you can redistribute it and/or modify it -+ under the terms of the GNU General Public License as published -+ by the Free Software Foundation; either version 3, or (at your -+ option) any later version. + /* Register global variables with the garbage collector. */ + arm_add_gc_roots (); + } +@@ -2382,6 +2433,10 @@ + if (IS_INTERRUPT (func_type) && (frame_pointer_needed || TARGET_THUMB)) + return 0; + ++ if (TARGET_LDRD && current_tune->prefer_ldrd_strd ++ && !optimize_function_for_size_p (cfun)) ++ return 0; + -+ GCC is distributed in the hope that it will be useful, but WITHOUT -+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -+ License for more details. + offsets = arm_get_frame_offsets (); + stack_adjust = offsets->outgoing_args - offsets->saved_regs; + +@@ -2479,6 +2534,18 @@ + return 1; + } + ++/* Return TRUE if we should try to use a simple_return insn, i.e. perform ++ shrink-wrapping if possible. This is the case if we need to emit a ++ prologue, which we can test by looking at the offsets. */ ++bool ++use_simple_return_p (void) ++{ ++ arm_stack_offsets *offsets; + -+ You should have received a copy of the GNU General Public License -+ along with GCC; see the file COPYING3. If not see -+ . */ ++ offsets = arm_get_frame_offsets (); ++ return offsets->outgoing_args != 0; ++} + -+VAR10 (BINOP, vadd, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR3 (BINOP, vaddl, v8qi, v4hi, v2si), -+VAR3 (BINOP, vaddw, v8qi, v4hi, v2si), -+VAR6 (BINOP, vhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR8 (BINOP, vqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR3 (BINOP, vaddhn, v8hi, v4si, v2di), -+VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si), -+VAR2 (TERNOP, vfma, v2sf, v4sf), -+VAR2 (TERNOP, vfms, v2sf, v4sf), -+VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si), -+VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si), -+VAR2 (TERNOP, vqdmlal, v4hi, v2si), -+VAR2 (TERNOP, vqdmlsl, v4hi, v2si), -+VAR3 (BINOP, vmull, v8qi, v4hi, v2si), -+VAR2 (SCALARMULL, vmull_n, v4hi, v2si), -+VAR2 (LANEMULL, vmull_lane, v4hi, v2si), -+VAR2 (SCALARMULL, vqdmull_n, v4hi, v2si), -+VAR2 (LANEMULL, vqdmull_lane, v4hi, v2si), -+VAR4 (SCALARMULH, vqdmulh_n, v4hi, v2si, v8hi, v4si), -+VAR4 (LANEMULH, vqdmulh_lane, v4hi, v2si, v8hi, v4si), -+VAR2 (BINOP, vqdmull, v4hi, v2si), -+VAR8 (BINOP, vshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR8 (BINOP, vqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR8 (SHIFTIMM, vshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR3 (SHIFTIMM, vshrn_n, v8hi, v4si, v2di), -+VAR3 (SHIFTIMM, vqshrn_n, v8hi, v4si, v2di), -+VAR3 (SHIFTIMM, vqshrun_n, v8hi, v4si, v2di), -+VAR8 (SHIFTIMM, vshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR8 (SHIFTIMM, vqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR8 (SHIFTIMM, vqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR3 (SHIFTIMM, vshll_n, v8qi, v4hi, v2si), -+VAR8 (SHIFTACC, vsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR10 (BINOP, vsub, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR3 (BINOP, vsubl, v8qi, v4hi, v2si), -+VAR3 (BINOP, vsubw, v8qi, v4hi, v2si), -+VAR8 (BINOP, vqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR6 (BINOP, vhsub, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR3 (BINOP, vsubhn, v8hi, v4si, v2di), -+VAR8 (BINOP, vceq, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR8 (BINOP, vcge, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR6 (BINOP, vcgeu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR8 (BINOP, vcgt, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR6 (BINOP, vcgtu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR2 (BINOP, vcage, v2sf, v4sf), -+VAR2 (BINOP, vcagt, v2sf, v4sf), -+VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR8 (BINOP, vabd, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR3 (BINOP, vabdl, v8qi, v4hi, v2si), -+VAR6 (TERNOP, vaba, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR3 (TERNOP, vabal, v8qi, v4hi, v2si), -+VAR8 (BINOP, vmax, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR8 (BINOP, vmin, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR4 (BINOP, vpadd, v8qi, v4hi, v2si, v2sf), -+VAR6 (UNOP, vpaddl, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR6 (BINOP, vpadal, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR4 (BINOP, vpmax, v8qi, v4hi, v2si, v2sf), -+VAR4 (BINOP, vpmin, v8qi, v4hi, v2si, v2sf), -+VAR2 (BINOP, vrecps, v2sf, v4sf), -+VAR2 (BINOP, vrsqrts, v2sf, v4sf), -+VAR8 (SHIFTINSERT, vsri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR8 (SHIFTINSERT, vsli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), -+VAR8 (UNOP, vabs, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR6 (UNOP, vqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR8 (UNOP, vneg, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR6 (UNOP, vqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR6 (UNOP, vcls, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR6 (UNOP, vclz, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+VAR2 (UNOP, vcnt, v8qi, v16qi), -+VAR4 (UNOP, vrecpe, v2si, v2sf, v4si, v4sf), -+VAR4 (UNOP, vrsqrte, v2si, v2sf, v4si, v4sf), -+VAR6 (UNOP, vmvn, v8qi, v4hi, v2si, v16qi, v8hi, v4si), -+ /* FIXME: vget_lane supports more variants than this! */ -+VAR10 (GETLANE, vget_lane, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (SETLANE, vset_lane, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR5 (CREATE, vcreate, v8qi, v4hi, v2si, v2sf, di), -+VAR10 (DUP, vdup_n, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (DUPLANE, vdup_lane, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR5 (COMBINE, vcombine, v8qi, v4hi, v2si, v2sf, di), -+VAR5 (SPLIT, vget_high, v16qi, v8hi, v4si, v4sf, v2di), -+VAR5 (SPLIT, vget_low, v16qi, v8hi, v4si, v4sf, v2di), -+VAR3 (UNOP, vmovn, v8hi, v4si, v2di), -+VAR3 (UNOP, vqmovn, v8hi, v4si, v2di), -+VAR3 (UNOP, vqmovun, v8hi, v4si, v2di), -+VAR3 (UNOP, vmovl, v8qi, v4hi, v2si), -+VAR6 (LANEMUL, vmul_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR6 (LANEMAC, vmla_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR2 (LANEMAC, vmlal_lane, v4hi, v2si), -+VAR2 (LANEMAC, vqdmlal_lane, v4hi, v2si), -+VAR6 (LANEMAC, vmls_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR2 (LANEMAC, vmlsl_lane, v4hi, v2si), -+VAR2 (LANEMAC, vqdmlsl_lane, v4hi, v2si), -+VAR6 (SCALARMUL, vmul_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR6 (SCALARMAC, vmla_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR2 (SCALARMAC, vmlal_n, v4hi, v2si), -+VAR2 (SCALARMAC, vqdmlal_n, v4hi, v2si), -+VAR6 (SCALARMAC, vmls_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR2 (SCALARMAC, vmlsl_n, v4hi, v2si), -+VAR2 (SCALARMAC, vqdmlsl_n, v4hi, v2si), -+VAR10 (BINOP, vext, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR8 (UNOP, vrev64, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR4 (UNOP, vrev32, v8qi, v4hi, v16qi, v8hi), -+VAR2 (UNOP, vrev16, v8qi, v16qi), -+VAR4 (CONVERT, vcvt, v2si, v2sf, v4si, v4sf), -+VAR4 (FIXCONV, vcvt_n, v2si, v2sf, v4si, v4sf), -+VAR1 (FLOAT_WIDEN, vcvtv4sf, v4hf), -+VAR1 (FLOAT_NARROW, vcvtv4hf, v4sf), -+VAR10 (SELECT, vbsl, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR2 (RINT, vrintn, v2sf, v4sf), -+VAR2 (RINT, vrinta, v2sf, v4sf), -+VAR2 (RINT, vrintp, v2sf, v4sf), -+VAR2 (RINT, vrintm, v2sf, v4sf), -+VAR2 (RINT, vrintz, v2sf, v4sf), -+VAR2 (RINT, vrintx, v2sf, v4sf), -+VAR1 (VTBL, vtbl1, v8qi), -+VAR1 (VTBL, vtbl2, v8qi), -+VAR1 (VTBL, vtbl3, v8qi), -+VAR1 (VTBL, vtbl4, v8qi), -+VAR1 (VTBX, vtbx1, v8qi), -+VAR1 (VTBX, vtbx2, v8qi), -+VAR1 (VTBX, vtbx3, v8qi), -+VAR1 (VTBX, vtbx4, v8qi), -+VAR8 (RESULTPAIR, vtrn, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR8 (RESULTPAIR, vzip, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR8 (RESULTPAIR, vuzp, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), -+VAR5 (REINTERP, vreinterpretv8qi, v8qi, v4hi, v2si, v2sf, di), -+VAR5 (REINTERP, vreinterpretv4hi, v8qi, v4hi, v2si, v2sf, di), -+VAR5 (REINTERP, vreinterpretv2si, v8qi, v4hi, v2si, v2sf, di), -+VAR5 (REINTERP, vreinterpretv2sf, v8qi, v4hi, v2si, v2sf, di), -+VAR5 (REINTERP, vreinterpretdi, v8qi, v4hi, v2si, v2sf, di), -+VAR6 (REINTERP, vreinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di, ti), -+VAR6 (REINTERP, vreinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di, ti), -+VAR6 (REINTERP, vreinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di, ti), -+VAR6 (REINTERP, vreinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di, ti), -+VAR6 (REINTERP, vreinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di, ti), -+VAR6 (REINTERP, vreinterpretti, v16qi, v8hi, v4si, v4sf, v2di, ti), -+VAR10 (LOAD1, vld1, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (LOAD1LANE, vld1_lane, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (LOAD1, vld1_dup, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (STORE1, vst1, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (STORE1LANE, vst1_lane, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR9 (LOADSTRUCT, -+ vld2, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -+VAR7 (LOADSTRUCTLANE, vld2_lane, -+ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR5 (LOADSTRUCT, vld2_dup, v8qi, v4hi, v2si, v2sf, di), -+VAR9 (STORESTRUCT, vst2, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -+VAR7 (STORESTRUCTLANE, vst2_lane, -+ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR9 (LOADSTRUCT, -+ vld3, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -+VAR7 (LOADSTRUCTLANE, vld3_lane, -+ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR5 (LOADSTRUCT, vld3_dup, v8qi, v4hi, v2si, v2sf, di), -+VAR9 (STORESTRUCT, vst3, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -+VAR7 (STORESTRUCTLANE, vst3_lane, -+ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR9 (LOADSTRUCT, vld4, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -+VAR7 (LOADSTRUCTLANE, vld4_lane, -+ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR5 (LOADSTRUCT, vld4_dup, v8qi, v4hi, v2si, v2sf, di), -+VAR9 (STORESTRUCT, vst4, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), -+VAR7 (STORESTRUCTLANE, vst4_lane, -+ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), -+VAR10 (LOGICBINOP, vand, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (LOGICBINOP, vorr, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (BINOP, veor, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (LOGICBINOP, vbic, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), -+VAR10 (LOGICBINOP, vorn, -+ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) ---- a/src/gcc/config/arm/neon.ml -+++ b/src/gcc/config/arm/neon.ml -@@ -21,8 +21,8 @@ - . *) + /* Return TRUE if int I is a valid immediate ARM constant. */ + + int +@@ -2617,6 +2684,11 @@ + + switch (code) + { ++ case AND: ++ case IOR: ++ case XOR: ++ return (const_ok_for_op (hi_val, code) || hi_val == 0xFFFFFFFF) ++ && (const_ok_for_op (lo_val, code) || lo_val == 0xFFFFFFFF); + case PLUS: + return arm_not_operand (hi, SImode) && arm_add_operand (lo, SImode); - (* Shorthand types for vector elements. *) --type elts = S8 | S16 | S32 | S64 | F32 | U8 | U16 | U32 | U64 | P8 | P16 -- | I8 | I16 | I32 | I64 | B8 | B16 | B32 | B64 | Conv of elts * elts -+type elts = S8 | S16 | S32 | S64 | F16 | F32 | U8 | U16 | U32 | U64 | P8 | P16 -+ | P64 | P128 | I8 | I16 | I32 | I64 | B8 | B16 | B32 | B64 | Conv of elts * elts - | Cast of elts * elts | NoElts +@@ -5337,9 +5409,8 @@ + if (cfun->machine->sibcall_blocked) + return false; - type eltclass = Signed | Unsigned | Float | Poly | Int | Bits -@@ -37,6 +37,7 @@ - | T_uint16x4 | T_uint16x8 - | T_uint32x2 | T_uint32x4 - | T_uint64x1 | T_uint64x2 -+ | T_float16x4 - | T_float32x2 | T_float32x4 - | T_poly8x8 | T_poly8x16 - | T_poly16x4 | T_poly16x8 -@@ -46,11 +47,15 @@ - | T_uint8 | T_uint16 - | T_uint32 | T_uint64 - | T_poly8 | T_poly16 -- | T_float32 | T_arrayof of int * vectype -+ | T_poly64 | T_poly64x1 -+ | T_poly64x2 | T_poly128 -+ | T_float16 | T_float32 -+ | T_arrayof of int * vectype - | T_ptrto of vectype | T_const of vectype - | T_void | T_intQI - | T_intHI | T_intSI -- | T_intDI | T_floatSF -+ | T_intDI | T_intTI -+ | T_floatHF | T_floatSF +- /* Never tailcall something for which we have no decl, or if we +- are generating code for Thumb-1. */ +- if (decl == NULL || TARGET_THUMB1) ++ /* Never tailcall something if we are generating code for Thumb-1. */ ++ if (TARGET_THUMB1) + return false; - (* The meanings of the following are: - TImode : "Tetra", two registers (four words). -@@ -92,8 +97,8 @@ - | Arity3 of vectype * vectype * vectype * vectype - | Arity4 of vectype * vectype * vectype * vectype * vectype + /* The PIC register is live on entry to VxWorks PLT entries, so we +@@ -5349,13 +5420,14 @@ --type vecmode = V8QI | V4HI | V2SI | V2SF | DI -- | V16QI | V8HI | V4SI | V4SF | V2DI -+type vecmode = V8QI | V4HI | V4HF |V2SI | V2SF | DI -+ | V16QI | V8HI | V4SI | V4SF | V2DI | TI - | QI | HI | SI | SF + /* Cannot tail-call to long calls, since these are out of range of + a branch instruction. */ +- if (arm_is_long_call_p (decl)) ++ if (decl && arm_is_long_call_p (decl)) + return false; - type opcode = -@@ -284,18 +289,23 @@ - | Fixed_core_reg - (* Mark that the intrinsic requires __ARM_FEATURE_string to be defined. *) - | Requires_feature of string -+ (* Mark that the intrinsic requires a particular architecture version. *) - | Requires_arch of int -+ (* Mark that the intrinsic requires a particular bit in __ARM_FP to -+ be set. *) -+ | Requires_FP_bit of int + /* If we are interworking and the function is not declared static + then we can't tail-call it unless we know that it exists in this + compilation unit (since it might be a Thumb routine). */ +- if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl)) ++ if (TARGET_INTERWORK && decl && TREE_PUBLIC (decl) ++ && !TREE_ASM_WRITTEN (decl)) + return false; - exception MixedMode of elts * elts + func_type = arm_current_func_type (); +@@ -5387,6 +5459,7 @@ + sibling calls. */ + if (TARGET_AAPCS_BASED + && arm_abi == ARM_ABI_AAPCS ++ && decl + && DECL_WEAK (decl)) + return false; - let rec elt_width = function - S8 | U8 | P8 | I8 | B8 -> 8 -- | S16 | U16 | P16 | I16 | B16 -> 16 -+ | S16 | U16 | P16 | I16 | B16 | F16 -> 16 - | S32 | F32 | U32 | I32 | B32 -> 32 -- | S64 | U64 | I64 | B64 -> 64 -+ | S64 | U64 | P64 | I64 | B64 -> 64 -+ | P128 -> 128 - | Conv (a, b) -> - let wa = elt_width a and wb = elt_width b in -- if wa = wb then wa else failwith "element width?" -+ if wa = wb then wa else raise (MixedMode (a, b)) - | Cast (a, b) -> raise (MixedMode (a, b)) - | NoElts -> failwith "No elts" +@@ -8578,7 +8651,12 @@ + instruction we depend on is another ALU instruction, then we may + have to account for an additional stall. */ + if (shift_opnum != 0 +- && (attr_type == TYPE_ALU_SHIFT || attr_type == TYPE_ALU_SHIFT_REG)) ++ && (attr_type == TYPE_ARLO_SHIFT ++ || attr_type == TYPE_ARLO_SHIFT_REG ++ || attr_type == TYPE_MOV_SHIFT ++ || attr_type == TYPE_MVN_SHIFT ++ || attr_type == TYPE_MOV_SHIFT_REG ++ || attr_type == TYPE_MVN_SHIFT_REG)) + { + rtx shifted_operand; + int opno; +@@ -8859,12 +8937,12 @@ + if (recog_memoized (insn) < 0) + return false; -@@ -302,8 +312,8 @@ - let rec elt_class = function - S8 | S16 | S32 | S64 -> Signed - | U8 | U16 | U32 | U64 -> Unsigned -- | P8 | P16 -> Poly -- | F32 -> Float -+ | P8 | P16 | P64 | P128 -> Poly -+ | F16 | F32 -> Float - | I8 | I16 | I32 | I64 -> Int - | B8 | B16 | B32 | B64 -> Bits - | Conv (a, b) | Cast (a, b) -> ConvClass (elt_class a, elt_class b) -@@ -315,6 +325,7 @@ - | Signed, 16 -> S16 - | Signed, 32 -> S32 - | Signed, 64 -> S64 -+ | Float, 16 -> F16 - | Float, 32 -> F32 - | Unsigned, 8 -> U8 - | Unsigned, 16 -> U16 -@@ -322,6 +333,8 @@ - | Unsigned, 64 -> U64 - | Poly, 8 -> P8 - | Poly, 16 -> P16 -+ | Poly, 64 -> P64 -+ | Poly, 128 -> P128 - | Int, 8 -> I8 - | Int, 16 -> I16 - | Int, 32 -> I32 -@@ -384,20 +397,28 @@ - in - scan ((Array.length operands) - 1) +- if (get_attr_insn (insn) == INSN_MOV) +- return false; +- + switch (get_attr_type (insn)) + { +- case TYPE_ALU_REG: ++ case TYPE_ARLO_REG: ++ case TYPE_MVN_REG: ++ case TYPE_SHIFT: ++ case TYPE_SHIFT_REG: + case TYPE_LOAD_BYTE: + case TYPE_LOAD1: + case TYPE_STORE1: +@@ -8905,13 +8983,15 @@ + return false; + } --let rec mode_of_elt elt shape = -+(* Find a vecmode from a shape_elt ELT for an instruction with shape_form -+ SHAPE. For a Use_operands shape, if ARGPOS is passed then return the mode -+ for the given argument position, else determine which argument to return a -+ mode for automatically. *) +- if (get_attr_insn (insn) == INSN_MOV) +- return true; +- + switch (get_attr_type (insn)) + { +- case TYPE_SIMPLE_ALU_IMM: +- case TYPE_SIMPLE_ALU_SHIFT: ++ case TYPE_ARLO_IMM: ++ case TYPE_EXTEND: ++ case TYPE_MVN_IMM: ++ case TYPE_MOV_IMM: ++ case TYPE_MOV_REG: ++ case TYPE_MOV_SHIFT: ++ case TYPE_MOV_SHIFT_REG: + case TYPE_BRANCH: + case TYPE_CALL: + return true; +@@ -9070,6 +9150,12 @@ + return cost; + } + ++int ++arm_max_conditional_execute (void) ++{ ++ return max_insns_skipped; ++} ++ + static int + arm_default_branch_cost (bool speed_p, bool predictable_p ATTRIBUTE_UNUSED) + { +@@ -11825,6 +11911,142 @@ + return 1; + } + ++/* Helper for gen_movmem_ldrd_strd. Increase the address of memory rtx ++by mode size. */ ++inline static rtx ++next_consecutive_mem (rtx mem) ++{ ++ enum machine_mode mode = GET_MODE (mem); ++ HOST_WIDE_INT offset = GET_MODE_SIZE (mode); ++ rtx addr = plus_constant (Pmode, XEXP (mem, 0), offset); ++ ++ return adjust_automodify_address (mem, mode, addr, offset); ++} ++ ++/* Copy using LDRD/STRD instructions whenever possible. ++ Returns true upon success. */ ++bool ++gen_movmem_ldrd_strd (rtx *operands) ++{ ++ unsigned HOST_WIDE_INT len; ++ HOST_WIDE_INT align; ++ rtx src, dst, base; ++ rtx reg0; ++ bool src_aligned, dst_aligned; ++ bool src_volatile, dst_volatile; ++ ++ gcc_assert (CONST_INT_P (operands[2])); ++ gcc_assert (CONST_INT_P (operands[3])); ++ ++ len = UINTVAL (operands[2]); ++ if (len > 64) ++ return false; ++ ++ /* Maximum alignment we can assume for both src and dst buffers. */ ++ align = INTVAL (operands[3]); ++ ++ if ((!unaligned_access) && (len >= 4) && ((align & 3) != 0)) ++ return false; ++ ++ /* Place src and dst addresses in registers ++ and update the corresponding mem rtx. */ ++ dst = operands[0]; ++ dst_volatile = MEM_VOLATILE_P (dst); ++ dst_aligned = MEM_ALIGN (dst) >= BITS_PER_WORD; ++ base = copy_to_mode_reg (SImode, XEXP (dst, 0)); ++ dst = adjust_automodify_address (dst, VOIDmode, base, 0); ++ ++ src = operands[1]; ++ src_volatile = MEM_VOLATILE_P (src); ++ src_aligned = MEM_ALIGN (src) >= BITS_PER_WORD; ++ base = copy_to_mode_reg (SImode, XEXP (src, 0)); ++ src = adjust_automodify_address (src, VOIDmode, base, 0); ++ ++ if (!unaligned_access && !(src_aligned && dst_aligned)) ++ return false; ++ ++ if (src_volatile || dst_volatile) ++ return false; ++ ++ /* If we cannot generate any LDRD/STRD, try to generate LDM/STM. */ ++ if (!(dst_aligned || src_aligned)) ++ return arm_gen_movmemqi (operands); ++ ++ src = adjust_address (src, DImode, 0); ++ dst = adjust_address (dst, DImode, 0); ++ while (len >= 8) ++ { ++ len -= 8; ++ reg0 = gen_reg_rtx (DImode); ++ if (src_aligned) ++ emit_move_insn (reg0, src); ++ else ++ emit_insn (gen_unaligned_loaddi (reg0, src)); ++ ++ if (dst_aligned) ++ emit_move_insn (dst, reg0); ++ else ++ emit_insn (gen_unaligned_storedi (dst, reg0)); ++ ++ src = next_consecutive_mem (src); ++ dst = next_consecutive_mem (dst); ++ } ++ ++ gcc_assert (len < 8); ++ if (len >= 4) ++ { ++ /* More than a word but less than a double-word to copy. Copy a word. */ ++ reg0 = gen_reg_rtx (SImode); ++ src = adjust_address (src, SImode, 0); ++ dst = adjust_address (dst, SImode, 0); ++ if (src_aligned) ++ emit_move_insn (reg0, src); ++ else ++ emit_insn (gen_unaligned_loadsi (reg0, src)); ++ ++ if (dst_aligned) ++ emit_move_insn (dst, reg0); ++ else ++ emit_insn (gen_unaligned_storesi (dst, reg0)); ++ ++ src = next_consecutive_mem (src); ++ dst = next_consecutive_mem (dst); ++ len -= 4; ++ } ++ ++ if (len == 0) ++ return true; ++ ++ /* Copy the remaining bytes. */ ++ if (len >= 2) ++ { ++ dst = adjust_address (dst, HImode, 0); ++ src = adjust_address (src, HImode, 0); ++ reg0 = gen_reg_rtx (SImode); ++ if (src_aligned) ++ emit_insn (gen_zero_extendhisi2 (reg0, src)); ++ else ++ emit_insn (gen_unaligned_loadhiu (reg0, src)); ++ ++ if (dst_aligned) ++ emit_insn (gen_movhi (dst, gen_lowpart(HImode, reg0))); ++ else ++ emit_insn (gen_unaligned_storehi (dst, gen_lowpart (HImode, reg0))); ++ ++ src = next_consecutive_mem (src); ++ dst = next_consecutive_mem (dst); ++ if (len == 2) ++ return true; ++ } ++ ++ dst = adjust_address (dst, QImode, 0); ++ src = adjust_address (src, QImode, 0); ++ reg0 = gen_reg_rtx (QImode); ++ emit_move_insn (reg0, src); ++ emit_move_insn (dst, reg0); ++ return true; ++} ++ + /* Select a dominance comparison mode if possible for a test of the general + form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms. + COND_OR == DOM_CC_X_AND_Y => (X && Y) +@@ -12625,6 +12847,277 @@ + return true; + } + ++/* Helper for gen_operands_ldrd_strd. Returns true iff the memory ++ operand ADDR is an immediate offset from the base register and is ++ not volatile, in which case it sets BASE and OFFSET ++ accordingly. */ ++bool ++mem_ok_for_ldrd_strd (rtx addr, rtx *base, rtx *offset) ++{ ++ /* TODO: Handle more general memory operand patterns, such as ++ PRE_DEC and PRE_INC. */ ++ ++ /* Convert a subreg of mem into mem itself. */ ++ if (GET_CODE (addr) == SUBREG) ++ addr = alter_subreg (&addr, true); ++ ++ gcc_assert (MEM_P (addr)); ++ ++ /* Don't modify volatile memory accesses. */ ++ if (MEM_VOLATILE_P (addr)) ++ return false; ++ ++ *offset = const0_rtx; ++ ++ addr = XEXP (addr, 0); ++ if (REG_P (addr)) ++ { ++ *base = addr; ++ return true; ++ } ++ else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS) ++ { ++ *base = XEXP (addr, 0); ++ *offset = XEXP (addr, 1); ++ return (REG_P (*base) && CONST_INT_P (*offset)); ++ } ++ ++ return false; ++} ++ ++#define SWAP_RTX(x,y) do { rtx tmp = x; x = y; y = tmp; } while (0) ++ ++/* Called from a peephole2 to replace two word-size accesses with a ++ single LDRD/STRD instruction. Returns true iff we can generate a ++ new instruction sequence. That is, both accesses use the same base ++ register and the gap between constant offsets is 4. This function ++ may reorder its operands to match ldrd/strd RTL templates. ++ OPERANDS are the operands found by the peephole matcher; ++ OPERANDS[0,1] are register operands, and OPERANDS[2,3] are the ++ corresponding memory operands. LOAD indicaates whether the access ++ is load or store. CONST_STORE indicates a store of constant ++ integer values held in OPERANDS[4,5] and assumes that the pattern ++ is of length 4 insn, for the purpose of checking dead registers. ++ COMMUTE indicates that register operands may be reordered. */ ++bool ++gen_operands_ldrd_strd (rtx *operands, bool load, ++ bool const_store, bool commute) ++{ ++ int nops = 2; ++ HOST_WIDE_INT offsets[2], offset; ++ rtx base = NULL_RTX; ++ rtx cur_base, cur_offset, tmp; ++ int i, gap; ++ HARD_REG_SET regset; ++ ++ gcc_assert (!const_store || !load); ++ /* Check that the memory references are immediate offsets from the ++ same base register. Extract the base register, the destination ++ registers, and the corresponding memory offsets. */ ++ for (i = 0; i < nops; i++) ++ { ++ if (!mem_ok_for_ldrd_strd (operands[nops+i], &cur_base, &cur_offset)) ++ return false; ++ ++ if (i == 0) ++ base = cur_base; ++ else if (REGNO (base) != REGNO (cur_base)) ++ return false; ++ ++ offsets[i] = INTVAL (cur_offset); ++ if (GET_CODE (operands[i]) == SUBREG) ++ { ++ tmp = SUBREG_REG (operands[i]); ++ gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp)); ++ operands[i] = tmp; ++ } ++ } ++ ++ /* Make sure there is no dependency between the individual loads. */ ++ if (load && REGNO (operands[0]) == REGNO (base)) ++ return false; /* RAW */ ++ ++ if (load && REGNO (operands[0]) == REGNO (operands[1])) ++ return false; /* WAW */ ++ ++ /* If the same input register is used in both stores ++ when storing different constants, try to find a free register. ++ For example, the code ++ mov r0, 0 ++ str r0, [r2] ++ mov r0, 1 ++ str r0, [r2, #4] ++ can be transformed into ++ mov r1, 0 ++ strd r1, r0, [r2] ++ in Thumb mode assuming that r1 is free. */ ++ if (const_store ++ && REGNO (operands[0]) == REGNO (operands[1]) ++ && INTVAL (operands[4]) != INTVAL (operands[5])) ++ { ++ if (TARGET_THUMB2) ++ { ++ CLEAR_HARD_REG_SET (regset); ++ tmp = peep2_find_free_register (0, 4, "r", SImode, ®set); ++ if (tmp == NULL_RTX) ++ return false; ++ ++ /* Use the new register in the first load to ensure that ++ if the original input register is not dead after peephole, ++ then it will have the correct constant value. */ ++ operands[0] = tmp; ++ } ++ else if (TARGET_ARM) ++ { ++ return false; ++ int regno = REGNO (operands[0]); ++ if (!peep2_reg_dead_p (4, operands[0])) ++ { ++ /* When the input register is even and is not dead after the ++ pattern, it has to hold the second constant but we cannot ++ form a legal STRD in ARM mode with this register as the second ++ register. */ ++ if (regno % 2 == 0) ++ return false; ++ ++ /* Is regno-1 free? */ ++ SET_HARD_REG_SET (regset); ++ CLEAR_HARD_REG_BIT(regset, regno - 1); ++ tmp = peep2_find_free_register (0, 4, "r", SImode, ®set); ++ if (tmp == NULL_RTX) ++ return false; ++ ++ operands[0] = tmp; ++ } ++ else ++ { ++ /* Find a DImode register. */ ++ CLEAR_HARD_REG_SET (regset); ++ tmp = peep2_find_free_register (0, 4, "r", DImode, ®set); ++ if (tmp != NULL_RTX) ++ { ++ operands[0] = simplify_gen_subreg (SImode, tmp, DImode, 0); ++ operands[1] = simplify_gen_subreg (SImode, tmp, DImode, 4); ++ } ++ else ++ { ++ /* Can we use the input register to form a DI register? */ ++ SET_HARD_REG_SET (regset); ++ CLEAR_HARD_REG_BIT(regset, ++ regno % 2 == 0 ? regno + 1 : regno - 1); ++ tmp = peep2_find_free_register (0, 4, "r", SImode, ®set); ++ if (tmp == NULL_RTX) ++ return false; ++ operands[regno % 2 == 1 ? 0 : 1] = tmp; ++ } ++ } ++ ++ gcc_assert (operands[0] != NULL_RTX); ++ gcc_assert (operands[1] != NULL_RTX); ++ gcc_assert (REGNO (operands[0]) % 2 == 0); ++ gcc_assert (REGNO (operands[1]) == REGNO (operands[0]) + 1); ++ } ++ } ++ ++ /* Make sure the instructions are ordered with lower memory access first. */ ++ if (offsets[0] > offsets[1]) ++ { ++ gap = offsets[0] - offsets[1]; ++ offset = offsets[1]; ++ ++ /* Swap the instructions such that lower memory is accessed first. */ ++ SWAP_RTX (operands[0], operands[1]); ++ SWAP_RTX (operands[2], operands[3]); ++ if (const_store) ++ SWAP_RTX (operands[4], operands[5]); ++ } ++ else ++ { ++ gap = offsets[1] - offsets[0]; ++ offset = offsets[0]; ++ } ++ ++ /* Make sure accesses are to consecutive memory locations. */ ++ if (gap != 4) ++ return false; ++ ++ /* Make sure we generate legal instructions. */ ++ if (operands_ok_ldrd_strd (operands[0], operands[1], base, offset, ++ false, load)) ++ return true; ++ ++ /* In Thumb state, where registers are almost unconstrained, there ++ is little hope to fix it. */ ++ if (TARGET_THUMB2) ++ return false; + -+let rec mode_of_elt ?argpos elt shape = - let flt = match elt_class elt with - Float | ConvClass(_, Float) -> true | _ -> false in - let idx = - match elt_width elt with -- 8 -> 0 | 16 -> 1 | 32 -> 2 | 64 -> 3 -+ 8 -> 0 | 16 -> 1 | 32 -> 2 | 64 -> 3 | 128 -> 4 - | _ -> failwith "Bad element width" - in match shape with - All (_, Dreg) | By_scalar Dreg | Pair_result Dreg | Unary_scalar Dreg - | Binary_imm Dreg | Long_noreg Dreg | Wide_noreg Dreg -> -- [| V8QI; V4HI; if flt then V2SF else V2SI; DI |].(idx) -+ if flt then -+ [| V8QI; V4HF; V2SF; DI |].(idx) -+ else -+ [| V8QI; V4HI; V2SI; DI |].(idx) - | All (_, Qreg) | By_scalar Qreg | Pair_result Qreg | Unary_scalar Qreg - | Binary_imm Qreg | Long_noreg Qreg | Wide_noreg Qreg -> -- [| V16QI; V8HI; if flt then V4SF else V4SI; V2DI |].(idx) -+ [| V16QI; V8HI; if flt then V4SF else V4SI; V2DI; TI|].(idx) - | All (_, (Corereg | PtrTo _ | CstPtrTo _)) -> - [| QI; HI; if flt then SF else SI; DI |].(idx) - | Long | Wide | Wide_lane | Wide_scalar -@@ -404,7 +425,11 @@ - | Long_imm -> - [| V8QI; V4HI; V2SI; DI |].(idx) - | Narrow | Narrow_imm -> [| V16QI; V8HI; V4SI; V2DI |].(idx) -- | Use_operands ops -> mode_of_elt elt (All (0, (find_key_operand ops))) -+ | Use_operands ops -> -+ begin match argpos with -+ None -> mode_of_elt ?argpos elt (All (0, (find_key_operand ops))) -+ | Some pos -> mode_of_elt ?argpos elt (All (0, ops.(pos))) -+ end - | _ -> failwith "invalid shape" - - (* Modify an element type dependent on the shape of the instruction and the -@@ -454,10 +479,13 @@ - | U16 -> T_uint16x4 - | U32 -> T_uint32x2 - | U64 -> T_uint64x1 -+ | P64 -> T_poly64x1 -+ | P128 -> T_poly128 -+ | F16 -> T_float16x4 - | F32 -> T_float32x2 - | P8 -> T_poly8x8 - | P16 -> T_poly16x4 -- | _ -> failwith "Bad elt type" -+ | _ -> failwith "Bad elt type for Dreg" - end - | Qreg -> - begin match elt with -@@ -472,7 +500,9 @@ - | F32 -> T_float32x4 - | P8 -> T_poly8x16 - | P16 -> T_poly16x8 -- | _ -> failwith "Bad elt type" -+ | P64 -> T_poly64x2 -+ | P128 -> T_poly128 -+ | _ -> failwith "Bad elt type for Qreg" - end - | Corereg -> - begin match elt with -@@ -486,8 +516,10 @@ - | U64 -> T_uint64 - | P8 -> T_poly8 - | P16 -> T_poly16 -+ | P64 -> T_poly64 -+ | P128 -> T_poly128 - | F32 -> T_float32 -- | _ -> failwith "Bad elt type" -+ | _ -> failwith "Bad elt type for Corereg" - end - | Immed -> - T_immediate (0, 0) -@@ -506,10 +538,10 @@ - let vectype_size = function - T_int8x8 | T_int16x4 | T_int32x2 | T_int64x1 - | T_uint8x8 | T_uint16x4 | T_uint32x2 | T_uint64x1 -- | T_float32x2 | T_poly8x8 | T_poly16x4 -> 64 -+ | T_float32x2 | T_poly8x8 | T_poly64x1 | T_poly16x4 | T_float16x4 -> 64 - | T_int8x16 | T_int16x8 | T_int32x4 | T_int64x2 - | T_uint8x16 | T_uint16x8 | T_uint32x4 | T_uint64x2 -- | T_float32x4 | T_poly8x16 | T_poly16x8 -> 128 -+ | T_float32x4 | T_poly8x16 | T_poly64x2 | T_poly16x8 -> 128 - | _ -> raise Not_found - - let inttype_for_array num elttype = -@@ -1020,14 +1052,22 @@ - "vRsraQ_n", shift_right_acc, su_8_64; - - (* Vector shift right and insert. *) -+ Vsri, [Requires_feature "CRYPTO"], Use_operands [| Dreg; Dreg; Immed |], "vsri_n", shift_insert, -+ [P64]; - Vsri, [], Use_operands [| Dreg; Dreg; Immed |], "vsri_n", shift_insert, - P8 :: P16 :: su_8_64; -+ Vsri, [Requires_feature "CRYPTO"], Use_operands [| Qreg; Qreg; Immed |], "vsriQ_n", shift_insert, -+ [P64]; - Vsri, [], Use_operands [| Qreg; Qreg; Immed |], "vsriQ_n", shift_insert, - P8 :: P16 :: su_8_64; - - (* Vector shift left and insert. *) -+ Vsli, [Requires_feature "CRYPTO"], Use_operands [| Dreg; Dreg; Immed |], "vsli_n", shift_insert, -+ [P64]; - Vsli, [], Use_operands [| Dreg; Dreg; Immed |], "vsli_n", shift_insert, - P8 :: P16 :: su_8_64; -+ Vsli, [Requires_feature "CRYPTO"], Use_operands [| Qreg; Qreg; Immed |], "vsliQ_n", shift_insert, -+ [P64]; - Vsli, [], Use_operands [| Qreg; Qreg; Immed |], "vsliQ_n", shift_insert, - P8 :: P16 :: su_8_64; - -@@ -1114,6 +1154,11 @@ - - (* Create vector from literal bit pattern. *) - Vcreate, -+ [Requires_feature "CRYPTO"; No_op], (* Not really, but it can yield various things that are too -+ hard for the test generator at this time. *) -+ Use_operands [| Dreg; Corereg |], "vcreate", create_vector, -+ [P64]; -+ Vcreate, - [No_op], (* Not really, but it can yield various things that are too - hard for the test generator at this time. *) - Use_operands [| Dreg; Corereg |], "vcreate", create_vector, -@@ -1127,6 +1172,12 @@ - Use_operands [| Dreg; Corereg |], "vdup_n", bits_1, - pf_su_8_32; - Vdup_n, -+ [No_op; Requires_feature "CRYPTO"; -+ Instruction_name ["vmov"]; -+ Disassembles_as [Use_operands [| Dreg; Corereg; Corereg |]]], -+ Use_operands [| Dreg; Corereg |], "vdup_n", notype_1, -+ [P64]; -+ Vdup_n, - [No_op; - Instruction_name ["vmov"]; - Disassembles_as [Use_operands [| Dreg; Corereg; Corereg |]]], -@@ -1133,6 +1184,13 @@ - Use_operands [| Dreg; Corereg |], "vdup_n", notype_1, - [S64; U64]; - Vdup_n, -+ [No_op; Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| Qreg; -+ Alternatives [ Corereg; -+ Element_of_dreg ] |]]], -+ Use_operands [| Qreg; Corereg |], "vdupQ_n", bits_1, -+ [P64]; -+ Vdup_n, - [Disassembles_as [Use_operands [| Qreg; - Alternatives [ Corereg; - Element_of_dreg ] |]]], -@@ -1185,6 +1243,9 @@ - [Disassembles_as [Use_operands [| Dreg; Element_of_dreg |]]], - Unary_scalar Dreg, "vdup_lane", bits_2, pf_su_8_32; - Vdup_lane, -+ [No_op; Requires_feature "CRYPTO"; Const_valuator (fun _ -> 0)], -+ Unary_scalar Dreg, "vdup_lane", bits_2, [P64]; -+ Vdup_lane, - [No_op; Const_valuator (fun _ -> 0)], - Unary_scalar Dreg, "vdup_lane", bits_2, [S64; U64]; - Vdup_lane, -@@ -1191,15 +1252,24 @@ - [Disassembles_as [Use_operands [| Qreg; Element_of_dreg |]]], - Unary_scalar Qreg, "vdupQ_lane", bits_2, pf_su_8_32; - Vdup_lane, -+ [No_op; Requires_feature "CRYPTO"; Const_valuator (fun _ -> 0)], -+ Unary_scalar Qreg, "vdupQ_lane", bits_2, [P64]; -+ Vdup_lane, - [No_op; Const_valuator (fun _ -> 0)], - Unary_scalar Qreg, "vdupQ_lane", bits_2, [S64; U64]; - - (* Combining vectors. *) -+ Vcombine, [Requires_feature "CRYPTO"; No_op], -+ Use_operands [| Qreg; Dreg; Dreg |], "vcombine", notype_2, -+ [P64]; - Vcombine, [No_op], - Use_operands [| Qreg; Dreg; Dreg |], "vcombine", notype_2, - pf_su_8_64; - - (* Splitting vectors. *) -+ Vget_high, [Requires_feature "CRYPTO"; No_op], -+ Use_operands [| Dreg; Qreg |], "vget_high", -+ notype_1, [P64]; - Vget_high, [No_op], - Use_operands [| Dreg; Qreg |], "vget_high", - notype_1, pf_su_8_64; -@@ -1208,8 +1278,11 @@ - Fixed_vector_reg], - Use_operands [| Dreg; Qreg |], "vget_low", - notype_1, pf_su_8_32; -- Vget_low, [No_op], -+ Vget_low, [Requires_feature "CRYPTO"; No_op], - Use_operands [| Dreg; Qreg |], "vget_low", -+ notype_1, [P64]; -+ Vget_low, [No_op], -+ Use_operands [| Dreg; Qreg |], "vget_low", - notype_1, [S64; U64]; - - (* Conversions. *) -@@ -1217,6 +1290,10 @@ - [Conv (S32, F32); Conv (U32, F32); Conv (F32, S32); Conv (F32, U32)]; - Vcvt, [InfoWord], All (2, Qreg), "vcvtQ", conv_1, - [Conv (S32, F32); Conv (U32, F32); Conv (F32, S32); Conv (F32, U32)]; -+ Vcvt, [Builtin_name "vcvt" ; Requires_FP_bit 1], -+ Use_operands [| Dreg; Qreg; |], "vcvt", conv_1, [Conv (F16, F32)]; -+ Vcvt, [Builtin_name "vcvt" ; Requires_FP_bit 1], -+ Use_operands [| Qreg; Dreg; |], "vcvt", conv_1, [Conv (F32, F16)]; - Vcvt_n, [InfoWord], Use_operands [| Dreg; Dreg; Immed |], "vcvt_n", conv_2, - [Conv (S32, F32); Conv (U32, F32); Conv (F32, S32); Conv (F32, U32)]; - Vcvt_n, [InfoWord], Use_operands [| Qreg; Qreg; Immed |], "vcvtQ_n", conv_2, -@@ -1387,9 +1464,15 @@ - [S16; S32]; - - (* Vector extract. *) -+ Vext, [Requires_feature "CRYPTO"; Const_valuator (fun _ -> 0)], -+ Use_operands [| Dreg; Dreg; Dreg; Immed |], "vext", extend, -+ [P64]; - Vext, [Const_valuator (fun _ -> 0)], - Use_operands [| Dreg; Dreg; Dreg; Immed |], "vext", extend, - pf_su_8_64; -+ Vext, [Requires_feature "CRYPTO"; Const_valuator (fun _ -> 0)], -+ Use_operands [| Qreg; Qreg; Qreg; Immed |], "vextQ", extend, -+ [P64]; - Vext, [Const_valuator (fun _ -> 0)], - Use_operands [| Qreg; Qreg; Qreg; Immed |], "vextQ", extend, - pf_su_8_64; -@@ -1410,11 +1493,21 @@ - - (* Bit selection. *) - Vbsl, -+ [Requires_feature "CRYPTO"; Instruction_name ["vbsl"; "vbit"; "vbif"]; -+ Disassembles_as [Use_operands [| Dreg; Dreg; Dreg |]]], -+ Use_operands [| Dreg; Dreg; Dreg; Dreg |], "vbsl", bit_select, -+ [P64]; -+ Vbsl, - [Instruction_name ["vbsl"; "vbit"; "vbif"]; - Disassembles_as [Use_operands [| Dreg; Dreg; Dreg |]]], - Use_operands [| Dreg; Dreg; Dreg; Dreg |], "vbsl", bit_select, - pf_su_8_64; - Vbsl, -+ [Requires_feature "CRYPTO"; Instruction_name ["vbsl"; "vbit"; "vbif"]; -+ Disassembles_as [Use_operands [| Qreg; Qreg; Qreg |]]], -+ Use_operands [| Qreg; Qreg; Qreg; Qreg |], "vbslQ", bit_select, -+ [P64]; -+ Vbsl, - [Instruction_name ["vbsl"; "vbit"; "vbif"]; - Disassembles_as [Use_operands [| Qreg; Qreg; Qreg |]]], - Use_operands [| Qreg; Qreg; Qreg; Qreg |], "vbslQ", bit_select, -@@ -1436,10 +1529,21 @@ - - (* Element/structure loads. VLD1 variants. *) - Vldx 1, -+ [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ CstPtrTo Corereg |]]], -+ Use_operands [| Dreg; CstPtrTo Corereg |], "vld1", bits_1, -+ [P64]; -+ Vldx 1, - [Disassembles_as [Use_operands [| VecArray (1, Dreg); - CstPtrTo Corereg |]]], - Use_operands [| Dreg; CstPtrTo Corereg |], "vld1", bits_1, - pf_su_8_64; -+ Vldx 1, [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (2, Dreg); -+ CstPtrTo Corereg |]]], -+ Use_operands [| Qreg; CstPtrTo Corereg |], "vld1Q", bits_1, -+ [P64]; - Vldx 1, [Disassembles_as [Use_operands [| VecArray (2, Dreg); - CstPtrTo Corereg |]]], - Use_operands [| Qreg; CstPtrTo Corereg |], "vld1Q", bits_1, -@@ -1451,6 +1555,13 @@ - Use_operands [| Dreg; CstPtrTo Corereg; Dreg; Immed |], - "vld1_lane", bits_3, pf_su_8_32; - Vldx_lane 1, -+ [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ CstPtrTo Corereg |]]; -+ Const_valuator (fun _ -> 0)], -+ Use_operands [| Dreg; CstPtrTo Corereg; Dreg; Immed |], -+ "vld1_lane", bits_3, [P64]; -+ Vldx_lane 1, - [Disassembles_as [Use_operands [| VecArray (1, Dreg); - CstPtrTo Corereg |]]; - Const_valuator (fun _ -> 0)], -@@ -1462,6 +1573,12 @@ - Use_operands [| Qreg; CstPtrTo Corereg; Qreg; Immed |], - "vld1Q_lane", bits_3, pf_su_8_32; - Vldx_lane 1, -+ [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ CstPtrTo Corereg |]]], -+ Use_operands [| Qreg; CstPtrTo Corereg; Qreg; Immed |], -+ "vld1Q_lane", bits_3, [P64]; -+ Vldx_lane 1, - [Disassembles_as [Use_operands [| VecArray (1, Dreg); - CstPtrTo Corereg |]]], - Use_operands [| Qreg; CstPtrTo Corereg; Qreg; Immed |], -@@ -1473,6 +1590,12 @@ - Use_operands [| Dreg; CstPtrTo Corereg |], "vld1_dup", - bits_1, pf_su_8_32; - Vldx_dup 1, -+ [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ CstPtrTo Corereg |]]], -+ Use_operands [| Dreg; CstPtrTo Corereg |], "vld1_dup", -+ bits_1, [P64]; -+ Vldx_dup 1, - [Disassembles_as [Use_operands [| VecArray (1, Dreg); - CstPtrTo Corereg |]]], - Use_operands [| Dreg; CstPtrTo Corereg |], "vld1_dup", -@@ -1485,6 +1608,12 @@ - (* Treated identically to vld1_dup above as we now - do a single load followed by a duplicate. *) - Vldx_dup 1, -+ [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ CstPtrTo Corereg |]]], -+ Use_operands [| Qreg; CstPtrTo Corereg |], "vld1Q_dup", -+ bits_1, [P64]; -+ Vldx_dup 1, - [Disassembles_as [Use_operands [| VecArray (1, Dreg); - CstPtrTo Corereg |]]], - Use_operands [| Qreg; CstPtrTo Corereg |], "vld1Q_dup", -@@ -1491,10 +1620,20 @@ - bits_1, [S64; U64]; - - (* VST1 variants. *) -+ Vstx 1, [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ PtrTo Corereg |]]], -+ Use_operands [| PtrTo Corereg; Dreg |], "vst1", -+ store_1, [P64]; - Vstx 1, [Disassembles_as [Use_operands [| VecArray (1, Dreg); - PtrTo Corereg |]]], - Use_operands [| PtrTo Corereg; Dreg |], "vst1", - store_1, pf_su_8_64; -+ Vstx 1, [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (2, Dreg); -+ PtrTo Corereg |]]], -+ Use_operands [| PtrTo Corereg; Qreg |], "vst1Q", -+ store_1, [P64]; - Vstx 1, [Disassembles_as [Use_operands [| VecArray (2, Dreg); - PtrTo Corereg |]]], - Use_operands [| PtrTo Corereg; Qreg |], "vst1Q", -@@ -1506,6 +1645,13 @@ - Use_operands [| PtrTo Corereg; Dreg; Immed |], - "vst1_lane", store_3, pf_su_8_32; - Vstx_lane 1, -+ [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ CstPtrTo Corereg |]]; -+ Const_valuator (fun _ -> 0)], -+ Use_operands [| PtrTo Corereg; Dreg; Immed |], -+ "vst1_lane", store_3, [P64]; -+ Vstx_lane 1, - [Disassembles_as [Use_operands [| VecArray (1, Dreg); - CstPtrTo Corereg |]]; - Const_valuator (fun _ -> 0)], -@@ -1517,6 +1663,12 @@ - Use_operands [| PtrTo Corereg; Qreg; Immed |], - "vst1Q_lane", store_3, pf_su_8_32; - Vstx_lane 1, -+ [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (1, Dreg); -+ CstPtrTo Corereg |]]], -+ Use_operands [| PtrTo Corereg; Qreg; Immed |], -+ "vst1Q_lane", store_3, [P64]; -+ Vstx_lane 1, - [Disassembles_as [Use_operands [| VecArray (1, Dreg); - CstPtrTo Corereg |]]], - Use_operands [| PtrTo Corereg; Qreg; Immed |], -@@ -1525,6 +1677,9 @@ - (* VLD2 variants. *) - Vldx 2, [], Use_operands [| VecArray (2, Dreg); CstPtrTo Corereg |], - "vld2", bits_1, pf_su_8_32; -+ Vldx 2, [Requires_feature "CRYPTO"; Instruction_name ["vld1"]], -+ Use_operands [| VecArray (2, Dreg); CstPtrTo Corereg |], -+ "vld2", bits_1, [P64]; - Vldx 2, [Instruction_name ["vld1"]], - Use_operands [| VecArray (2, Dreg); CstPtrTo Corereg |], - "vld2", bits_1, [S64; U64]; -@@ -1556,6 +1711,12 @@ - Use_operands [| VecArray (2, Dreg); CstPtrTo Corereg |], - "vld2_dup", bits_1, pf_su_8_32; - Vldx_dup 2, -+ [Requires_feature "CRYPTO"; -+ Instruction_name ["vld1"]; Disassembles_as [Use_operands -+ [| VecArray (2, Dreg); CstPtrTo Corereg |]]], -+ Use_operands [| VecArray (2, Dreg); CstPtrTo Corereg |], -+ "vld2_dup", bits_1, [P64]; -+ Vldx_dup 2, - [Instruction_name ["vld1"]; Disassembles_as [Use_operands - [| VecArray (2, Dreg); CstPtrTo Corereg |]]], - Use_operands [| VecArray (2, Dreg); CstPtrTo Corereg |], -@@ -1566,6 +1727,12 @@ - PtrTo Corereg |]]], - Use_operands [| PtrTo Corereg; VecArray (2, Dreg) |], "vst2", - store_1, pf_su_8_32; -+ Vstx 2, [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (2, Dreg); -+ PtrTo Corereg |]]; -+ Instruction_name ["vst1"]], -+ Use_operands [| PtrTo Corereg; VecArray (2, Dreg) |], "vst2", -+ store_1, [P64]; - Vstx 2, [Disassembles_as [Use_operands [| VecArray (2, Dreg); - PtrTo Corereg |]]; - Instruction_name ["vst1"]], -@@ -1594,6 +1761,9 @@ - (* VLD3 variants. *) - Vldx 3, [], Use_operands [| VecArray (3, Dreg); CstPtrTo Corereg |], - "vld3", bits_1, pf_su_8_32; -+ Vldx 3, [Requires_feature "CRYPTO"; Instruction_name ["vld1"]], -+ Use_operands [| VecArray (3, Dreg); CstPtrTo Corereg |], -+ "vld3", bits_1, [P64]; - Vldx 3, [Instruction_name ["vld1"]], - Use_operands [| VecArray (3, Dreg); CstPtrTo Corereg |], - "vld3", bits_1, [S64; U64]; -@@ -1625,6 +1795,12 @@ - Use_operands [| VecArray (3, Dreg); CstPtrTo Corereg |], - "vld3_dup", bits_1, pf_su_8_32; - Vldx_dup 3, -+ [Requires_feature "CRYPTO"; -+ Instruction_name ["vld1"]; Disassembles_as [Use_operands -+ [| VecArray (3, Dreg); CstPtrTo Corereg |]]], -+ Use_operands [| VecArray (3, Dreg); CstPtrTo Corereg |], -+ "vld3_dup", bits_1, [P64]; -+ Vldx_dup 3, - [Instruction_name ["vld1"]; Disassembles_as [Use_operands - [| VecArray (3, Dreg); CstPtrTo Corereg |]]], - Use_operands [| VecArray (3, Dreg); CstPtrTo Corereg |], -@@ -1635,6 +1811,12 @@ - PtrTo Corereg |]]], - Use_operands [| PtrTo Corereg; VecArray (3, Dreg) |], "vst3", - store_1, pf_su_8_32; -+ Vstx 3, [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (4, Dreg); -+ PtrTo Corereg |]]; -+ Instruction_name ["vst1"]], -+ Use_operands [| PtrTo Corereg; VecArray (3, Dreg) |], "vst3", -+ store_1, [P64]; - Vstx 3, [Disassembles_as [Use_operands [| VecArray (4, Dreg); - PtrTo Corereg |]]; - Instruction_name ["vst1"]], -@@ -1663,6 +1845,9 @@ - (* VLD4/VST4 variants. *) - Vldx 4, [], Use_operands [| VecArray (4, Dreg); CstPtrTo Corereg |], - "vld4", bits_1, pf_su_8_32; -+ Vldx 4, [Requires_feature "CRYPTO"; Instruction_name ["vld1"]], -+ Use_operands [| VecArray (4, Dreg); CstPtrTo Corereg |], -+ "vld4", bits_1, [P64]; - Vldx 4, [Instruction_name ["vld1"]], - Use_operands [| VecArray (4, Dreg); CstPtrTo Corereg |], - "vld4", bits_1, [S64; U64]; -@@ -1694,6 +1879,12 @@ - Use_operands [| VecArray (4, Dreg); CstPtrTo Corereg |], - "vld4_dup", bits_1, pf_su_8_32; - Vldx_dup 4, -+ [Requires_feature "CRYPTO"; -+ Instruction_name ["vld1"]; Disassembles_as [Use_operands -+ [| VecArray (4, Dreg); CstPtrTo Corereg |]]], -+ Use_operands [| VecArray (4, Dreg); CstPtrTo Corereg |], -+ "vld4_dup", bits_1, [P64]; -+ Vldx_dup 4, - [Instruction_name ["vld1"]; Disassembles_as [Use_operands - [| VecArray (4, Dreg); CstPtrTo Corereg |]]], - Use_operands [| VecArray (4, Dreg); CstPtrTo Corereg |], -@@ -1703,6 +1894,12 @@ - PtrTo Corereg |]]], - Use_operands [| PtrTo Corereg; VecArray (4, Dreg) |], "vst4", - store_1, pf_su_8_32; -+ Vstx 4, [Requires_feature "CRYPTO"; -+ Disassembles_as [Use_operands [| VecArray (4, Dreg); -+ PtrTo Corereg |]]; -+ Instruction_name ["vst1"]], -+ Use_operands [| PtrTo Corereg; VecArray (4, Dreg) |], "vst4", -+ store_1, [P64]; - Vstx 4, [Disassembles_as [Use_operands [| VecArray (4, Dreg); - PtrTo Corereg |]]; - Instruction_name ["vst1"]], -@@ -1754,27 +1951,33 @@ - Vorn, [], All (3, Qreg), "vornQ", notype_2, su_8_64; - ] - -+let type_in_crypto_only t -+ = (t == P64) or (t == P128) ++ if (load && commute) ++ { ++ /* Try reordering registers. */ ++ SWAP_RTX (operands[0], operands[1]); ++ if (operands_ok_ldrd_strd (operands[0], operands[1], base, offset, ++ false, load)) ++ return true; ++ } + -+let cross_product s1 s2 -+ = List.filter (fun (e, e') -> e <> e') -+ (List.concat (List.map (fun e1 -> List.map (fun e2 -> (e1,e2)) s1) s2)) -+ - let reinterp = -- let elems = P8 :: P16 :: F32 :: su_8_64 in -- List.fold_right -- (fun convto acc -> -- let types = List.fold_right -- (fun convfrom acc -> -- if convfrom <> convto then -- Cast (convto, convfrom) :: acc -- else -- acc) -- elems -- [] -- in -- let dconv = Vreinterp, [No_op], Use_operands [| Dreg; Dreg |], -- "vreinterpret", conv_1, types -- and qconv = Vreinterp, [No_op], Use_operands [| Qreg; Qreg |], -- "vreinterpretQ", conv_1, types in -- dconv :: qconv :: acc) -- elems -- [] -+ let elems = P8 :: P16 :: F32 :: P64 :: su_8_64 in -+ let casts = cross_product elems elems in -+ List.map -+ (fun (convto, convfrom) -> -+ Vreinterp, (if (type_in_crypto_only convto) or (type_in_crypto_only convfrom) -+ then [Requires_feature "CRYPTO"] else []) @ [No_op], Use_operands [| Dreg; Dreg |], -+ "vreinterpret", conv_1, [Cast (convto, convfrom)]) -+ casts - -+let reinterpq = -+ let elems = P8 :: P16 :: F32 :: P64 :: P128 :: su_8_64 in -+ let casts = cross_product elems elems in -+ List.map -+ (fun (convto, convfrom) -> -+ Vreinterp, (if (type_in_crypto_only convto) or (type_in_crypto_only convfrom) -+ then [Requires_feature "CRYPTO"] else []) @ [No_op], Use_operands [| Qreg; Qreg |], -+ "vreinterpretQ", conv_1, [Cast (convto, convfrom)]) -+ casts ++ if (const_store) ++ { ++ /* If input registers are dead after this pattern, they can be ++ reordered or replaced by other registers that are free in the ++ current pattern. */ ++ if (!peep2_reg_dead_p (4, operands[0]) ++ || !peep2_reg_dead_p (4, operands[1])) ++ return false; + - (* Output routines. *) - - let rec string_of_elt = function -@@ -1782,7 +1985,8 @@ - | U8 -> "u8" | U16 -> "u16" | U32 -> "u32" | U64 -> "u64" - | I8 -> "i8" | I16 -> "i16" | I32 -> "i32" | I64 -> "i64" - | B8 -> "8" | B16 -> "16" | B32 -> "32" | B64 -> "64" -- | F32 -> "f32" | P8 -> "p8" | P16 -> "p16" -+ | F16 -> "f16" | F32 -> "f32" | P8 -> "p8" | P16 -> "p16" -+ | P64 -> "p64" | P128 -> "p128" - | Conv (a, b) | Cast (a, b) -> string_of_elt a ^ "_" ^ string_of_elt b - | NoElts -> failwith "No elts" - -@@ -1809,6 +2013,7 @@ - | T_uint32x4 -> affix "uint32x4" - | T_uint64x1 -> affix "uint64x1" - | T_uint64x2 -> affix "uint64x2" -+ | T_float16x4 -> affix "float16x4" - | T_float32x2 -> affix "float32x2" - | T_float32x4 -> affix "float32x4" - | T_poly8x8 -> affix "poly8x8" -@@ -1825,6 +2030,11 @@ - | T_uint64 -> affix "uint64" - | T_poly8 -> affix "poly8" - | T_poly16 -> affix "poly16" -+ | T_poly64 -> affix "poly64" -+ | T_poly64x1 -> affix "poly64x1" -+ | T_poly64x2 -> affix "poly64x2" -+ | T_poly128 -> affix "poly128" -+ | T_float16 -> affix "float16" - | T_float32 -> affix "float32" - | T_immediate _ -> "const int" - | T_void -> "void" -@@ -1832,6 +2042,8 @@ - | T_intHI -> "__builtin_neon_hi" - | T_intSI -> "__builtin_neon_si" - | T_intDI -> "__builtin_neon_di" -+ | T_intTI -> "__builtin_neon_ti" -+ | T_floatHF -> "__builtin_neon_hf" - | T_floatSF -> "__builtin_neon_sf" - | T_arrayof (num, base) -> - let basename = name (fun x -> x) base in -@@ -1853,10 +2065,10 @@ - | B_XImode -> "__builtin_neon_xi" - - let string_of_mode = function -- V8QI -> "v8qi" | V4HI -> "v4hi" | V2SI -> "v2si" | V2SF -> "v2sf" -- | DI -> "di" | V16QI -> "v16qi" | V8HI -> "v8hi" | V4SI -> "v4si" -- | V4SF -> "v4sf" | V2DI -> "v2di" | QI -> "qi" | HI -> "hi" | SI -> "si" -- | SF -> "sf" -+ V8QI -> "v8qi" | V4HI -> "v4hi" | V4HF -> "v4hf" | V2SI -> "v2si" -+ | V2SF -> "v2sf" | DI -> "di" | V16QI -> "v16qi" | V8HI -> "v8hi" -+ | V4SI -> "v4si" | V4SF -> "v4sf" | V2DI -> "v2di" | QI -> "qi" -+ | HI -> "hi" | SI -> "si" | SF -> "sf" | TI -> "ti" - - (* Use uppercase chars for letters which form part of the intrinsic name, but - should be omitted from the builtin name (the info is passed in an extra -@@ -1963,3 +2175,181 @@ - | _ -> assert false - with Not_found -> [f shape] - -+(* The crypto intrinsics have unconventional shapes and are not that -+ numerous to be worth the trouble of encoding here. We implement them -+ explicitly here. *) -+let crypto_intrinsics = -+" -+#ifdef __ARM_FEATURE_CRYPTO -+ -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vldrq_p128 (poly128_t const * __ptr) -+{ -+#ifdef __ARM_BIG_ENDIAN -+ poly64_t* __ptmp = (poly64_t*) __ptr; -+ poly64_t __d0 = vld1_p64 (__ptmp); -+ poly64_t __d1 = vld1_p64 (__ptmp + 1); -+ return vreinterpretq_p128_p64 (vcombine_p64 (__d1, __d0)); -+#else -+ return vreinterpretq_p128_p64 (vld1q_p64 ((poly64_t*) __ptr)); -+#endif -+} ++ /* Try to reorder the input registers. */ ++ /* For example, the code ++ mov r0, 0 ++ mov r1, 1 ++ str r1, [r2] ++ str r0, [r2, #4] ++ can be transformed into ++ mov r1, 0 ++ mov r0, 1 ++ strd r0, [r2] ++ */ ++ if (operands_ok_ldrd_strd (operands[1], operands[0], base, offset, ++ false, false)) ++ { ++ SWAP_RTX (operands[0], operands[1]); ++ return true; ++ } + -+__extension__ static __inline void __attribute__ ((__always_inline__)) -+vstrq_p128 (poly128_t * __ptr, poly128_t __val) -+{ -+#ifdef __ARM_BIG_ENDIAN -+ poly64x2_t __tmp = vreinterpretq_p64_p128 (__val); -+ poly64_t __d0 = vget_high_p64 (__tmp); -+ poly64_t __d1 = vget_low_p64 (__tmp); -+ vst1q_p64 ((poly64_t*) __ptr, vcombine_p64 (__d0, __d1)); -+#else -+ vst1q_p64 ((poly64_t*) __ptr, vreinterpretq_p64_p128 (__val)); -+#endif -+} ++ /* Try to find a free DI register. */ ++ CLEAR_HARD_REG_SET (regset); ++ add_to_hard_reg_set (®set, SImode, REGNO (operands[0])); ++ add_to_hard_reg_set (®set, SImode, REGNO (operands[1])); ++ while (true) ++ { ++ tmp = peep2_find_free_register (0, 4, "r", DImode, ®set); ++ if (tmp == NULL_RTX) ++ return false; ++ ++ /* DREG must be an even-numbered register in DImode. ++ Split it into SI registers. */ ++ operands[0] = simplify_gen_subreg (SImode, tmp, DImode, 0); ++ operands[1] = simplify_gen_subreg (SImode, tmp, DImode, 4); ++ gcc_assert (operands[0] != NULL_RTX); ++ gcc_assert (operands[1] != NULL_RTX); ++ gcc_assert (REGNO (operands[0]) % 2 == 0); ++ gcc_assert (REGNO (operands[0]) + 1 == REGNO (operands[1])); + -+/* The vceq_p64 intrinsic does not map to a single instruction. -+ Instead we emulate it by performing a 32-bit variant of the vceq -+ and applying a pairwise min reduction to the result. -+ vceq_u32 will produce two 32-bit halves, each of which will contain either -+ all ones or all zeros depending on whether the corresponding 32-bit -+ halves of the poly64_t were equal. The whole poly64_t values are equal -+ if and only if both halves are equal, i.e. vceq_u32 returns all ones. -+ If the result is all zeroes for any half then the whole result is zeroes. -+ This is what the pairwise min reduction achieves. */ ++ return (operands_ok_ldrd_strd (operands[0], operands[1], ++ base, offset, ++ false, load)); ++ } ++ } + -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vceq_p64 (poly64x1_t __a, poly64x1_t __b) -+{ -+ uint32x2_t __t_a = vreinterpret_u32_p64 (__a); -+ uint32x2_t __t_b = vreinterpret_u32_p64 (__b); -+ uint32x2_t __c = vceq_u32 (__t_a, __t_b); -+ uint32x2_t __m = vpmin_u32 (__c, __c); -+ return vreinterpret_u64_u32 (__m); ++ return false; +} ++#undef SWAP_RTX + -+/* The vtst_p64 intrinsic does not map to a single instruction. -+ We emulate it in way similar to vceq_p64 above but here we do -+ a reduction with max since if any two corresponding bits -+ in the two poly64_t's match, then the whole result must be all ones. */ + -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vtst_p64 (poly64x1_t __a, poly64x1_t __b) -+{ -+ uint32x2_t __t_a = vreinterpret_u32_p64 (__a); -+ uint32x2_t __t_b = vreinterpret_u32_p64 (__b); -+ uint32x2_t __c = vtst_u32 (__t_a, __t_b); -+ uint32x2_t __m = vpmax_u32 (__c, __c); -+ return vreinterpret_u64_u32 (__m); -+} + -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaeseq_u8 (uint8x16_t __data, uint8x16_t __key) -+{ -+ return __builtin_arm_crypto_aese (__data, __key); -+} + + /* Print a symbolic form of X to the debug file, F. */ + static void +@@ -13858,6 +14351,16 @@ + && IN_RANGE (INTVAL (op1), -7, 7)) + action = CONV; + } ++ /* ADCS , */ ++ else if (GET_CODE (XEXP (src, 0)) == PLUS ++ && rtx_equal_p (XEXP (XEXP (src, 0), 0), dst) ++ && low_register_operand (XEXP (XEXP (src, 0), 1), ++ SImode) ++ && COMPARISON_P (op1) ++ && cc_register (XEXP (op1, 0), VOIDmode) ++ && maybe_get_arm_condition_code (op1) == ARM_CS ++ && XEXP (op1, 1) == const0_rtx) ++ action = CONV; + break; + + case MINUS: +@@ -14816,7 +15319,8 @@ + { + /* Constraints should ensure this. */ + gcc_assert (code0 == MEM && code1 == REG); +- gcc_assert (REGNO (operands[1]) != IP_REGNUM); ++ gcc_assert ((REGNO (operands[1]) != IP_REGNUM) ++ || (TARGET_ARM && TARGET_LDRD)); + + switch (GET_CODE (XEXP (operands[0], 0))) + { +@@ -16289,124 +16793,308 @@ + } + } + +-/* Generate and emit a pattern that will be recognized as STRD pattern. If even +- number of registers are being pushed, multiple STRD patterns are created for +- all register pairs. If odd number of registers are pushed, emit a +- combination of STRDs and STR for the prologue saves. */ ++/* Generate and emit a sequence of insns equivalent to PUSH, but using ++ STR and STRD. If an even number of registers are being pushed, one ++ or more STRD patterns are created for each register pair. If an ++ odd number of registers are pushed, emit an initial STR followed by ++ as many STRD instructions as are needed. This works best when the ++ stack is initially 64-bit aligned (the normal case), since it ++ ensures that each STRD is also 64-bit aligned. */ + static void + thumb2_emit_strd_push (unsigned long saved_regs_mask) + { + int num_regs = 0; +- int i, j; ++ int i; ++ int regno; + rtx par = NULL_RTX; +- rtx insn = NULL_RTX; + rtx dwarf = NULL_RTX; +- rtx tmp, reg, tmp1; ++ rtx tmp; ++ bool first = true; + ++ num_regs = bit_count (saved_regs_mask); + -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaesdq_u8 (uint8x16_t __data, uint8x16_t __key) -+{ -+ return __builtin_arm_crypto_aesd (__data, __key); -+} ++ /* Must be at least one register to save, and can't save SP or PC. */ ++ gcc_assert (num_regs > 0 && num_regs <= 14); ++ gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); ++ gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); + -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaesmcq_u8 (uint8x16_t __data) -+{ -+ return __builtin_arm_crypto_aesmc (__data); -+} ++ /* Create sequence for DWARF info. All the frame-related data for ++ debugging is held in this wrapper. */ ++ dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1)); + -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaesimcq_u8 (uint8x16_t __data) -+{ -+ return __builtin_arm_crypto_aesimc (__data); -+} ++ /* Describe the stack adjustment. */ ++ tmp = gen_rtx_SET (VOIDmode, ++ stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (dwarf, 0, 0) = tmp; + -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vsha1h_u32 (uint32_t __hash_e) -+{ -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ __t = __builtin_arm_crypto_sha1h (__t); -+ return vgetq_lane_u32 (__t, 0); -+} ++ /* Find the first register. */ ++ for (regno = 0; (saved_regs_mask & (1 << regno)) == 0; regno++) ++ ; + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha1cq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk) -+{ -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ return __builtin_arm_crypto_sha1c (__hash_abcd, __t, __wk); -+} ++ i = 0; + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha1pq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk) -+{ -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ return __builtin_arm_crypto_sha1p (__hash_abcd, __t, __wk); -+} ++ /* If there's an odd number of registers to push. Start off by ++ pushing a single register. This ensures that subsequent strd ++ operations are dword aligned (assuming that SP was originally ++ 64-bit aligned). */ ++ if ((num_regs & 1) != 0) ++ { ++ rtx reg, mem, insn; + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha1mq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk) -+{ -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ return __builtin_arm_crypto_sha1m (__hash_abcd, __t, __wk); -+} ++ reg = gen_rtx_REG (SImode, regno); ++ if (num_regs == 1) ++ mem = gen_frame_mem (Pmode, gen_rtx_PRE_DEC (Pmode, ++ stack_pointer_rtx)); ++ else ++ mem = gen_frame_mem (Pmode, ++ gen_rtx_PRE_MODIFY ++ (Pmode, stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, ++ -4 * num_regs))); + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha1su0q_u32 (uint32x4_t __w0_3, uint32x4_t __w4_7, uint32x4_t __w8_11) -+{ -+ return __builtin_arm_crypto_sha1su0 (__w0_3, __w4_7, __w8_11); -+} ++ tmp = gen_rtx_SET (VOIDmode, mem, reg); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ insn = emit_insn (tmp); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); ++ tmp = gen_rtx_SET (VOIDmode, gen_frame_mem (Pmode, stack_pointer_rtx), ++ reg); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ i++; ++ regno++; ++ XVECEXP (dwarf, 0, i) = tmp; ++ first = false; ++ } + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha1su1q_u32 (uint32x4_t __tw0_3, uint32x4_t __w12_15) -+{ -+ return __builtin_arm_crypto_sha1su1 (__tw0_3, __w12_15); -+} ++ while (i < num_regs) ++ if (saved_regs_mask & (1 << regno)) ++ { ++ rtx reg1, reg2, mem1, mem2; ++ rtx tmp0, tmp1, tmp2; ++ int regno2; + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha256hq_u32 (uint32x4_t __hash_abcd, uint32x4_t __hash_efgh, uint32x4_t __wk) -+{ -+ return __builtin_arm_crypto_sha256h (__hash_abcd, __hash_efgh, __wk); -+} ++ /* Find the register to pair with this one. */ ++ for (regno2 = regno + 1; (saved_regs_mask & (1 << regno2)) == 0; ++ regno2++) ++ ; + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha256h2q_u32 (uint32x4_t __hash_abcd, uint32x4_t __hash_efgh, uint32x4_t __wk) -+{ -+ return __builtin_arm_crypto_sha256h2 (__hash_abcd, __hash_efgh, __wk); -+} ++ reg1 = gen_rtx_REG (SImode, regno); ++ reg2 = gen_rtx_REG (SImode, regno2); + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha256su0q_u32 (uint32x4_t __w0_3, uint32x4_t __w4_7) -+{ -+ return __builtin_arm_crypto_sha256su0 (__w0_3, __w4_7); -+} ++ if (first) ++ { ++ rtx insn; + -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vsha256su1q_u32 (uint32x4_t __tw0_3, uint32x4_t __w8_11, uint32x4_t __w12_15) -+{ -+ return __builtin_arm_crypto_sha256su1 (__tw0_3, __w8_11, __w12_15); -+} ++ first = false; ++ mem1 = gen_frame_mem (Pmode, plus_constant (Pmode, ++ stack_pointer_rtx, ++ -4 * num_regs)); ++ mem2 = gen_frame_mem (Pmode, plus_constant (Pmode, ++ stack_pointer_rtx, ++ -4 * (num_regs - 1))); ++ tmp0 = gen_rtx_SET (VOIDmode, stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, ++ -4 * (num_regs))); ++ tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1); ++ tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2); ++ RTX_FRAME_RELATED_P (tmp0) = 1; ++ RTX_FRAME_RELATED_P (tmp1) = 1; ++ RTX_FRAME_RELATED_P (tmp2) = 1; ++ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (3)); ++ XVECEXP (par, 0, 0) = tmp0; ++ XVECEXP (par, 0, 1) = tmp1; ++ XVECEXP (par, 0, 2) = tmp2; ++ insn = emit_insn (par); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); ++ } ++ else ++ { ++ mem1 = gen_frame_mem (Pmode, plus_constant (Pmode, ++ stack_pointer_rtx, ++ 4 * i)); ++ mem2 = gen_frame_mem (Pmode, plus_constant (Pmode, ++ stack_pointer_rtx, ++ 4 * (i + 1))); ++ tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1); ++ tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2); ++ RTX_FRAME_RELATED_P (tmp1) = 1; ++ RTX_FRAME_RELATED_P (tmp2) = 1; ++ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); ++ XVECEXP (par, 0, 0) = tmp1; ++ XVECEXP (par, 0, 1) = tmp2; ++ emit_insn (par); ++ } + -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vmull_p64 (poly64_t __a, poly64_t __b) -+{ -+ return (poly128_t) __builtin_arm_crypto_vmullp64 ((uint64_t) __a, (uint64_t) __b); -+} ++ /* Create unwind information. This is an approximation. */ ++ tmp1 = gen_rtx_SET (VOIDmode, ++ gen_frame_mem (Pmode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ 4 * i)), ++ reg1); ++ tmp2 = gen_rtx_SET (VOIDmode, ++ gen_frame_mem (Pmode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ 4 * (i + 1))), ++ reg2); + -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vmull_high_p64 (poly64x2_t __a, poly64x2_t __b) -+{ -+ poly64_t __t1 = vget_high_p64 (__a); -+ poly64_t __t2 = vget_high_p64 (__b); ++ RTX_FRAME_RELATED_P (tmp1) = 1; ++ RTX_FRAME_RELATED_P (tmp2) = 1; ++ XVECEXP (dwarf, 0, i + 1) = tmp1; ++ XVECEXP (dwarf, 0, i + 2) = tmp2; ++ i += 2; ++ regno = regno2 + 1; ++ } ++ else ++ regno++; + -+ return (poly128_t) __builtin_arm_crypto_vmullp64 ((uint64_t) __t1, (uint64_t) __t2); ++ return; +} + -+#endif -+" ---- a/src/gcc/config/arm/constraints.md -+++ b/src/gcc/config/arm/constraints.md -@@ -21,7 +21,7 @@ - ;; The following register constraints have been used: - ;; - in ARM/Thumb-2 state: t, w, x, y, z - ;; - in Thumb state: h, b --;; - in both states: l, c, k -+;; - in both states: l, c, k, q, US - ;; In ARM state, 'l' is an alias for 'r' - ;; 'f' and 'v' were previously used for FPA and MAVERICK registers. - -@@ -86,6 +86,9 @@ - (define_register_constraint "k" "STACK_REG" - "@internal The stack register.") - -+(define_register_constraint "q" "(TARGET_ARM && TARGET_LDRD) ? CORE_REGS : GENERAL_REGS" -+ "@internal In ARM state with LDRD support, core registers, otherwise general registers.") ++/* STRD in ARM mode requires consecutive registers. This function emits STRD ++ whenever possible, otherwise it emits single-word stores. The first store ++ also allocates stack space for all saved registers, using writeback with ++ post-addressing mode. All other stores use offset addressing. If no STRD ++ can be emitted, this function emits a sequence of single-word stores, ++ and not an STM as before, because single-word stores provide more freedom ++ scheduling and can be turned into an STM by peephole optimizations. */ ++static void ++arm_emit_strd_push (unsigned long saved_regs_mask) ++{ ++ int num_regs = 0; ++ int i, j, dwarf_index = 0; ++ int offset = 0; ++ rtx dwarf = NULL_RTX; ++ rtx insn = NULL_RTX; ++ rtx tmp, mem; + - (define_register_constraint "b" "TARGET_THUMB ? BASE_REGS : NO_REGS" - "@internal - Thumb only. The union of the low registers and the stack register.") -@@ -93,6 +96,9 @@ - (define_register_constraint "c" "CC_REG" - "@internal The condition code register.") ++ /* TODO: A more efficient code can be emitted by changing the ++ layout, e.g., first push all pairs that can use STRD to keep the ++ stack aligned, and then push all other registers. */ + for (i = 0; i <= LAST_ARM_REGNUM; i++) + if (saved_regs_mask & (1 << i)) + num_regs++; -+(define_register_constraint "Cs" "CALLER_SAVE_REGS" -+ "@internal The caller save registers. Useful for sibcalls.") -+ - (define_constraint "I" - "In ARM/Thumb-2 state a constant that can be used as an immediate value in a - Data Processing instruction. In Thumb-1 state a constant in the range -@@ -164,9 +170,9 @@ - && ival > 1020 && ival <= 1275"))) +- gcc_assert (num_regs && num_regs <= 16); ++ gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); ++ gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); ++ gcc_assert (num_regs > 0); - (define_constraint "Pd" -- "@internal In Thumb-1 state a constant in the range 0 to 7" -+ "@internal In Thumb state a constant in the range 0 to 7" - (and (match_code "const_int") -- (match_test "TARGET_THUMB1 && ival >= 0 && ival <= 7"))) -+ (match_test "TARGET_THUMB && ival >= 0 && ival <= 7"))) +- /* Pre-decrement the stack pointer, based on there being num_regs 4-byte +- registers to push. */ +- tmp = gen_rtx_SET (VOIDmode, +- stack_pointer_rtx, +- plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); +- RTX_FRAME_RELATED_P (tmp) = 1; +- insn = emit_insn (tmp); +- + /* Create sequence for DWARF info. */ + dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1)); - (define_constraint "Pe" - "@internal In Thumb-1 state a constant in the range 256 to +510" -@@ -208,6 +214,11 @@ - (and (match_code "const_int") - (match_test "TARGET_THUMB2 && ival >= 0 && ival <= 255"))) +- /* RTLs cannot be shared, hence create new copy for dwarf. */ +- tmp1 = gen_rtx_SET (VOIDmode, ++ /* For dwarf info, we generate explicit stack update. */ ++ tmp = gen_rtx_SET (VOIDmode, + stack_pointer_rtx, + plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); +- RTX_FRAME_RELATED_P (tmp1) = 1; +- XVECEXP (dwarf, 0, 0) = tmp1; ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (dwarf, 0, dwarf_index++) = tmp; + +- gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); +- gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); +- +- /* Var j iterates over all the registers to gather all the registers in +- saved_regs_mask. Var i gives index of register R_j in stack frame. +- A PARALLEL RTX of register-pair is created here, so that pattern for +- STRD can be matched. If num_regs is odd, 1st register will be pushed +- using STR and remaining registers will be pushed with STRD in pairs. +- If num_regs is even, all registers are pushed with STRD in pairs. +- Hence, skip first element for odd num_regs. */ +- for (i = num_regs - 1, j = LAST_ARM_REGNUM; i >= (num_regs % 2); j--) ++ /* Save registers. */ ++ offset = - 4 * num_regs; ++ j = 0; ++ while (j <= LAST_ARM_REGNUM) + if (saved_regs_mask & (1 << j)) + { +- /* Create RTX for store. New RTX is created for dwarf as +- they are not sharable. */ +- reg = gen_rtx_REG (SImode, j); +- tmp = gen_rtx_SET (SImode, +- gen_frame_mem +- (SImode, +- plus_constant (Pmode, stack_pointer_rtx, 4 * i)), +- reg); ++ if ((j % 2 == 0) ++ && (saved_regs_mask & (1 << (j + 1)))) ++ { ++ /* Current register and previous register form register pair for ++ which STRD can be generated. */ ++ if (offset < 0) ++ { ++ /* Allocate stack space for all saved registers. */ ++ tmp = plus_constant (Pmode, stack_pointer_rtx, offset); ++ tmp = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, tmp); ++ mem = gen_frame_mem (DImode, tmp); ++ offset = 0; ++ } ++ else if (offset > 0) ++ mem = gen_frame_mem (DImode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ offset)); ++ else ++ mem = gen_frame_mem (DImode, stack_pointer_rtx); -+(define_constraint "Pz" -+ "@internal In Thumb-2 state the constant 0" -+ (and (match_code "const_int") -+ (match_test "TARGET_THUMB2 && (ival == 0)"))) -+ - (define_constraint "G" - "In ARM/Thumb-2 state the floating-point constant 0." - (and (match_code "const_double") -@@ -248,6 +259,24 @@ - (and (match_code "const_int") - (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)"))) +- tmp1 = gen_rtx_SET (SImode, +- gen_frame_mem +- (SImode, +- plus_constant (Pmode, stack_pointer_rtx, 4 * i)), +- reg); +- RTX_FRAME_RELATED_P (tmp) = 1; +- RTX_FRAME_RELATED_P (tmp1) = 1; ++ tmp = gen_rtx_SET (DImode, mem, gen_rtx_REG (DImode, j)); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ tmp = emit_insn (tmp); -+(define_constraint "De" -+ "@internal -+ In ARM/Thumb-2 state a const_int that can be used by insn anddi." -+ (and (match_code "const_int") -+ (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)"))) -+ -+(define_constraint "Df" -+ "@internal -+ In ARM/Thumb-2 state a const_int that can be used by insn iordi." -+ (and (match_code "const_int") -+ (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, IOR)"))) -+ -+(define_constraint "Dg" -+ "@internal -+ In ARM/Thumb-2 state a const_int that can be used by insn xordi." -+ (and (match_code "const_int") -+ (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, XOR)"))) -+ - (define_constraint "Di" - "@internal - In ARM/Thumb-2 state a const_int or const_double where both the high -@@ -305,6 +334,9 @@ - (and (match_code "const_double") - (match_test "TARGET_32BIT && TARGET_VFP && vfp3_const_double_for_fract_bits (op)"))) +- if (((i - (num_regs % 2)) % 2) == 1) +- /* When (i - (num_regs % 2)) is odd, the RTX to be emitted is yet to +- be created. Hence create it first. The STRD pattern we are +- generating is : +- [ (SET (MEM (PLUS (SP) (NUM))) (reg_t1)) +- (SET (MEM (PLUS (SP) (NUM + 4))) (reg_t2)) ] +- where the target registers need not be consecutive. */ +- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); ++ /* Record the first store insn. */ ++ if (dwarf_index == 1) ++ insn = tmp; -+(define_register_constraint "Ts" "(arm_restrict_it) ? LO_REGS : GENERAL_REGS" -+ "For arm_restrict_it the core registers @code{r0}-@code{r7}. GENERAL_REGS otherwise.") -+ - (define_memory_constraint "Ua" - "@internal - An address valid for loading/storing register exclusive" -@@ -385,6 +417,12 @@ - 0) - && GET_CODE (XEXP (op, 0)) != POST_INC"))) +- /* Register R_j is added in PARALLEL RTX. If (i - (num_regs % 2)) is +- even, the reg_j is added as 0th element and if it is odd, reg_i is +- added as 1st element of STRD pattern shown above. */ +- XVECEXP (par, 0, ((i - (num_regs % 2)) % 2)) = tmp; +- XVECEXP (dwarf, 0, (i + 1)) = tmp1; ++ /* Generate dwarf info. */ ++ mem = gen_frame_mem (SImode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ offset)); ++ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j)); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (dwarf, 0, dwarf_index++) = tmp; -+(define_constraint "US" -+ "@internal -+ US is a symbol reference." -+ (match_code "symbol_ref") -+) -+ - ;; We used to have constraint letters for S and R in ARM state, but - ;; all uses of these now appear to have been removed. +- if (((i - (num_regs % 2)) % 2) == 0) +- /* When (i - (num_regs % 2)) is even, RTXs for both the registers +- to be loaded are generated in above given STRD pattern, and the +- pattern can be emitted now. */ +- emit_insn (par); ++ mem = gen_frame_mem (SImode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ offset + 4)); ++ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j + 1)); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (dwarf, 0, dwarf_index++) = tmp; -@@ -391,3 +429,4 @@ - ;; Additionally, we used to have a Q constraint in Thumb state, but - ;; this wasn't really a valid memory constraint. Again, all uses of - ;; this now seem to have been removed. -+ ---- a/src/gcc/config/arm/cortex-a7.md -+++ b/src/gcc/config/arm/cortex-a7.md -@@ -88,9 +88,9 @@ - ;; ALU instruction with an immediate operand can dual-issue. - (define_insn_reservation "cortex_a7_alu_imm" 2 - (and (eq_attr "tune" "cortexa7") -- (and (ior (eq_attr "type" "simple_alu_imm") -- (ior (eq_attr "type" "simple_alu_shift") -- (and (eq_attr "insn" "mov") -+ (and (ior (eq_attr "type" "arlo_imm,mov_imm,mvn_imm") -+ (ior (eq_attr "type" "extend") -+ (and (eq_attr "type" "mov_reg,mov_shift,mov_shift_reg") - (not (eq_attr "length" "8"))))) - (eq_attr "neon_type" "none"))) - "cortex_a7_ex2|cortex_a7_ex1") -@@ -99,13 +99,15 @@ - ;; with a younger immediate-based instruction. - (define_insn_reservation "cortex_a7_alu_reg" 2 - (and (eq_attr "tune" "cortexa7") -- (and (eq_attr "type" "alu_reg") -+ (and (eq_attr "type" "arlo_reg,shift,shift_reg,mov_reg,mvn_reg") - (eq_attr "neon_type" "none"))) - "cortex_a7_ex1") +- i--; +- } ++ offset += 8; ++ j += 2; ++ } ++ else ++ { ++ /* Emit a single word store. */ ++ if (offset < 0) ++ { ++ /* Allocate stack space for all saved registers. */ ++ tmp = plus_constant (Pmode, stack_pointer_rtx, offset); ++ tmp = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, tmp); ++ mem = gen_frame_mem (SImode, tmp); ++ offset = 0; ++ } ++ else if (offset > 0) ++ mem = gen_frame_mem (SImode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ offset)); ++ else ++ mem = gen_frame_mem (SImode, stack_pointer_rtx); - (define_insn_reservation "cortex_a7_alu_shift" 2 - (and (eq_attr "tune" "cortexa7") -- (and (eq_attr "type" "alu_shift,alu_shift_reg") -+ (and (eq_attr "type" "arlo_shift,arlo_shift_reg,\ -+ mov_shift,mov_shift_reg,\ -+ mvn_shift,mvn_shift_reg") - (eq_attr "neon_type" "none"))) - "cortex_a7_ex1") +- if ((num_regs % 2) == 1) +- { +- /* If odd number of registers are pushed, generate STR pattern to store +- lone register. */ +- for (; (saved_regs_mask & (1 << j)) == 0; j--); ++ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j)); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ tmp = emit_insn (tmp); -@@ -127,8 +129,9 @@ +- tmp1 = gen_frame_mem (SImode, plus_constant (Pmode, +- stack_pointer_rtx, 4 * i)); +- reg = gen_rtx_REG (SImode, j); +- tmp = gen_rtx_SET (SImode, tmp1, reg); +- RTX_FRAME_RELATED_P (tmp) = 1; ++ /* Record the first store insn. */ ++ if (dwarf_index == 1) ++ insn = tmp; - (define_insn_reservation "cortex_a7_mul" 2 - (and (eq_attr "tune" "cortexa7") -- (and (eq_attr "type" "mult") -- (eq_attr "neon_type" "none"))) -+ (and (eq_attr "neon_type" "none") -+ (ior (eq_attr "mul32" "yes") -+ (eq_attr "mul64" "yes")))) - "cortex_a7_both") +- emit_insn (tmp); ++ /* Generate dwarf info. */ ++ mem = gen_frame_mem (SImode, ++ plus_constant(Pmode, ++ stack_pointer_rtx, ++ offset)); ++ tmp = gen_rtx_SET (SImode, mem, gen_rtx_REG (SImode, j)); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (dwarf, 0, dwarf_index++) = tmp; - ;; Forward the result of a multiply operation to the accumulator -@@ -140,7 +143,7 @@ - ;; The latency depends on the operands, so we use an estimate here. - (define_insn_reservation "cortex_a7_idiv" 5 - (and (eq_attr "tune" "cortexa7") -- (eq_attr "insn" "udiv,sdiv")) -+ (eq_attr "type" "udiv,sdiv")) - "cortex_a7_both*5") +- tmp1 = gen_rtx_SET (SImode, +- gen_frame_mem +- (SImode, +- plus_constant (Pmode, stack_pointer_rtx, 4 * i)), +- reg); +- RTX_FRAME_RELATED_P (tmp1) = 1; +- XVECEXP (dwarf, 0, (i + 1)) = tmp1; +- } ++ offset += 4; ++ j += 1; ++ } ++ } ++ else ++ j++; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ---- a/src/gcc/config/arm/arm-arches.def -+++ b/src/gcc/config/arm/arm-arches.def -@@ -53,6 +53,7 @@ - ARM_ARCH("armv7-r", cortexr4, 7R, FL_CO_PROC | FL_FOR_ARCH7R) - ARM_ARCH("armv7-m", cortexm3, 7M, FL_CO_PROC | FL_FOR_ARCH7M) - ARM_ARCH("armv7e-m", cortexm4, 7EM, FL_CO_PROC | FL_FOR_ARCH7EM) --ARM_ARCH("armv8-a", cortexa15, 8A, FL_CO_PROC | FL_FOR_ARCH8A) -+ARM_ARCH("armv8-a", cortexa53, 8A, FL_CO_PROC | FL_FOR_ARCH8A) -+ARM_ARCH("armv8-a+crc",cortexa53, 8A,FL_CO_PROC | FL_CRC32 | FL_FOR_ARCH8A) - ARM_ARCH("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT) - ARM_ARCH("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2) ---- a/src/gcc/config/arm/t-arm -+++ b/src/gcc/config/arm/t-arm -@@ -39,6 +39,7 @@ - $(srcdir)/config/arm/cortex-a8-neon.md \ - $(srcdir)/config/arm/cortex-a9.md \ - $(srcdir)/config/arm/cortex-a9-neon.md \ -+ $(srcdir)/config/arm/cortex-a53.md \ - $(srcdir)/config/arm/cortex-m4-fpu.md \ - $(srcdir)/config/arm/cortex-m4.md \ - $(srcdir)/config/arm/cortex-r4f.md \ -@@ -52,6 +53,7 @@ - $(srcdir)/config/arm/iwmmxt.md \ - $(srcdir)/config/arm/iwmmxt2.md \ - $(srcdir)/config/arm/ldmstm.md \ -+ $(srcdir)/config/arm/ldrdstrd.md \ - $(srcdir)/config/arm/marvell-f-iwmmxt.md \ - $(srcdir)/config/arm/neon.md \ - $(srcdir)/config/arm/predicates.md \ -@@ -84,7 +86,8 @@ - $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ - $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ - intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) $(srcdir)/config/arm/arm-cores.def \ -- $(srcdir)/config/arm/arm-arches.def $(srcdir)/config/arm/arm-fpus.def -+ $(srcdir)/config/arm/arm-arches.def $(srcdir)/config/arm/arm-fpus.def \ -+ $(srcdir)/config/arm/arm_neon_builtins.def ++ /* Attach dwarf info to the first insn we generate. */ ++ gcc_assert (insn != NULL_RTX); + add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); + RTX_FRAME_RELATED_P (insn) = 1; +- return; + } - arm-c.o: $(srcdir)/config/arm/arm-c.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) ---- a/src/gcc/config/arm/arm.opt -+++ b/src/gcc/config/arm/arm.opt -@@ -239,6 +239,10 @@ - Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS) - Only generate absolute relocations on word sized values. + /* Generate and emit an insn that we will recognize as a push_multi. +@@ -16551,6 +17239,19 @@ + return par; + } -+mrestrict-it -+Target Report Var(arm_restrict_it) Init(2) -+Generate IT blocks appropriate for ARMv8. ++/* Add a REG_CFA_ADJUST_CFA REG note to INSN. ++ SIZE is the offset to be adjusted. ++ DEST and SRC might be stack_pointer_rtx or hard_frame_pointer_rtx. */ ++static void ++arm_add_cfa_adjust_cfa_note (rtx insn, int size, rtx dest, rtx src) ++{ ++ rtx dwarf; + - mfix-cortex-m3-ldrd - Target Report Var(fix_cm3_ldrd) Init(2) - Avoid overlapping destination and address registers on LDRD instructions -@@ -247,3 +251,7 @@ - munaligned-access - Target Report Var(unaligned_access) Init(2) - Enable unaligned word and halfword accesses to packed data. ++ RTX_FRAME_RELATED_P (insn) = 1; ++ dwarf = gen_rtx_SET (VOIDmode, dest, plus_constant (Pmode, src, size)); ++ add_reg_note (insn, REG_CFA_ADJUST_CFA, dwarf); ++} + -+mneon-for-64bits -+Target Report RejectNegative Var(use_neon_for_64bits) Init(0) -+Use Neon to perform 64-bits operations rather than core registers. ---- a/src/gcc/config/arm/arm926ejs.md -+++ b/src/gcc/config/arm/arm926ejs.md -@@ -58,7 +58,9 @@ - ;; ALU operations with no shifted operand - (define_insn_reservation "9_alu_op" 1 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "type" "alu_reg,simple_alu_imm,simple_alu_shift,alu_shift")) -+ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,arlo_shift,\ -+ mov_imm,mov_reg,mov_shift,\ -+ mvn_imm,mvn_reg,mvn_shift")) - "e,m,w") + /* Generate and emit an insn pattern that we will recognize as a pop_multi. + SAVED_REGS_MASK shows which registers need to be restored. - ;; ALU operations with a shift-by-register operand -@@ -67,7 +69,7 @@ - ;; the execute stage. - (define_insn_reservation "9_alu_shift_reg_op" 2 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "type" "alu_shift_reg")) -+ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) - "e*2,m,w") +@@ -16608,6 +17309,17 @@ + if (saved_regs_mask & (1 << i)) + { + reg = gen_rtx_REG (SImode, i); ++ if ((num_regs == 1) && emit_update && !return_in_pc) ++ { ++ /* Emit single load with writeback. */ ++ tmp = gen_frame_mem (SImode, ++ gen_rtx_POST_INC (Pmode, ++ stack_pointer_rtx)); ++ tmp = emit_insn (gen_rtx_SET (VOIDmode, reg, tmp)); ++ REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); ++ return; ++ } ++ + tmp = gen_rtx_SET (VOIDmode, + reg, + gen_frame_mem +@@ -16630,6 +17342,9 @@ + par = emit_insn (par); - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@@ -81,32 +83,32 @@ + REG_NOTES (par) = dwarf; ++ if (!return_in_pc) ++ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD * num_regs, ++ stack_pointer_rtx, stack_pointer_rtx); + } - (define_insn_reservation "9_mult1" 3 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "insn" "smlalxy,mul,mla")) -+ (eq_attr "type" "smlalxy,mul,mla")) - "e*2,m,w") + /* Generate and emit an insn pattern that we will recognize as a pop_multi +@@ -16700,6 +17415,9 @@ - (define_insn_reservation "9_mult2" 4 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "insn" "muls,mlas")) -+ (eq_attr "type" "muls,mlas")) - "e*3,m,w") + par = emit_insn (par); + REG_NOTES (par) = dwarf; ++ ++ arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs, ++ base_reg, base_reg); + } - (define_insn_reservation "9_mult3" 4 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "insn" "umull,umlal,smull,smlal")) -+ (eq_attr "type" "umull,umlal,smull,smlal")) - "e*3,m,w") + /* Generate and emit a pattern that will be recognized as LDRD pattern. If even +@@ -16775,6 +17493,7 @@ + pattern can be emitted now. */ + par = emit_insn (par); + REG_NOTES (par) = dwarf; ++ RTX_FRAME_RELATED_P (par) = 1; + } - (define_insn_reservation "9_mult4" 5 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "insn" "umulls,umlals,smulls,smlals")) -+ (eq_attr "type" "umulls,umlals,smulls,smlals")) - "e*4,m,w") + i++; +@@ -16791,7 +17510,12 @@ + stack_pointer_rtx, + plus_constant (Pmode, stack_pointer_rtx, 4 * i)); + RTX_FRAME_RELATED_P (tmp) = 1; +- emit_insn (tmp); ++ tmp = emit_insn (tmp); ++ if (!return_in_pc) ++ { ++ arm_add_cfa_adjust_cfa_note (tmp, UNITS_PER_WORD * i, ++ stack_pointer_rtx, stack_pointer_rtx); ++ } - (define_insn_reservation "9_mult5" 2 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "insn" "smulxy,smlaxy,smlawx")) -+ (eq_attr "type" "smulxy,smlaxy,smlawx")) - "e,m,w") + dwarf = NULL_RTX; - (define_insn_reservation "9_mult6" 3 - (and (eq_attr "tune" "arm926ejs") -- (eq_attr "insn" "smlalxy")) -+ (eq_attr "type" "smlalxy")) - "e*2,m,w") +@@ -16825,9 +17549,11 @@ + else + { + par = emit_insn (tmp); ++ REG_NOTES (par) = dwarf; ++ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD, ++ stack_pointer_rtx, stack_pointer_rtx); + } - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ---- a/src/gcc/config/arm/ldrdstrd.md -+++ b/src/gcc/config/arm/ldrdstrd.md -@@ -0,0 +1,260 @@ -+;; ARM ldrd/strd peephole optimizations. -+;; -+;; Copyright (C) 2013 Free Software Foundation, Inc. -+;; -+;; Written by Greta Yorsh +- REG_NOTES (par) = dwarf; + } + else if ((num_regs % 2) == 1 && return_in_pc) + { +@@ -16839,6 +17565,132 @@ + return; + } + ++/* LDRD in ARM mode needs consecutive registers as operands. This function ++ emits LDRD whenever possible, otherwise it emits single-word loads. It uses ++ offset addressing and then generates one separate stack udpate. This provides ++ more scheduling freedom, compared to writeback on every load. However, ++ if the function returns using load into PC directly ++ (i.e., if PC is in SAVED_REGS_MASK), the stack needs to be updated ++ before the last load. TODO: Add a peephole optimization to recognize ++ the new epilogue sequence as an LDM instruction whenever possible. TODO: Add ++ peephole optimization to merge the load at stack-offset zero ++ with the stack update instruction using load with writeback ++ in post-index addressing mode. */ ++static void ++arm_emit_ldrd_pop (unsigned long saved_regs_mask) ++{ ++ int j = 0; ++ int offset = 0; ++ rtx par = NULL_RTX; ++ rtx dwarf = NULL_RTX; ++ rtx tmp, mem; ++ ++ /* Restore saved registers. */ ++ gcc_assert (!((saved_regs_mask & (1 << SP_REGNUM)))); ++ j = 0; ++ while (j <= LAST_ARM_REGNUM) ++ if (saved_regs_mask & (1 << j)) ++ { ++ if ((j % 2) == 0 ++ && (saved_regs_mask & (1 << (j + 1))) ++ && (j + 1) != PC_REGNUM) ++ { ++ /* Current register and next register form register pair for which ++ LDRD can be generated. PC is always the last register popped, and ++ we handle it separately. */ ++ if (offset > 0) ++ mem = gen_frame_mem (DImode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ offset)); ++ else ++ mem = gen_frame_mem (DImode, stack_pointer_rtx); ++ ++ tmp = gen_rtx_SET (DImode, gen_rtx_REG (DImode, j), mem); ++ tmp = emit_insn (tmp); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ ++ /* Generate dwarf info. */ ++ ++ dwarf = alloc_reg_note (REG_CFA_RESTORE, ++ gen_rtx_REG (SImode, j), ++ NULL_RTX); ++ dwarf = alloc_reg_note (REG_CFA_RESTORE, ++ gen_rtx_REG (SImode, j + 1), ++ dwarf); ++ ++ REG_NOTES (tmp) = dwarf; ++ ++ offset += 8; ++ j += 2; ++ } ++ else if (j != PC_REGNUM) ++ { ++ /* Emit a single word load. */ ++ if (offset > 0) ++ mem = gen_frame_mem (SImode, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ offset)); ++ else ++ mem = gen_frame_mem (SImode, stack_pointer_rtx); + -+;; This file is part of GCC. -+;; -+;; GCC is free software; you can redistribute it and/or modify it -+;; under the terms of the GNU General Public License as published by -+;; the Free Software Foundation; either version 3, or (at your option) -+;; any later version. -+;; -+;; GCC is distributed in the hope that it will be useful, but -+;; WITHOUT ANY WARRANTY; without even the implied warranty of -+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+;; General Public License for more details. -+;; -+;; You should have received a copy of the GNU General Public License -+;; along with GCC; see the file COPYING3. If not see -+;; . ++ tmp = gen_rtx_SET (SImode, gen_rtx_REG (SImode, j), mem); ++ tmp = emit_insn (tmp); ++ RTX_FRAME_RELATED_P (tmp) = 1; + -+;; The following peephole optimizations identify consecutive memory -+;; accesses, and try to rearrange the operands to enable generation of -+;; ldrd/strd. ++ /* Generate dwarf info. */ ++ REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, ++ gen_rtx_REG (SImode, j), ++ NULL_RTX); + -+(define_peephole2 ; ldrd -+ [(set (match_operand:SI 0 "arm_general_register_operand" "") -+ (match_operand:SI 2 "memory_operand" "")) -+ (set (match_operand:SI 1 "arm_general_register_operand" "") -+ (match_operand:SI 3 "memory_operand" ""))] -+ "TARGET_LDRD -+ && current_tune->prefer_ldrd_strd -+ && !optimize_function_for_size_p (cfun)" -+ [(const_int 0)] -+{ -+ if (!gen_operands_ldrd_strd (operands, true, false, false)) -+ FAIL; -+ else if (TARGET_ARM) -+ { -+ /* In ARM state, the destination registers of LDRD/STRD must be -+ consecutive. We emit DImode access. */ -+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); -+ operands[2] = adjust_address (operands[2], DImode, 0); -+ /* Emit [(set (match_dup 0) (match_dup 2))] */ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); -+ DONE; -+ } -+ else if (TARGET_THUMB2) -+ { -+ /* Emit the pattern: -+ [(parallel [(set (match_dup 0) (match_dup 2)) -+ (set (match_dup 1) (match_dup 3))])] */ -+ rtx t1 = gen_rtx_SET (VOIDmode, operands[0], operands[2]); -+ rtx t2 = gen_rtx_SET (VOIDmode, operands[1], operands[3]); -+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); -+ DONE; -+ } -+}) ++ offset += 4; ++ j += 1; ++ } ++ else /* j == PC_REGNUM */ ++ j++; ++ } ++ else ++ j++; + -+(define_peephole2 ; strd -+ [(set (match_operand:SI 2 "memory_operand" "") -+ (match_operand:SI 0 "arm_general_register_operand" "")) -+ (set (match_operand:SI 3 "memory_operand" "") -+ (match_operand:SI 1 "arm_general_register_operand" ""))] -+ "TARGET_LDRD -+ && current_tune->prefer_ldrd_strd -+ && !optimize_function_for_size_p (cfun)" -+ [(const_int 0)] -+{ -+ if (!gen_operands_ldrd_strd (operands, false, false, false)) -+ FAIL; -+ else if (TARGET_ARM) -+ { -+ /* In ARM state, the destination registers of LDRD/STRD must be -+ consecutive. We emit DImode access. */ -+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); -+ operands[2] = adjust_address (operands[2], DImode, 0); -+ /* Emit [(set (match_dup 2) (match_dup 0))] */ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[0])); -+ DONE; -+ } -+ else if (TARGET_THUMB2) -+ { -+ /* Emit the pattern: -+ [(parallel [(set (match_dup 2) (match_dup 0)) -+ (set (match_dup 3) (match_dup 1))])] */ -+ rtx t1 = gen_rtx_SET (VOIDmode, operands[2], operands[0]); -+ rtx t2 = gen_rtx_SET (VOIDmode, operands[3], operands[1]); -+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); -+ DONE; -+ } -+}) ++ /* Update the stack. */ ++ if (offset > 0) ++ { ++ tmp = gen_rtx_SET (Pmode, ++ stack_pointer_rtx, ++ plus_constant (Pmode, ++ stack_pointer_rtx, ++ offset)); ++ tmp = emit_insn (tmp); ++ arm_add_cfa_adjust_cfa_note (tmp, offset, ++ stack_pointer_rtx, stack_pointer_rtx); ++ offset = 0; ++ } + -+;; The following peepholes reorder registers to enable LDRD/STRD. -+(define_peephole2 ; strd of constants -+ [(set (match_operand:SI 0 "arm_general_register_operand" "") -+ (match_operand:SI 4 "const_int_operand" "")) -+ (set (match_operand:SI 2 "memory_operand" "") -+ (match_dup 0)) -+ (set (match_operand:SI 1 "arm_general_register_operand" "") -+ (match_operand:SI 5 "const_int_operand" "")) -+ (set (match_operand:SI 3 "memory_operand" "") -+ (match_dup 1))] -+ "TARGET_LDRD -+ && current_tune->prefer_ldrd_strd -+ && !optimize_function_for_size_p (cfun)" -+ [(const_int 0)] -+{ -+ if (!gen_operands_ldrd_strd (operands, false, true, false)) -+ FAIL; -+ else if (TARGET_ARM) -+ { -+ rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0])); -+ operands[2] = adjust_address (operands[2], DImode, 0); -+ /* Emit the pattern: -+ [(set (match_dup 0) (match_dup 4)) -+ (set (match_dup 1) (match_dup 5)) -+ (set (match_dup 2) tmp)] */ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); -+ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); -+ emit_insn (gen_rtx_SET (VOIDmode, operands[2], tmp)); -+ DONE; -+ } -+ else if (TARGET_THUMB2) -+ { -+ /* Emit the pattern: -+ [(set (match_dup 0) (match_dup 4)) -+ (set (match_dup 1) (match_dup 5)) -+ (parallel [(set (match_dup 2) (match_dup 0)) -+ (set (match_dup 3) (match_dup 1))])] */ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); -+ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); -+ rtx t1 = gen_rtx_SET (VOIDmode, operands[2], operands[0]); -+ rtx t2 = gen_rtx_SET (VOIDmode, operands[3], operands[1]); -+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); -+ DONE; -+ } -+}) ++ if (saved_regs_mask & (1 << PC_REGNUM)) ++ { ++ /* Only PC is to be popped. */ ++ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); ++ XVECEXP (par, 0, 0) = ret_rtx; ++ tmp = gen_rtx_SET (SImode, ++ gen_rtx_REG (SImode, PC_REGNUM), ++ gen_frame_mem (SImode, ++ gen_rtx_POST_INC (SImode, ++ stack_pointer_rtx))); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (par, 0, 1) = tmp; ++ par = emit_jump_insn (par); + -+(define_peephole2 ; strd of constants -+ [(set (match_operand:SI 0 "arm_general_register_operand" "") -+ (match_operand:SI 4 "const_int_operand" "")) -+ (set (match_operand:SI 1 "arm_general_register_operand" "") -+ (match_operand:SI 5 "const_int_operand" "")) -+ (set (match_operand:SI 2 "memory_operand" "") -+ (match_dup 0)) -+ (set (match_operand:SI 3 "memory_operand" "") -+ (match_dup 1))] -+ "TARGET_LDRD -+ && current_tune->prefer_ldrd_strd -+ && !optimize_function_for_size_p (cfun)" -+ [(const_int 0)] -+{ -+ if (!gen_operands_ldrd_strd (operands, false, true, false)) -+ FAIL; -+ else if (TARGET_ARM) -+ { -+ rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0])); -+ operands[2] = adjust_address (operands[2], DImode, 0); -+ /* Emit the pattern -+ [(set (match_dup 0) (match_dup 4)) -+ (set (match_dup 1) (match_dup 5)) -+ (set (match_dup 2) tmp)] */ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); -+ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); -+ emit_insn (gen_rtx_SET (VOIDmode, operands[2], tmp)); -+ DONE; -+ } -+ else if (TARGET_THUMB2) -+ { -+ /* Emit the pattern: -+ [(set (match_dup 0) (match_dup 4)) -+ (set (match_dup 1) (match_dup 5)) -+ (parallel [(set (match_dup 2) (match_dup 0)) -+ (set (match_dup 3) (match_dup 1))])] */ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); -+ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); -+ rtx t1 = gen_rtx_SET (VOIDmode, operands[2], operands[0]); -+ rtx t2 = gen_rtx_SET (VOIDmode, operands[3], operands[1]); -+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); -+ DONE; -+ } -+}) ++ /* Generate dwarf info. */ ++ dwarf = alloc_reg_note (REG_CFA_RESTORE, ++ gen_rtx_REG (SImode, PC_REGNUM), ++ NULL_RTX); ++ REG_NOTES (par) = dwarf; ++ arm_add_cfa_adjust_cfa_note (par, UNITS_PER_WORD, ++ stack_pointer_rtx, stack_pointer_rtx); ++ } ++} + -+;; The following two peephole optimizations are only relevant for ARM -+;; mode where LDRD/STRD require consecutive registers. + /* Calculate the size of the return value that is passed in registers. */ + static unsigned + arm_size_return_regs (void) +@@ -16863,11 +17715,27 @@ + || df_regs_ever_live_p (LR_REGNUM)); + } + ++/* We do not know if r3 will be available because ++ we do have an indirect tailcall happening in this ++ particular case. */ ++static bool ++is_indirect_tailcall_p (rtx call) ++{ ++ rtx pat = PATTERN (call); + ++ /* Indirect tail call. */ ++ pat = XVECEXP (pat, 0, 0); ++ if (GET_CODE (pat) == SET) ++ pat = SET_SRC (pat); + -+(define_peephole2 ; swap the destination registers of two loads -+ ; before a commutative operation. -+ [(set (match_operand:SI 0 "arm_general_register_operand" "") -+ (match_operand:SI 2 "memory_operand" "")) -+ (set (match_operand:SI 1 "arm_general_register_operand" "") -+ (match_operand:SI 3 "memory_operand" "")) -+ (set (match_operand:SI 4 "arm_general_register_operand" "") -+ (match_operator:SI 5 "commutative_binary_operator" -+ [(match_operand 6 "arm_general_register_operand" "") -+ (match_operand 7 "arm_general_register_operand" "") ]))] -+ "TARGET_LDRD && TARGET_ARM -+ && current_tune->prefer_ldrd_strd -+ && !optimize_function_for_size_p (cfun) -+ && ( ((rtx_equal_p(operands[0], operands[6])) && (rtx_equal_p(operands[1], operands[7]))) -+ ||((rtx_equal_p(operands[0], operands[7])) && (rtx_equal_p(operands[1], operands[6])))) -+ && (peep2_reg_dead_p (3, operands[0]) || rtx_equal_p (operands[0], operands[4])) -+ && (peep2_reg_dead_p (3, operands[1]) || rtx_equal_p (operands[1], operands[4]))" -+ [(set (match_dup 0) (match_dup 2)) -+ (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))] -+ { -+ if (!gen_operands_ldrd_strd (operands, true, false, true)) -+ { -+ FAIL; -+ } -+ else -+ { -+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); -+ operands[2] = adjust_address (operands[2], DImode, 0); -+ } -+ } -+) ++ pat = XEXP (XEXP (pat, 0), 0); ++ return REG_P (pat); ++} + -+(define_peephole2 ; swap the destination registers of two loads -+ ; before a commutative operation that sets the flags. -+ [(set (match_operand:SI 0 "arm_general_register_operand" "") -+ (match_operand:SI 2 "memory_operand" "")) -+ (set (match_operand:SI 1 "arm_general_register_operand" "") -+ (match_operand:SI 3 "memory_operand" "")) -+ (parallel -+ [(set (match_operand:SI 4 "arm_general_register_operand" "") -+ (match_operator:SI 5 "commutative_binary_operator" -+ [(match_operand 6 "arm_general_register_operand" "") -+ (match_operand 7 "arm_general_register_operand" "") ])) -+ (clobber (reg:CC CC_REGNUM))])] -+ "TARGET_LDRD && TARGET_ARM -+ && current_tune->prefer_ldrd_strd -+ && !optimize_function_for_size_p (cfun) -+ && ( ((rtx_equal_p(operands[0], operands[6])) && (rtx_equal_p(operands[1], operands[7]))) -+ ||((rtx_equal_p(operands[0], operands[7])) && (rtx_equal_p(operands[1], operands[6])))) -+ && (peep2_reg_dead_p (3, operands[0]) || rtx_equal_p (operands[0], operands[4])) -+ && (peep2_reg_dead_p (3, operands[1]) || rtx_equal_p (operands[1], operands[4]))" -+ [(set (match_dup 0) (match_dup 2)) -+ (parallel -+ [(set (match_dup 4) -+ (match_op_dup 5 [(match_dup 6) (match_dup 7)])) -+ (clobber (reg:CC CC_REGNUM))])] -+ { -+ if (!gen_operands_ldrd_strd (operands, true, false, true)) -+ { -+ FAIL; -+ } -+ else -+ { -+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); -+ operands[2] = adjust_address (operands[2], DImode, 0); -+ } -+ } -+) + /* Return true if r3 is used by any of the tail call insns in the + current function. */ + static bool +-any_sibcall_uses_r3 (void) ++any_sibcall_could_use_r3 (void) + { + edge_iterator ei; + edge e; +@@ -16881,7 +17749,8 @@ + if (!CALL_P (call)) + call = prev_nonnote_nondebug_insn (call); + gcc_assert (CALL_P (call) && SIBLING_CALL_P (call)); +- if (find_regno_fusage (call, USE, 3)) ++ if (find_regno_fusage (call, USE, 3) ++ || is_indirect_tailcall_p (call)) + return true; + } + return false; +@@ -17048,9 +17917,11 @@ + /* If it is safe to use r3, then do so. This sometimes + generates better code on Thumb-2 by avoiding the need to + use 32-bit push/pop instructions. */ +- if (! any_sibcall_uses_r3 () ++ if (! any_sibcall_could_use_r3 () + && arm_size_return_regs () <= 12 +- && (offsets->saved_regs_mask & (1 << 3)) == 0) ++ && (offsets->saved_regs_mask & (1 << 3)) == 0 ++ && (TARGET_THUMB2 ++ || !(TARGET_LDRD && current_tune->prefer_ldrd_strd))) + { + reg = 3; + } +@@ -17483,6 +18354,12 @@ + { + thumb2_emit_strd_push (live_regs_mask); + } ++ else if (TARGET_ARM ++ && !TARGET_APCS_FRAME ++ && !IS_INTERRUPT (func_type)) ++ { ++ arm_emit_strd_push (live_regs_mask); ++ } + else + { + insn = emit_multi_reg_push (live_regs_mask); +@@ -18760,7 +19637,14 @@ + enum arm_cond_code code; + int n; + int mask; ++ int max; + ++ /* Maximum number of conditionally executed instructions in a block ++ is minimum of the two max values: maximum allowed in an IT block ++ and maximum that is beneficial according to the cost model and tune. */ ++ max = (max_insns_skipped < MAX_INSN_PER_IT_BLOCK) ? ++ max_insns_skipped : MAX_INSN_PER_IT_BLOCK; + -+;; TODO: Handle LDRD/STRD with writeback: -+;; (a) memory operands can be POST_INC, POST_DEC, PRE_MODIFY, POST_MODIFY -+;; (b) Patterns may be followed by an update of the base address. ---- a/src/gcc/config/arm/predicates.md -+++ b/src/gcc/config/arm/predicates.md -@@ -31,6 +31,28 @@ - || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); - }) + /* Remove the previous insn from the count of insns to be output. */ + if (arm_condexec_count) + arm_condexec_count--; +@@ -18802,9 +19686,9 @@ + /* ??? Recognize conditional jumps, and combine them with IT blocks. */ + if (GET_CODE (body) != COND_EXEC) + break; +- /* Allow up to 4 conditionally executed instructions in a block. */ ++ /* Maximum number of conditionally executed instructions in a block. */ + n = get_attr_ce_count (insn); +- if (arm_condexec_masklen + n > 4) ++ if (arm_condexec_masklen + n > max) + break; + + predicate = COND_EXEC_TEST (body); +@@ -19362,6 +20246,7 @@ + typedef enum { + T_V8QI, + T_V4HI, ++ T_V4HF, + T_V2SI, + T_V2SF, + T_DI, +@@ -19379,14 +20264,15 @@ + #define TYPE_MODE_BIT(X) (1 << (X)) + + #define TB_DREG (TYPE_MODE_BIT (T_V8QI) | TYPE_MODE_BIT (T_V4HI) \ +- | TYPE_MODE_BIT (T_V2SI) | TYPE_MODE_BIT (T_V2SF) \ +- | TYPE_MODE_BIT (T_DI)) ++ | TYPE_MODE_BIT (T_V4HF) | TYPE_MODE_BIT (T_V2SI) \ ++ | TYPE_MODE_BIT (T_V2SF) | TYPE_MODE_BIT (T_DI)) + #define TB_QREG (TYPE_MODE_BIT (T_V16QI) | TYPE_MODE_BIT (T_V8HI) \ + | TYPE_MODE_BIT (T_V4SI) | TYPE_MODE_BIT (T_V4SF) \ + | TYPE_MODE_BIT (T_V2DI) | TYPE_MODE_BIT (T_TI)) + + #define v8qi_UP T_V8QI + #define v4hi_UP T_V4HI ++#define v4hf_UP T_V4HF + #define v2si_UP T_V2SI + #define v2sf_UP T_V2SF + #define di_UP T_DI +@@ -19422,6 +20308,8 @@ + NEON_SCALARMULH, + NEON_SCALARMAC, + NEON_CONVERT, ++ NEON_FLOAT_WIDEN, ++ NEON_FLOAT_NARROW, + NEON_FIXCONV, + NEON_SELECT, + NEON_RESULTPAIR, +@@ -19482,7 +20370,8 @@ + VAR9 (T, N, A, B, C, D, E, F, G, H, I), \ + {#N, NEON_##T, UP (J), CF (N, J), 0} + +-/* The mode entries in the following table correspond to the "key" type of the ++/* The NEON builtin data can be found in arm_neon_builtins.def. ++ The mode entries in the following table correspond to the "key" type of the + instruction variant, i.e. equivalent to that which would be specified after + the assembler mnemonic, which usually refers to the last vector operand. + (Signed/unsigned/polynomial types are not differentiated between though, and +@@ -19492,196 +20381,7 @@ + + static neon_builtin_datum neon_builtin_data[] = + { +- VAR10 (BINOP, vadd, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR3 (BINOP, vaddl, v8qi, v4hi, v2si), +- VAR3 (BINOP, vaddw, v8qi, v4hi, v2si), +- VAR6 (BINOP, vhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR8 (BINOP, vqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR3 (BINOP, vaddhn, v8hi, v4si, v2di), +- VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si), +- VAR2 (TERNOP, vfma, v2sf, v4sf), +- VAR2 (TERNOP, vfms, v2sf, v4sf), +- VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si), +- VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si), +- VAR2 (TERNOP, vqdmlal, v4hi, v2si), +- VAR2 (TERNOP, vqdmlsl, v4hi, v2si), +- VAR3 (BINOP, vmull, v8qi, v4hi, v2si), +- VAR2 (SCALARMULL, vmull_n, v4hi, v2si), +- VAR2 (LANEMULL, vmull_lane, v4hi, v2si), +- VAR2 (SCALARMULL, vqdmull_n, v4hi, v2si), +- VAR2 (LANEMULL, vqdmull_lane, v4hi, v2si), +- VAR4 (SCALARMULH, vqdmulh_n, v4hi, v2si, v8hi, v4si), +- VAR4 (LANEMULH, vqdmulh_lane, v4hi, v2si, v8hi, v4si), +- VAR2 (BINOP, vqdmull, v4hi, v2si), +- VAR8 (BINOP, vshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR8 (BINOP, vqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR8 (SHIFTIMM, vshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR3 (SHIFTIMM, vshrn_n, v8hi, v4si, v2di), +- VAR3 (SHIFTIMM, vqshrn_n, v8hi, v4si, v2di), +- VAR3 (SHIFTIMM, vqshrun_n, v8hi, v4si, v2di), +- VAR8 (SHIFTIMM, vshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR8 (SHIFTIMM, vqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR8 (SHIFTIMM, vqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR3 (SHIFTIMM, vshll_n, v8qi, v4hi, v2si), +- VAR8 (SHIFTACC, vsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR10 (BINOP, vsub, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR3 (BINOP, vsubl, v8qi, v4hi, v2si), +- VAR3 (BINOP, vsubw, v8qi, v4hi, v2si), +- VAR8 (BINOP, vqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR6 (BINOP, vhsub, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR3 (BINOP, vsubhn, v8hi, v4si, v2di), +- VAR8 (BINOP, vceq, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR8 (BINOP, vcge, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR6 (BINOP, vcgeu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR8 (BINOP, vcgt, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR6 (BINOP, vcgtu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR2 (BINOP, vcage, v2sf, v4sf), +- VAR2 (BINOP, vcagt, v2sf, v4sf), +- VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR8 (BINOP, vabd, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR3 (BINOP, vabdl, v8qi, v4hi, v2si), +- VAR6 (TERNOP, vaba, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR3 (TERNOP, vabal, v8qi, v4hi, v2si), +- VAR8 (BINOP, vmax, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR8 (BINOP, vmin, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR4 (BINOP, vpadd, v8qi, v4hi, v2si, v2sf), +- VAR6 (UNOP, vpaddl, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR6 (BINOP, vpadal, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR4 (BINOP, vpmax, v8qi, v4hi, v2si, v2sf), +- VAR4 (BINOP, vpmin, v8qi, v4hi, v2si, v2sf), +- VAR2 (BINOP, vrecps, v2sf, v4sf), +- VAR2 (BINOP, vrsqrts, v2sf, v4sf), +- VAR8 (SHIFTINSERT, vsri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR8 (SHIFTINSERT, vsli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), +- VAR8 (UNOP, vabs, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR6 (UNOP, vqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR8 (UNOP, vneg, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR6 (UNOP, vqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR6 (UNOP, vcls, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR6 (UNOP, vclz, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- VAR2 (UNOP, vcnt, v8qi, v16qi), +- VAR4 (UNOP, vrecpe, v2si, v2sf, v4si, v4sf), +- VAR4 (UNOP, vrsqrte, v2si, v2sf, v4si, v4sf), +- VAR6 (UNOP, vmvn, v8qi, v4hi, v2si, v16qi, v8hi, v4si), +- /* FIXME: vget_lane supports more variants than this! */ +- VAR10 (GETLANE, vget_lane, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (SETLANE, vset_lane, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR5 (CREATE, vcreate, v8qi, v4hi, v2si, v2sf, di), +- VAR10 (DUP, vdup_n, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (DUPLANE, vdup_lane, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR5 (COMBINE, vcombine, v8qi, v4hi, v2si, v2sf, di), +- VAR5 (SPLIT, vget_high, v16qi, v8hi, v4si, v4sf, v2di), +- VAR5 (SPLIT, vget_low, v16qi, v8hi, v4si, v4sf, v2di), +- VAR3 (UNOP, vmovn, v8hi, v4si, v2di), +- VAR3 (UNOP, vqmovn, v8hi, v4si, v2di), +- VAR3 (UNOP, vqmovun, v8hi, v4si, v2di), +- VAR3 (UNOP, vmovl, v8qi, v4hi, v2si), +- VAR6 (LANEMUL, vmul_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR6 (LANEMAC, vmla_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR2 (LANEMAC, vmlal_lane, v4hi, v2si), +- VAR2 (LANEMAC, vqdmlal_lane, v4hi, v2si), +- VAR6 (LANEMAC, vmls_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR2 (LANEMAC, vmlsl_lane, v4hi, v2si), +- VAR2 (LANEMAC, vqdmlsl_lane, v4hi, v2si), +- VAR6 (SCALARMUL, vmul_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR6 (SCALARMAC, vmla_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR2 (SCALARMAC, vmlal_n, v4hi, v2si), +- VAR2 (SCALARMAC, vqdmlal_n, v4hi, v2si), +- VAR6 (SCALARMAC, vmls_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR2 (SCALARMAC, vmlsl_n, v4hi, v2si), +- VAR2 (SCALARMAC, vqdmlsl_n, v4hi, v2si), +- VAR10 (BINOP, vext, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR8 (UNOP, vrev64, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR4 (UNOP, vrev32, v8qi, v4hi, v16qi, v8hi), +- VAR2 (UNOP, vrev16, v8qi, v16qi), +- VAR4 (CONVERT, vcvt, v2si, v2sf, v4si, v4sf), +- VAR4 (FIXCONV, vcvt_n, v2si, v2sf, v4si, v4sf), +- VAR10 (SELECT, vbsl, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR2 (RINT, vrintn, v2sf, v4sf), +- VAR2 (RINT, vrinta, v2sf, v4sf), +- VAR2 (RINT, vrintp, v2sf, v4sf), +- VAR2 (RINT, vrintm, v2sf, v4sf), +- VAR2 (RINT, vrintz, v2sf, v4sf), +- VAR2 (RINT, vrintx, v2sf, v4sf), +- VAR1 (VTBL, vtbl1, v8qi), +- VAR1 (VTBL, vtbl2, v8qi), +- VAR1 (VTBL, vtbl3, v8qi), +- VAR1 (VTBL, vtbl4, v8qi), +- VAR1 (VTBX, vtbx1, v8qi), +- VAR1 (VTBX, vtbx2, v8qi), +- VAR1 (VTBX, vtbx3, v8qi), +- VAR1 (VTBX, vtbx4, v8qi), +- VAR8 (RESULTPAIR, vtrn, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR8 (RESULTPAIR, vzip, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR8 (RESULTPAIR, vuzp, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), +- VAR5 (REINTERP, vreinterpretv8qi, v8qi, v4hi, v2si, v2sf, di), +- VAR5 (REINTERP, vreinterpretv4hi, v8qi, v4hi, v2si, v2sf, di), +- VAR5 (REINTERP, vreinterpretv2si, v8qi, v4hi, v2si, v2sf, di), +- VAR5 (REINTERP, vreinterpretv2sf, v8qi, v4hi, v2si, v2sf, di), +- VAR5 (REINTERP, vreinterpretdi, v8qi, v4hi, v2si, v2sf, di), +- VAR5 (REINTERP, vreinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di), +- VAR5 (REINTERP, vreinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di), +- VAR5 (REINTERP, vreinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di), +- VAR5 (REINTERP, vreinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di), +- VAR5 (REINTERP, vreinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (LOAD1, vld1, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (LOAD1LANE, vld1_lane, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (LOAD1, vld1_dup, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (STORE1, vst1, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (STORE1LANE, vst1_lane, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR9 (LOADSTRUCT, +- vld2, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), +- VAR7 (LOADSTRUCTLANE, vld2_lane, +- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR5 (LOADSTRUCT, vld2_dup, v8qi, v4hi, v2si, v2sf, di), +- VAR9 (STORESTRUCT, vst2, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), +- VAR7 (STORESTRUCTLANE, vst2_lane, +- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR9 (LOADSTRUCT, +- vld3, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), +- VAR7 (LOADSTRUCTLANE, vld3_lane, +- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR5 (LOADSTRUCT, vld3_dup, v8qi, v4hi, v2si, v2sf, di), +- VAR9 (STORESTRUCT, vst3, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), +- VAR7 (STORESTRUCTLANE, vst3_lane, +- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR9 (LOADSTRUCT, vld4, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), +- VAR7 (LOADSTRUCTLANE, vld4_lane, +- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR5 (LOADSTRUCT, vld4_dup, v8qi, v4hi, v2si, v2sf, di), +- VAR9 (STORESTRUCT, vst4, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), +- VAR7 (STORESTRUCTLANE, vst4_lane, +- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), +- VAR10 (LOGICBINOP, vand, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (LOGICBINOP, vorr, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (BINOP, veor, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (LOGICBINOP, vbic, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), +- VAR10 (LOGICBINOP, vorn, +- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) ++#include "arm_neon_builtins.def" + }; -+(define_predicate "imm_for_neon_inv_logic_operand" -+ (match_code "const_vector") -+{ -+ return (TARGET_NEON -+ && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); -+}) -+ -+(define_predicate "neon_inv_logic_op2" -+ (ior (match_operand 0 "imm_for_neon_inv_logic_operand") -+ (match_operand 0 "s_register_operand"))) -+ -+(define_predicate "imm_for_neon_logic_operand" -+ (match_code "const_vector") -+{ -+ return (TARGET_NEON -+ && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); -+}) -+ -+(define_predicate "neon_logic_op2" -+ (ior (match_operand 0 "imm_for_neon_logic_operand") -+ (match_operand 0 "s_register_operand"))) -+ - ;; Any general register. - (define_predicate "arm_hard_general_register_operand" - (match_code "reg") -@@ -151,6 +173,23 @@ - (ior (match_operand 0 "arm_rhs_operand") - (match_operand 0 "arm_neg_immediate_operand"))) + #undef CF +@@ -19696,9 +20396,36 @@ + #undef VAR9 + #undef VAR10 -+(define_predicate "arm_anddi_operand_neon" -+ (ior (match_operand 0 "s_register_operand") -+ (and (match_code "const_int") -+ (match_test "const_ok_for_dimode_op (INTVAL (op), AND)")) -+ (match_operand 0 "neon_inv_logic_op2"))) -+ -+(define_predicate "arm_iordi_operand_neon" -+ (ior (match_operand 0 "s_register_operand") -+ (and (match_code "const_int") -+ (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)")) -+ (match_operand 0 "neon_logic_op2"))) -+ -+(define_predicate "arm_xordi_operand" -+ (ior (match_operand 0 "s_register_operand") -+ (and (match_code "const_int") -+ (match_test "const_ok_for_dimode_op (INTVAL (op), XOR)")))) -+ - (define_predicate "arm_adddi_operand" - (ior (match_operand 0 "s_register_operand") - (and (match_code "const_int") -@@ -213,6 +252,10 @@ - (and (match_code "plus,minus,ior,xor,and") - (match_test "mode == GET_MODE (op)"))) +-/* Neon defines builtins from ARM_BUILTIN_MAX upwards, though they don't have +- symbolic names defined here (which would require too much duplication). +- FIXME? */ ++#define CF(N,X) ARM_BUILTIN_NEON_##N##X ++#define VAR1(T, N, A) \ ++ CF (N, A) ++#define VAR2(T, N, A, B) \ ++ VAR1 (T, N, A), \ ++ CF (N, B) ++#define VAR3(T, N, A, B, C) \ ++ VAR2 (T, N, A, B), \ ++ CF (N, C) ++#define VAR4(T, N, A, B, C, D) \ ++ VAR3 (T, N, A, B, C), \ ++ CF (N, D) ++#define VAR5(T, N, A, B, C, D, E) \ ++ VAR4 (T, N, A, B, C, D), \ ++ CF (N, E) ++#define VAR6(T, N, A, B, C, D, E, F) \ ++ VAR5 (T, N, A, B, C, D, E), \ ++ CF (N, F) ++#define VAR7(T, N, A, B, C, D, E, F, G) \ ++ VAR6 (T, N, A, B, C, D, E, F), \ ++ CF (N, G) ++#define VAR8(T, N, A, B, C, D, E, F, G, H) \ ++ VAR7 (T, N, A, B, C, D, E, F, G), \ ++ CF (N, H) ++#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \ ++ VAR8 (T, N, A, B, C, D, E, F, G, H), \ ++ CF (N, I) ++#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \ ++ VAR9 (T, N, A, B, C, D, E, F, G, H, I), \ ++ CF (N, J) + enum arm_builtins + { + ARM_BUILTIN_GETWCGR0, +@@ -19947,11 +20674,25 @@ -+(define_special_predicate "shiftable_operator_strict_it" -+ (and (match_code "plus,and") -+ (match_test "mode == GET_MODE (op)"))) -+ - ;; True for logical binary operators. - (define_special_predicate "logical_binary_operator" - (and (match_code "ior,xor,and") -@@ -276,6 +319,24 @@ - (define_special_predicate "lt_ge_comparison_operator" - (match_code "lt,ge")) + ARM_BUILTIN_WMERGE, -+;; The vsel instruction only accepts the ARM condition codes listed below. -+(define_special_predicate "arm_vsel_comparison_operator" -+ (and (match_operand 0 "expandable_comparison_operator") -+ (match_test "maybe_get_arm_condition_code (op) == ARM_GE -+ || maybe_get_arm_condition_code (op) == ARM_GT -+ || maybe_get_arm_condition_code (op) == ARM_EQ -+ || maybe_get_arm_condition_code (op) == ARM_VS -+ || maybe_get_arm_condition_code (op) == ARM_LT -+ || maybe_get_arm_condition_code (op) == ARM_LE -+ || maybe_get_arm_condition_code (op) == ARM_NE -+ || maybe_get_arm_condition_code (op) == ARM_VC"))) +- ARM_BUILTIN_NEON_BASE, ++#include "arm_neon_builtins.def" + +- ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE + ARRAY_SIZE (neon_builtin_data) ++ ,ARM_BUILTIN_MAX + }; + ++#define ARM_BUILTIN_NEON_BASE (ARM_BUILTIN_MAX - ARRAY_SIZE (neon_builtin_data)) + -+(define_special_predicate "arm_cond_move_operator" -+ (if_then_else (match_test "arm_restrict_it") -+ (and (match_test "TARGET_FPU_ARMV8") -+ (match_operand 0 "arm_vsel_comparison_operator")) -+ (match_operand 0 "expandable_comparison_operator"))) ++#undef CF ++#undef VAR1 ++#undef VAR2 ++#undef VAR3 ++#undef VAR4 ++#undef VAR5 ++#undef VAR6 ++#undef VAR7 ++#undef VAR8 ++#undef VAR9 ++#undef VAR10 + - (define_special_predicate "noov_comparison_operator" - (match_code "lt,ge,eq,ne")) + static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX]; -@@ -512,28 +573,6 @@ - (ior (match_operand 0 "s_register_operand") - (match_operand 0 "imm_for_neon_rshift_operand"))) + static void +@@ -19962,6 +20703,7 @@ --(define_predicate "imm_for_neon_logic_operand" -- (match_code "const_vector") --{ -- return (TARGET_NEON -- && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); --}) -- --(define_predicate "imm_for_neon_inv_logic_operand" -- (match_code "const_vector") --{ -- return (TARGET_NEON -- && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); --}) -- --(define_predicate "neon_logic_op2" -- (ior (match_operand 0 "imm_for_neon_logic_operand") -- (match_operand 0 "s_register_operand"))) -- --(define_predicate "neon_inv_logic_op2" -- (ior (match_operand 0 "imm_for_neon_inv_logic_operand") -- (match_operand 0 "s_register_operand"))) -- - ;; Predicates for named expanders that overlap multiple ISAs. + tree neon_intQI_type_node; + tree neon_intHI_type_node; ++ tree neon_floatHF_type_node; + tree neon_polyQI_type_node; + tree neon_polyHI_type_node; + tree neon_intSI_type_node; +@@ -19988,6 +20730,7 @@ - (define_predicate "cmpdi_operand" -@@ -623,3 +662,7 @@ - (define_predicate "mem_noofs_operand" - (and (match_code "mem") - (match_code "reg" "0"))) + tree V8QI_type_node; + tree V4HI_type_node; ++ tree V4HF_type_node; + tree V2SI_type_node; + tree V2SF_type_node; + tree V16QI_type_node; +@@ -20042,6 +20785,9 @@ + neon_float_type_node = make_node (REAL_TYPE); + TYPE_PRECISION (neon_float_type_node) = FLOAT_TYPE_SIZE; + layout_type (neon_float_type_node); ++ neon_floatHF_type_node = make_node (REAL_TYPE); ++ TYPE_PRECISION (neon_floatHF_type_node) = GET_MODE_PRECISION (HFmode); ++ layout_type (neon_floatHF_type_node); + + /* Define typedefs which exactly correspond to the modes we are basing vector + types on. If you change these names you'll need to change +@@ -20050,6 +20796,8 @@ + "__builtin_neon_qi"); + (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node, + "__builtin_neon_hi"); ++ (*lang_hooks.types.register_builtin_type) (neon_floatHF_type_node, ++ "__builtin_neon_hf"); + (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node, + "__builtin_neon_si"); + (*lang_hooks.types.register_builtin_type) (neon_float_type_node, +@@ -20091,6 +20839,8 @@ + build_vector_type_for_mode (neon_intQI_type_node, V8QImode); + V4HI_type_node = + build_vector_type_for_mode (neon_intHI_type_node, V4HImode); ++ V4HF_type_node = ++ build_vector_type_for_mode (neon_floatHF_type_node, V4HFmode); + V2SI_type_node = + build_vector_type_for_mode (neon_intSI_type_node, V2SImode); + V2SF_type_node = +@@ -20213,7 +20963,7 @@ + neon_builtin_datum *d = &neon_builtin_data[i]; + + const char* const modenames[] = { +- "v8qi", "v4hi", "v2si", "v2sf", "di", ++ "v8qi", "v4hi", "v4hf", "v2si", "v2sf", "di", + "v16qi", "v8hi", "v4si", "v4sf", "v2di", + "ti", "ei", "oi" + }; +@@ -20416,8 +21166,9 @@ + case NEON_REINTERP: + { + /* We iterate over 5 doubleword types, then 5 quadword +- types. */ +- int rhs = d->mode % 5; ++ types. V4HF is not a type used in reinterpret, so we translate ++ d->mode to the correct index in reinterp_ftype_dreg. */ ++ int rhs = (d->mode - ((d->mode > T_V4HF) ? 1 : 0)) % 5; + switch (insn_data[d->code].operand[0].mode) + { + case V8QImode: ftype = reinterp_ftype_dreg[0][rhs]; break; +@@ -20434,7 +21185,38 @@ + } + } + break; ++ case NEON_FLOAT_WIDEN: ++ { ++ tree eltype = NULL_TREE; ++ tree return_type = NULL_TREE; + ++ switch (insn_data[d->code].operand[1].mode) ++ { ++ case V4HFmode: ++ eltype = V4HF_type_node; ++ return_type = V4SF_type_node; ++ break; ++ default: gcc_unreachable (); ++ } ++ ftype = build_function_type_list (return_type, eltype, NULL); ++ break; ++ } ++ case NEON_FLOAT_NARROW: ++ { ++ tree eltype = NULL_TREE; ++ tree return_type = NULL_TREE; + -+(define_predicate "call_insn_operand" -+ (ior (match_code "symbol_ref") -+ (match_operand 0 "s_register_operand"))) ---- a/src/gcc/config/arm/arm_neon.h -+++ b/src/gcc/config/arm/arm_neon.h -@@ -42,9 +42,13 @@ - typedef __builtin_neon_hi int16x4_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_si int32x2_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_di int64x1_t; -+typedef __builtin_neon_hf float16x4_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_sf float32x2_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_poly8 poly8x8_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_poly16 poly16x4_t __attribute__ ((__vector_size__ (8))); -+#ifdef __ARM_FEATURE_CRYPTO -+typedef __builtin_neon_poly64 poly64x1_t; -+#endif - typedef __builtin_neon_uqi uint8x8_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_uhi uint16x4_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_usi uint32x2_t __attribute__ ((__vector_size__ (8))); -@@ -56,6 +60,9 @@ - typedef __builtin_neon_sf float32x4_t __attribute__ ((__vector_size__ (16))); - typedef __builtin_neon_poly8 poly8x16_t __attribute__ ((__vector_size__ (16))); - typedef __builtin_neon_poly16 poly16x8_t __attribute__ ((__vector_size__ (16))); -+#ifdef __ARM_FEATURE_CRYPTO -+typedef __builtin_neon_poly64 poly64x2_t __attribute__ ((__vector_size__ (16))); -+#endif - typedef __builtin_neon_uqi uint8x16_t __attribute__ ((__vector_size__ (16))); - typedef __builtin_neon_uhi uint16x8_t __attribute__ ((__vector_size__ (16))); - typedef __builtin_neon_usi uint32x4_t __attribute__ ((__vector_size__ (16))); -@@ -64,6 +71,10 @@ - typedef float float32_t; - typedef __builtin_neon_poly8 poly8_t; - typedef __builtin_neon_poly16 poly16_t; -+#ifdef __ARM_FEATURE_CRYPTO -+typedef __builtin_neon_poly64 poly64_t; -+typedef __builtin_neon_poly128 poly128_t; -+#endif ++ switch (insn_data[d->code].operand[1].mode) ++ { ++ case V4SFmode: ++ eltype = V4SF_type_node; ++ return_type = V4HF_type_node; ++ break; ++ default: gcc_unreachable (); ++ } ++ ftype = build_function_type_list (return_type, eltype, NULL); ++ break; ++ } + default: + gcc_unreachable (); + } +@@ -21431,6 +22213,8 @@ + case NEON_DUP: + case NEON_RINT: + case NEON_SPLIT: ++ case NEON_FLOAT_WIDEN: ++ case NEON_FLOAT_NARROW: + case NEON_REINTERP: + return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode, + NEON_ARG_COPY_TO_REG, NEON_ARG_STOP); +@@ -21628,7 +22412,7 @@ + rtx op1; + rtx op2; + rtx pat; +- int fcode = DECL_FUNCTION_CODE (fndecl); ++ unsigned int fcode = DECL_FUNCTION_CODE (fndecl); + size_t i; + enum machine_mode tmode; + enum machine_mode mode0; +@@ -23345,7 +24129,7 @@ + all we really need to check here is if single register is to be + returned, or multiple register return. */ + void +-thumb2_expand_return (void) ++thumb2_expand_return (bool simple_return) + { + int i, num_regs; + unsigned long saved_regs_mask; +@@ -23358,7 +24142,7 @@ + if (saved_regs_mask & (1 << i)) + num_regs++; + +- if (saved_regs_mask) ++ if (!simple_return && saved_regs_mask) + { + if (num_regs == 1) + { +@@ -23636,6 +24420,7 @@ + + if (frame_pointer_needed) + { ++ rtx insn; + /* Restore stack pointer if necessary. */ + if (TARGET_ARM) + { +@@ -23646,9 +24431,12 @@ + /* Force out any pending memory operations that reference stacked data + before stack de-allocation occurs. */ + emit_insn (gen_blockage ()); +- emit_insn (gen_addsi3 (stack_pointer_rtx, +- hard_frame_pointer_rtx, +- GEN_INT (amount))); ++ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, ++ hard_frame_pointer_rtx, ++ GEN_INT (amount))); ++ arm_add_cfa_adjust_cfa_note (insn, amount, ++ stack_pointer_rtx, ++ hard_frame_pointer_rtx); + + /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not + deleted. */ +@@ -23658,16 +24446,25 @@ + { + /* In Thumb-2 mode, the frame pointer points to the last saved + register. */ +- amount = offsets->locals_base - offsets->saved_regs; +- if (amount) +- emit_insn (gen_addsi3 (hard_frame_pointer_rtx, +- hard_frame_pointer_rtx, +- GEN_INT (amount))); ++ amount = offsets->locals_base - offsets->saved_regs; ++ if (amount) ++ { ++ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ++ hard_frame_pointer_rtx, ++ GEN_INT (amount))); ++ arm_add_cfa_adjust_cfa_note (insn, amount, ++ hard_frame_pointer_rtx, ++ hard_frame_pointer_rtx); ++ } + + /* Force out any pending memory operations that reference stacked data + before stack de-allocation occurs. */ + emit_insn (gen_blockage ()); +- emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx)); ++ insn = emit_insn (gen_movsi (stack_pointer_rtx, ++ hard_frame_pointer_rtx)); ++ arm_add_cfa_adjust_cfa_note (insn, 0, ++ stack_pointer_rtx, ++ hard_frame_pointer_rtx); + /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not + deleted. */ + emit_insn (gen_force_register_use (stack_pointer_rtx)); +@@ -23680,12 +24477,15 @@ + amount = offsets->outgoing_args - offsets->saved_regs; + if (amount) + { ++ rtx tmp; + /* Force out any pending memory operations that reference stacked data + before stack de-allocation occurs. */ + emit_insn (gen_blockage ()); +- emit_insn (gen_addsi3 (stack_pointer_rtx, +- stack_pointer_rtx, +- GEN_INT (amount))); ++ tmp = emit_insn (gen_addsi3 (stack_pointer_rtx, ++ stack_pointer_rtx, ++ GEN_INT (amount))); ++ arm_add_cfa_adjust_cfa_note (tmp, amount, ++ stack_pointer_rtx, stack_pointer_rtx); + /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is + not deleted. */ + emit_insn (gen_force_register_use (stack_pointer_rtx)); +@@ -23738,6 +24538,8 @@ + REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE, + gen_rtx_REG (V2SImode, i), + NULL_RTX); ++ arm_add_cfa_adjust_cfa_note (insn, UNITS_PER_WORD, ++ stack_pointer_rtx, stack_pointer_rtx); + } + + if (saved_regs_mask) +@@ -23785,6 +24587,9 @@ + REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE, + gen_rtx_REG (SImode, i), + NULL_RTX); ++ arm_add_cfa_adjust_cfa_note (insn, UNITS_PER_WORD, ++ stack_pointer_rtx, ++ stack_pointer_rtx); + } + } + } +@@ -23796,6 +24601,8 @@ + { + if (TARGET_THUMB2) + thumb2_emit_ldrd_pop (saved_regs_mask); ++ else if (TARGET_ARM && !IS_INTERRUPT (func_type)) ++ arm_emit_ldrd_pop (saved_regs_mask); + else + arm_emit_multi_reg_pop (saved_regs_mask); + } +@@ -23808,10 +24615,34 @@ + } - typedef struct int8x8x2_t - { -@@ -175,6 +186,22 @@ - poly16x8_t val[2]; - } poly16x8x2_t; + if (crtl->args.pretend_args_size) +- emit_insn (gen_addsi3 (stack_pointer_rtx, +- stack_pointer_rtx, +- GEN_INT (crtl->args.pretend_args_size))); ++ { ++ int i, j; ++ rtx dwarf = NULL_RTX; ++ rtx tmp = emit_insn (gen_addsi3 (stack_pointer_rtx, ++ stack_pointer_rtx, ++ GEN_INT (crtl->args.pretend_args_size))); -+#ifdef __ARM_FEATURE_CRYPTO -+typedef struct poly64x1x2_t -+{ -+ poly64x1_t val[2]; -+} poly64x1x2_t; -+#endif -+ -+ -+#ifdef __ARM_FEATURE_CRYPTO -+typedef struct poly64x2x2_t -+{ -+ poly64x2_t val[2]; -+} poly64x2x2_t; -+#endif ++ RTX_FRAME_RELATED_P (tmp) = 1; + ++ if (cfun->machine->uses_anonymous_args) ++ { ++ /* Restore pretend args. Refer arm_expand_prologue on how to save ++ pretend_args in stack. */ ++ int num_regs = crtl->args.pretend_args_size / 4; ++ saved_regs_mask = (0xf0 >> num_regs) & 0xf; ++ for (j = 0, i = 0; j < num_regs; i++) ++ if (saved_regs_mask & (1 << i)) ++ { ++ rtx reg = gen_rtx_REG (SImode, i); ++ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); ++ j++; ++ } ++ REG_NOTES (tmp) = dwarf; ++ } ++ arm_add_cfa_adjust_cfa_note (tmp, crtl->args.pretend_args_size, ++ stack_pointer_rtx, stack_pointer_rtx); ++ } + - typedef struct int8x8x3_t - { - int8x8_t val[3]; -@@ -285,6 +312,22 @@ - poly16x8_t val[3]; - } poly16x8x3_t; + if (!really_return) + return; -+#ifdef __ARM_FEATURE_CRYPTO -+typedef struct poly64x1x3_t -+{ -+ poly64x1_t val[3]; -+} poly64x1x3_t; -+#endif -+ -+ -+#ifdef __ARM_FEATURE_CRYPTO -+typedef struct poly64x2x3_t -+{ -+ poly64x2_t val[3]; -+} poly64x2x3_t; -+#endif -+ -+ - typedef struct int8x8x4_t +@@ -25064,7 +25895,7 @@ { - int8x8_t val[4]; -@@ -395,7 +438,23 @@ - poly16x8_t val[4]; - } poly16x8x4_t; + /* Neon also supports V2SImode, etc. listed in the clause below. */ + if (TARGET_NEON && (mode == V2SFmode || mode == V4SImode || mode == V8HImode +- || mode == V16QImode || mode == V4SFmode || mode == V2DImode)) ++ || mode == V4HFmode || mode == V16QImode || mode == V4SFmode || mode == V2DImode)) + return true; -+#ifdef __ARM_FEATURE_CRYPTO -+typedef struct poly64x1x4_t -+{ -+ poly64x1_t val[4]; -+} poly64x1x4_t; -+#endif + if ((TARGET_NEON || TARGET_IWMMXT) +@@ -25227,9 +26058,8 @@ -+ -+#ifdef __ARM_FEATURE_CRYPTO -+typedef struct poly64x2x4_t -+{ -+ poly64x2_t val[4]; -+} poly64x2x4_t; -+#endif -+ -+ -+ - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vadd_s8 (int8x8_t __a, int8x8_t __b) - { -@@ -4360,6 +4419,14 @@ - return (uint64x2_t)__builtin_neon_vsra_nv2di ((int64x2_t) __a, (int64x2_t) __b, __c, 4); - } + nregs = GET_MODE_SIZE (GET_MODE (rtl)) / 8; + p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs)); +- regno = (regno - FIRST_VFP_REGNUM) / 2; + for (i = 0; i < nregs; i++) +- XVECEXP (p, 0, i) = gen_rtx_REG (DImode, 256 + regno + i); ++ XVECEXP (p, 0, i) = gen_rtx_REG (DImode, regno + i); -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vsri_n_p64 (poly64x1_t __a, poly64x1_t __b, const int __c) -+{ -+ return (poly64x1_t)__builtin_neon_vsri_ndi (__a, __b, __c); -+} -+ -+#endif - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vsri_n_s8 (int8x8_t __a, int8x8_t __b, const int __c) - { -@@ -4420,6 +4487,14 @@ - return (poly16x4_t)__builtin_neon_vsri_nv4hi ((int16x4_t) __a, (int16x4_t) __b, __c); + return p; } +@@ -25479,9 +26309,17 @@ + handled_one = true; + break; -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vsriq_n_p64 (poly64x2_t __a, poly64x2_t __b, const int __c) -+{ -+ return (poly64x2_t)__builtin_neon_vsri_nv2di ((int64x2_t) __a, (int64x2_t) __b, __c); -+} ++ /* The INSN is generated in epilogue. It is set as RTX_FRAME_RELATED_P ++ to get correct dwarf information for shrink-wrap. We should not ++ emit unwind information for it because these are used either for ++ pretend arguments or notes to adjust sp and restore registers from ++ stack. */ ++ case REG_CFA_ADJUST_CFA: ++ case REG_CFA_RESTORE: ++ return; + -+#endif - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vsriq_n_s8 (int8x16_t __a, int8x16_t __b, const int __c) - { -@@ -4480,6 +4555,14 @@ - return (poly16x8_t)__builtin_neon_vsri_nv8hi ((int16x8_t) __a, (int16x8_t) __b, __c); + case REG_CFA_DEF_CFA: + case REG_CFA_EXPRESSION: +- case REG_CFA_ADJUST_CFA: + case REG_CFA_OFFSET: + /* ??? Only handling here what we actually emit. */ + gcc_unreachable (); +@@ -25879,6 +26717,7 @@ + case cortexa7: + case cortexa8: + case cortexa9: ++ case cortexa53: + case fa726te: + case marvell_pj4: + return 2; +@@ -25907,6 +26746,7 @@ + { V8QImode, "__builtin_neon_uqi", "16__simd64_uint8_t" }, + { V4HImode, "__builtin_neon_hi", "16__simd64_int16_t" }, + { V4HImode, "__builtin_neon_uhi", "17__simd64_uint16_t" }, ++ { V4HFmode, "__builtin_neon_hf", "18__simd64_float16_t" }, + { V2SImode, "__builtin_neon_si", "16__simd64_int32_t" }, + { V2SImode, "__builtin_neon_usi", "17__simd64_uint32_t" }, + { V2SFmode, "__builtin_neon_sf", "18__simd64_float32_t" }, +@@ -26005,6 +26845,60 @@ + return !TARGET_THUMB1; } -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vsli_n_p64 (poly64x1_t __a, poly64x1_t __b, const int __c) ++tree ++arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) +{ -+ return (poly64x1_t)__builtin_neon_vsli_ndi (__a, __b, __c); -+} ++ enum machine_mode in_mode, out_mode; ++ int in_n, out_n; + -+#endif - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vsli_n_s8 (int8x8_t __a, int8x8_t __b, const int __c) - { -@@ -4540,6 +4623,14 @@ - return (poly16x4_t)__builtin_neon_vsli_nv4hi ((int16x4_t) __a, (int16x4_t) __b, __c); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vsliq_n_p64 (poly64x2_t __a, poly64x2_t __b, const int __c) -+{ -+ return (poly64x2_t)__builtin_neon_vsli_nv2di ((int64x2_t) __a, (int64x2_t) __b, __c); ++ if (TREE_CODE (type_out) != VECTOR_TYPE ++ || TREE_CODE (type_in) != VECTOR_TYPE ++ || !(TARGET_NEON && TARGET_FPU_ARMV8 && flag_unsafe_math_optimizations)) ++ return NULL_TREE; ++ ++ out_mode = TYPE_MODE (TREE_TYPE (type_out)); ++ out_n = TYPE_VECTOR_SUBPARTS (type_out); ++ in_mode = TYPE_MODE (TREE_TYPE (type_in)); ++ in_n = TYPE_VECTOR_SUBPARTS (type_in); ++ ++/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the ++ decl of the vectorized builtin for the appropriate vector mode. ++ NULL_TREE is returned if no such builtin is available. */ ++#undef ARM_CHECK_BUILTIN_MODE ++#define ARM_CHECK_BUILTIN_MODE(C) \ ++ (out_mode == SFmode && out_n == C \ ++ && in_mode == SFmode && in_n == C) ++ ++#undef ARM_FIND_VRINT_VARIANT ++#define ARM_FIND_VRINT_VARIANT(N) \ ++ (ARM_CHECK_BUILTIN_MODE (2) \ ++ ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \ ++ : (ARM_CHECK_BUILTIN_MODE (4) \ ++ ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \ ++ : NULL_TREE)) ++ ++ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) ++ { ++ enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); ++ switch (fn) ++ { ++ case BUILT_IN_FLOORF: ++ return ARM_FIND_VRINT_VARIANT (vrintm); ++ case BUILT_IN_CEILF: ++ return ARM_FIND_VRINT_VARIANT (vrintp); ++ case BUILT_IN_TRUNCF: ++ return ARM_FIND_VRINT_VARIANT (vrintz); ++ case BUILT_IN_ROUNDF: ++ return ARM_FIND_VRINT_VARIANT (vrinta); ++ default: ++ return NULL_TREE; ++ } ++ } ++ return NULL_TREE; +} ++#undef ARM_CHECK_BUILTIN_MODE ++#undef ARM_FIND_VRINT_VARIANT + -+#endif - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vsliq_n_s8 (int8x16_t __a, int8x16_t __b, const int __c) - { -@@ -5308,6 +5399,14 @@ - return (uint64x2_t)__builtin_neon_vset_lanev2di ((__builtin_neon_di) __a, (int64x2_t) __b, __c); + /* The AAPCS sets the maximum alignment of a vector to 64 bits. */ + static HOST_WIDE_INT + arm_vector_alignment (const_tree type) +@@ -26235,40 +27129,72 @@ + emit_insn (gen_memory_barrier ()); } -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vcreate_p64 (uint64_t __a) -+{ -+ return (poly64x1_t)__builtin_neon_vcreatedi ((__builtin_neon_di) __a); -+} -+ -+#endif - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vcreate_s8 (uint64_t __a) +-/* Emit the load-exclusive and store-exclusive instructions. */ ++/* Emit the load-exclusive and store-exclusive instructions. ++ Use acquire and release versions if necessary. */ + + static void +-arm_emit_load_exclusive (enum machine_mode mode, rtx rval, rtx mem) ++arm_emit_load_exclusive (enum machine_mode mode, rtx rval, rtx mem, bool acq) { -@@ -5428,6 +5527,14 @@ - return (poly16x4_t)__builtin_neon_vdup_nv4hi ((__builtin_neon_hi) __a); + rtx (*gen) (rtx, rtx); + +- switch (mode) ++ if (acq) + { +- case QImode: gen = gen_arm_load_exclusiveqi; break; +- case HImode: gen = gen_arm_load_exclusivehi; break; +- case SImode: gen = gen_arm_load_exclusivesi; break; +- case DImode: gen = gen_arm_load_exclusivedi; break; +- default: +- gcc_unreachable (); ++ switch (mode) ++ { ++ case QImode: gen = gen_arm_load_acquire_exclusiveqi; break; ++ case HImode: gen = gen_arm_load_acquire_exclusivehi; break; ++ case SImode: gen = gen_arm_load_acquire_exclusivesi; break; ++ case DImode: gen = gen_arm_load_acquire_exclusivedi; break; ++ default: ++ gcc_unreachable (); ++ } + } ++ else ++ { ++ switch (mode) ++ { ++ case QImode: gen = gen_arm_load_exclusiveqi; break; ++ case HImode: gen = gen_arm_load_exclusivehi; break; ++ case SImode: gen = gen_arm_load_exclusivesi; break; ++ case DImode: gen = gen_arm_load_exclusivedi; break; ++ default: ++ gcc_unreachable (); ++ } ++ } + + emit_insn (gen (rval, mem)); } -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vdup_n_p64 (poly64_t __a) -+{ -+ return (poly64x1_t)__builtin_neon_vdup_ndi ((__builtin_neon_di) __a); -+} -+ -+#endif - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vdup_n_s64 (int64_t __a) + static void +-arm_emit_store_exclusive (enum machine_mode mode, rtx bval, rtx rval, rtx mem) ++arm_emit_store_exclusive (enum machine_mode mode, rtx bval, rtx rval, ++ rtx mem, bool rel) { -@@ -5440,6 +5547,14 @@ - return (uint64x1_t)__builtin_neon_vdup_ndi ((__builtin_neon_di) __a); + rtx (*gen) (rtx, rtx, rtx); + +- switch (mode) ++ if (rel) + { +- case QImode: gen = gen_arm_store_exclusiveqi; break; +- case HImode: gen = gen_arm_store_exclusivehi; break; +- case SImode: gen = gen_arm_store_exclusivesi; break; +- case DImode: gen = gen_arm_store_exclusivedi; break; +- default: +- gcc_unreachable (); ++ switch (mode) ++ { ++ case QImode: gen = gen_arm_store_release_exclusiveqi; break; ++ case HImode: gen = gen_arm_store_release_exclusivehi; break; ++ case SImode: gen = gen_arm_store_release_exclusivesi; break; ++ case DImode: gen = gen_arm_store_release_exclusivedi; break; ++ default: ++ gcc_unreachable (); ++ } + } ++ else ++ { ++ switch (mode) ++ { ++ case QImode: gen = gen_arm_store_exclusiveqi; break; ++ case HImode: gen = gen_arm_store_exclusivehi; break; ++ case SImode: gen = gen_arm_store_exclusivesi; break; ++ case DImode: gen = gen_arm_store_exclusivedi; break; ++ default: ++ gcc_unreachable (); ++ } ++ } + + emit_insn (gen (bval, rval, mem)); } +@@ -26303,6 +27229,15 @@ + mod_f = operands[7]; + mode = GET_MODE (mem); -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vdupq_n_p64 (poly64_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vdup_nv2di ((__builtin_neon_di) __a); -+} ++ /* Normally the succ memory model must be stronger than fail, but in the ++ unlikely event of fail being ACQUIRE and succ being RELEASE we need to ++ promote succ to ACQ_REL so that we don't lose the acquire semantics. */ + -+#endif - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vdupq_n_s8 (int8_t __a) - { -@@ -5692,6 +5807,14 @@ - return (poly16x4_t)__builtin_neon_vdup_lanev4hi ((int16x4_t) __a, __b); - } ++ if (TARGET_HAVE_LDACQ ++ && INTVAL (mod_f) == MEMMODEL_ACQUIRE ++ && INTVAL (mod_s) == MEMMODEL_RELEASE) ++ mod_s = GEN_INT (MEMMODEL_ACQ_REL); ++ + switch (mode) + { + case QImode: +@@ -26377,8 +27312,20 @@ + scratch = operands[7]; + mode = GET_MODE (mem); -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vdup_lane_p64 (poly64x1_t __a, const int __b) -+{ -+ return (poly64x1_t)__builtin_neon_vdup_lanedi (__a, __b); -+} +- arm_pre_atomic_barrier (mod_s); ++ bool use_acquire = TARGET_HAVE_LDACQ ++ && !(mod_s == MEMMODEL_RELAXED ++ || mod_s == MEMMODEL_CONSUME ++ || mod_s == MEMMODEL_RELEASE); + ++ bool use_release = TARGET_HAVE_LDACQ ++ && !(mod_s == MEMMODEL_RELAXED ++ || mod_s == MEMMODEL_CONSUME ++ || mod_s == MEMMODEL_ACQUIRE); + -+#endif - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vdup_lane_s64 (int64x1_t __a, const int __b) - { -@@ -5758,6 +5881,14 @@ - return (poly16x8_t)__builtin_neon_vdup_lanev8hi ((int16x4_t) __a, __b); - } ++ /* Checks whether a barrier is needed and emits one accordingly. */ ++ if (!(use_acquire || use_release)) ++ arm_pre_atomic_barrier (mod_s); ++ + label1 = NULL_RTX; + if (!is_weak) + { +@@ -26387,7 +27334,7 @@ + } + label2 = gen_label_rtx (); -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vdupq_lane_p64 (poly64x1_t __a, const int __b) -+{ -+ return (poly64x2_t)__builtin_neon_vdup_lanev2di (__a, __b); -+} +- arm_emit_load_exclusive (mode, rval, mem); ++ arm_emit_load_exclusive (mode, rval, mem, use_acquire); + + cond = arm_gen_compare_reg (NE, rval, oldval, scratch); + x = gen_rtx_NE (VOIDmode, cond, const0_rtx); +@@ -26395,7 +27342,7 @@ + gen_rtx_LABEL_REF (Pmode, label2), pc_rtx); + emit_unlikely_jump (gen_rtx_SET (VOIDmode, pc_rtx, x)); + +- arm_emit_store_exclusive (mode, scratch, mem, newval); ++ arm_emit_store_exclusive (mode, scratch, mem, newval, use_release); + + /* Weak or strong, we want EQ to be true for success, so that we + match the flags that we got from the compare above. */ +@@ -26414,7 +27361,9 @@ + if (mod_f != MEMMODEL_RELAXED) + emit_label (label2); + +- arm_post_atomic_barrier (mod_s); ++ /* Checks whether a barrier is needed and emits one accordingly. */ ++ if (!(use_acquire || use_release)) ++ arm_post_atomic_barrier (mod_s); + + if (mod_f == MEMMODEL_RELAXED) + emit_label (label2); +@@ -26429,8 +27378,20 @@ + enum machine_mode wmode = (mode == DImode ? DImode : SImode); + rtx label, x; + +- arm_pre_atomic_barrier (model); ++ bool use_acquire = TARGET_HAVE_LDACQ ++ && !(model == MEMMODEL_RELAXED ++ || model == MEMMODEL_CONSUME ++ || model == MEMMODEL_RELEASE); + ++ bool use_release = TARGET_HAVE_LDACQ ++ && !(model == MEMMODEL_RELAXED ++ || model == MEMMODEL_CONSUME ++ || model == MEMMODEL_ACQUIRE); + -+#endif - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vdupq_lane_s64 (int64x1_t __a, const int __b) - { -@@ -5770,6 +5901,14 @@ - return (uint64x2_t)__builtin_neon_vdup_lanev2di ((int64x1_t) __a, __b); ++ /* Checks whether a barrier is needed and emits one accordingly. */ ++ if (!(use_acquire || use_release)) ++ arm_pre_atomic_barrier (model); ++ + label = gen_label_rtx (); + emit_label (label); + +@@ -26442,7 +27403,7 @@ + old_out = new_out; + value = simplify_gen_subreg (wmode, value, mode, 0); + +- arm_emit_load_exclusive (mode, old_out, mem); ++ arm_emit_load_exclusive (mode, old_out, mem, use_acquire); + + switch (code) + { +@@ -26490,12 +27451,15 @@ + break; + } + +- arm_emit_store_exclusive (mode, cond, mem, gen_lowpart (mode, new_out)); ++ arm_emit_store_exclusive (mode, cond, mem, gen_lowpart (mode, new_out), ++ use_release); + + x = gen_rtx_NE (VOIDmode, cond, const0_rtx); + emit_unlikely_jump (gen_cbranchsi4 (x, cond, const0_rtx, label)); + +- arm_post_atomic_barrier (model); ++ /* Checks whether a barrier is needed and emits one accordingly. */ ++ if (!(use_acquire || use_release)) ++ arm_post_atomic_barrier (model); } + + #define MAX_VECT_LEN 16 +@@ -27435,4 +28399,12 @@ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vcombine_p64 (poly64x1_t __a, poly64x1_t __b) -+{ -+ return (poly64x2_t)__builtin_neon_vcombinedi (__a, __b); -+} -+ -+#endif - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vcombine_s8 (int8x8_t __a, int8x8_t __b) - { -@@ -5836,6 +5975,14 @@ - return (poly16x8_t)__builtin_neon_vcombinev4hi ((int16x4_t) __a, (int16x4_t) __b); } -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vget_high_p64 (poly64x2_t __a) ++/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ ++ ++static unsigned HOST_WIDE_INT ++arm_asan_shadow_offset (void) +{ -+ return (poly64x1_t)__builtin_neon_vget_highv2di ((int64x2_t) __a); ++ return (unsigned HOST_WIDE_INT) 1 << 29; +} + -+#endif - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vget_high_s8 (int8x16_t __a) - { -@@ -5956,6 +6103,14 @@ - return (poly16x4_t)__builtin_neon_vget_lowv8hi ((int16x8_t) __a); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vget_low_p64 (poly64x2_t __a) -+{ -+ return (poly64x1_t)__builtin_neon_vget_lowv2di ((int64x2_t) __a); -+} + #include "gt-arm.h" +--- a/src/gcc/config/arm/t-aprofile ++++ b/src/gcc/config/arm/t-aprofile +@@ -0,0 +1,177 @@ ++# Copyright (C) 2012-2013 Free Software Foundation, Inc. ++# ++# This file is part of GCC. ++# ++# GCC is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++# ++# GCC is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GCC; see the file COPYING3. If not see ++# . ++ ++# This is a target makefile fragment that attempts to get ++# multilibs built for the range of CPU's, FPU's and ABI's that ++# are relevant for the A-profile architecture. It should ++# not be used in conjunction with another make file fragment and ++# assumes --with-arch, --with-cpu, --with-fpu, --with-float, --with-mode ++# have their default values during the configure step. We enforce ++# this during the top-level configury. ++ ++MULTILIB_OPTIONS = ++MULTILIB_DIRNAMES = ++MULTILIB_EXCEPTIONS = ++MULTILIB_MATCHES = ++MULTILIB_REUSE = ++ ++# We have the following hierachy: ++# ISA: A32 (.) or T32 (thumb) ++# Architecture: ARMv7-A (v7-a), ARMv7VE (v7ve), or ARMv8-A (v8-a). ++# FPU: VFPv3-D16 (fpv3), NEONv1 (simdv1), VFPv4-D16 (fpv4), ++# NEON-VFPV4 (simdvfpv4), NEON for ARMv8 (simdv8), or None (.). ++# Float-abi: Soft (.), softfp (softfp), or hard (hardfp). ++ ++# We use the option -mcpu=cortex-a7 because we do not yet have march=armv7ve ++# or march=armv7a+virt as a command line option for the compiler. ++MULTILIB_OPTIONS += mthumb ++MULTILIB_DIRNAMES += thumb ++ ++MULTILIB_OPTIONS += march=armv7-a/mcpu=cortex-a7/march=armv8-a ++MULTILIB_DIRNAMES += v7-a v7ve v8-a ++ ++MULTILIB_OPTIONS += mfpu=vfpv3-d16/mfpu=neon/mfpu=vfpv4-d16/mfpu=neon-vfpv4/mfpu=neon-fp-armv8 ++MULTILIB_DIRNAMES += fpv3 simdv1 fpv4 simdvfpv4 simdv8 ++ ++MULTILIB_OPTIONS += mfloat-abi=softfp/mfloat-abi=hard ++MULTILIB_DIRNAMES += softfp hard ++ ++# We don't build no-float libraries with an FPU. ++MULTILIB_EXCEPTIONS += *mfpu=vfpv3-d16 ++MULTILIB_EXCEPTIONS += *mfpu=neon ++MULTILIB_EXCEPTIONS += *mfpu=vfpv4-d16 ++MULTILIB_EXCEPTIONS += *mfpu=neon-vfpv4 ++MULTILIB_EXCEPTIONS += *mfpu=neon-fp-armv8 ++ ++# We don't build libraries requiring an FPU at the CPU/Arch/ISA level. ++MULTILIB_EXCEPTIONS += mfloat-abi=* ++MULTILIB_EXCEPTIONS += mfpu=* ++MULTILIB_EXCEPTIONS += mthumb/mfloat-abi=* ++MULTILIB_EXCEPTIONS += mthumb/mfpu=* ++MULTILIB_EXCEPTIONS += *march=armv7-a/mfloat-abi=* ++MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/mfloat-abi=* ++MULTILIB_EXCEPTIONS += *march=armv8-a/mfloat-abi=* ++ ++# Ensure the correct FPU variants apply to the correct base architectures. ++MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/*mfpu=vfpv3-d16* ++MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/*mfpu=neon/* ++MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=vfpv3-d16* ++MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=neon/* ++MULTILIB_EXCEPTIONS += *march=armv7-a/*mfpu=vfpv4-d16* ++MULTILIB_EXCEPTIONS += *march=armv7-a/*mfpu=neon-vfpv4* ++MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=vfpv4-d16* ++MULTILIB_EXCEPTIONS += *march=armv8-a/*mfpu=neon-vfpv4* ++MULTILIB_EXCEPTIONS += *march=armv7-a/*mfpu=neon-fp-armv8* ++MULTILIB_EXCEPTIONS += *mcpu=cortex-a7/*mfpu=neon-fp-armv8* ++ ++# CPU Matches ++MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a8 ++MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a9 ++MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a5 ++MULTILIB_MATCHES += mcpu?cortex-a7=mcpu?cortex-a15 ++MULTILIB_MATCHES += march?armv8-a=mcpu?cortex-a53 ++ ++# FPU matches ++MULTILIB_MATCHES += mfpu?vfpv3-d16=mfpu?vfpv3 ++MULTILIB_MATCHES += mfpu?vfpv3-d16=mfpu?vfpv3-fp16 ++MULTILIB_MATCHES += mfpu?vfpv3-d16=mfpu?vfpv3-fp16-d16 ++MULTILIB_MATCHES += mfpu?vfpv4-d16=mfpu?vfpv4 ++MULTILIB_MATCHES += mfpu?neon-fp-armv8=mfpu?crypto-neon-fp-armv8 ++ ++ ++# Map all requests for vfpv3 with a later CPU to vfpv3-d16 v7-a. ++# So if new CPUs are added above at the newer architecture levels, ++# do something to map them below here. ++# We take the approach of mapping down to v7-a regardless of what ++# the fp option is if the integer architecture brings things down. ++# This applies to any similar combination at the v7ve and v8-a arch ++# levels. ++ ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.softfp ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.softfp ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.softfp ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7-a/mfpu.fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7-a/mfpu.fp-armv8/mfloat-abi.softfp ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7-a/mfpu.vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7-a/mfpu.vfpv4/mfloat-abi.softfp + -+#endif - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vget_low_s64 (int64x2_t __a) - { -@@ -6016,6 +6171,22 @@ - return (uint32x4_t)__builtin_neon_vcvtv4sf (__a, 0); - } - -+#if ((__ARM_FP & 0x2) != 0) -+__extension__ static __inline float16x4_t __attribute__ ((__always_inline__)) -+vcvt_f16_f32 (float32x4_t __a) -+{ -+ return (float16x4_t)__builtin_neon_vcvtv4hfv4sf (__a); -+} + -+#endif -+#if ((__ARM_FP & 0x2) != 0) -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vcvt_f32_f16 (float16x4_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vcvtv4sfv4hf (__a); -+} ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=mcpu.cortex-a7/mfpu.neon/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.neon/mfloat-abi.softfp ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv8-a/mfpu.neon/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv8-a/mfpu.neon/mfloat-abi.softfp ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.softfp ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.softfp + -+#endif - __extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) - vcvt_n_s32_f32 (float32x2_t __a, const int __b) - { -@@ -7024,6 +7195,14 @@ - return (int64x2_t)__builtin_neon_vqdmlsl_nv2si (__a, __b, (__builtin_neon_si) __c, 1); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vext_p64 (poly64x1_t __a, poly64x1_t __b, const int __c) -+{ -+ return (poly64x1_t)__builtin_neon_vextdi (__a, __b, __c); -+} + -+#endif - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vext_s8 (int8x8_t __a, int8x8_t __b, const int __c) - { -@@ -7090,6 +7269,14 @@ - return (poly16x4_t)__builtin_neon_vextv4hi ((int16x4_t) __a, (int16x4_t) __b, __c); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vextq_p64 (poly64x2_t __a, poly64x2_t __b, const int __c) -+{ -+ return (poly64x2_t)__builtin_neon_vextv2di ((int64x2_t) __a, (int64x2_t) __b, __c); -+} ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.softfp ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv4/mfloat-abi.softfp ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.hard ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.softfp + -+#endif - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vextq_s8 (int8x16_t __a, int8x16_t __b, const int __c) - { -@@ -7372,6 +7559,14 @@ - return (poly8x16_t) __builtin_shuffle (__a, (uint8x16_t) { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 }); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vbsl_p64 (uint64x1_t __a, poly64x1_t __b, poly64x1_t __c) -+{ -+ return (poly64x1_t)__builtin_neon_vbsldi ((int64x1_t) __a, __b, __c); -+} + -+#endif - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vbsl_s8 (uint8x8_t __a, int8x8_t __b, int8x8_t __c) - { -@@ -7438,6 +7633,14 @@ - return (poly16x4_t)__builtin_neon_vbslv4hi ((int16x4_t) __a, (int16x4_t) __b, (int16x4_t) __c); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vbslq_p64 (uint64x2_t __a, poly64x2_t __b, poly64x2_t __c) -+{ -+ return (poly64x2_t)__builtin_neon_vbslv2di ((int64x2_t) __a, (int64x2_t) __b, (int64x2_t) __c); -+} ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.softfp ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.softfp + -+#endif - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vbslq_s8 (uint8x16_t __a, int8x16_t __b, int8x16_t __c) - { -@@ -7990,6 +8193,14 @@ - return __rv; - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vld1_p64 (const poly64_t * __a) -+{ -+ return (poly64x1_t)__builtin_neon_vld1di ((const __builtin_neon_di *) __a); -+} + -+#endif - __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) - vld1_s8 (const int8_t * __a) - { -@@ -8056,6 +8267,14 @@ - return (poly16x4_t)__builtin_neon_vld1v4hi ((const __builtin_neon_hi *) __a); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vld1q_p64 (const poly64_t * __a) -+{ -+ return (poly64x2_t)__builtin_neon_vld1v2di ((const __builtin_neon_di *) __a); -+} + -+#endif - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) - vld1q_s8 (const int8_t * __a) - { -@@ -8176,6 +8395,14 @@ - return (poly16x4_t)__builtin_neon_vld1_lanev4hi ((const __builtin_neon_hi *) __a, (int16x4_t) __b, __c); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vld1_lane_p64 (const poly64_t * __a, poly64x1_t __b, const int __c) -+{ -+ return (poly64x1_t)__builtin_neon_vld1_lanedi ((const __builtin_neon_di *) __a, __b, __c); -+} ++# And again for mthumb. + -+#endif - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vld1_lane_s64 (const int64_t * __a, int64x1_t __b, const int __c) - { -@@ -8242,6 +8469,14 @@ - return (poly16x8_t)__builtin_neon_vld1_lanev8hi ((const __builtin_neon_hi *) __a, (int16x8_t) __b, __c); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vld1q_lane_p64 (const poly64_t * __a, poly64x2_t __b, const int __c) -+{ -+ return (poly64x2_t)__builtin_neon_vld1_lanev2di ((const __builtin_neon_di *) __a, (int64x2_t) __b, __c); -+} ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.vfpv3-d16/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.fp-armv8/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.vfpv4/mfloat-abi.softfp + -+#endif - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vld1q_lane_s64 (const int64_t * __a, int64x2_t __b, const int __c) - { -@@ -8308,6 +8543,14 @@ - return (poly16x4_t)__builtin_neon_vld1_dupv4hi ((const __builtin_neon_hi *) __a); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vld1_dup_p64 (const poly64_t * __a) -+{ -+ return (poly64x1_t)__builtin_neon_vld1_dupdi ((const __builtin_neon_di *) __a); -+} + -+#endif - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vld1_dup_s64 (const int64_t * __a) - { -@@ -8374,6 +8617,14 @@ - return (poly16x8_t)__builtin_neon_vld1_dupv8hi ((const __builtin_neon_hi *) __a); - } - -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vld1q_dup_p64 (const poly64_t * __a) -+{ -+ return (poly64x2_t)__builtin_neon_vld1_dupv2di ((const __builtin_neon_di *) __a); -+} ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.neon/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.neon/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.neon/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.neon/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.softfp + -+#endif - __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) - vld1q_dup_s64 (const int64_t * __a) - { -@@ -8386,7 +8637,15 @@ - return (uint64x2_t)__builtin_neon_vld1_dupv2di ((const __builtin_neon_di *) __a); - } - -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline void __attribute__ ((__always_inline__)) -+vst1_p64 (poly64_t * __a, poly64x1_t __b) -+{ -+ __builtin_neon_vst1di ((__builtin_neon_di *) __a, __b); -+} + -+#endif -+__extension__ static __inline void __attribute__ ((__always_inline__)) - vst1_s8 (int8_t * __a, int8x8_t __b) - { - __builtin_neon_vst1v8qi ((__builtin_neon_qi *) __a, __b); -@@ -8452,7 +8711,15 @@ - __builtin_neon_vst1v4hi ((__builtin_neon_hi *) __a, (int16x4_t) __b); - } - -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline void __attribute__ ((__always_inline__)) -+vst1q_p64 (poly64_t * __a, poly64x2_t __b) -+{ -+ __builtin_neon_vst1v2di ((__builtin_neon_di *) __a, (int64x2_t) __b); -+} ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.fp-armv8/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv4/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.vfpv4-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.softfp + -+#endif -+__extension__ static __inline void __attribute__ ((__always_inline__)) - vst1q_s8 (int8_t * __a, int8x16_t __b) - { - __builtin_neon_vst1v16qi ((__builtin_neon_qi *) __a, __b); -@@ -8572,7 +8839,15 @@ - __builtin_neon_vst1_lanev4hi ((__builtin_neon_hi *) __a, (int16x4_t) __b, __c); - } - -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline void __attribute__ ((__always_inline__)) -+vst1_lane_p64 (poly64_t * __a, poly64x1_t __b, const int __c) -+{ -+ __builtin_neon_vst1_lanedi ((__builtin_neon_di *) __a, __b, __c); -+} + -+#endif -+__extension__ static __inline void __attribute__ ((__always_inline__)) - vst1_lane_s64 (int64_t * __a, int64x1_t __b, const int __c) - { - __builtin_neon_vst1_lanedi ((__builtin_neon_di *) __a, __b, __c); -@@ -8638,7 +8913,15 @@ - __builtin_neon_vst1_lanev8hi ((__builtin_neon_hi *) __a, (int16x8_t) __b, __c); - } ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.softfp ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.hard=mthumb/mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.hard ++MULTILIB_REUSE += mthumb/mcpu.cortex-a7/mfpu.neon-vfpv4/mfloat-abi.softfp=mthumb/mcpu.cortex-a7/mfpu.neon-fp-armv8/mfloat-abi.softfp +--- a/src/gcc/config/arm/arm.h ++++ b/src/gcc/config/arm/arm.h +@@ -183,6 +183,11 @@ -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline void __attribute__ ((__always_inline__)) -+vst1q_lane_p64 (poly64_t * __a, poly64x2_t __b, const int __c) -+{ -+ __builtin_neon_vst1_lanev2di ((__builtin_neon_di *) __a, (int64x2_t) __b, __c); -+} -+ -+#endif -+__extension__ static __inline void __attribute__ ((__always_inline__)) - vst1q_lane_s64 (int64_t * __a, int64x2_t __b, const int __c) - { - __builtin_neon_vst1_lanev2di ((__builtin_neon_di *) __a, __b, __c); -@@ -8722,6 +9005,16 @@ - return __rv.__i; - } + #define ARM_INVERSE_CONDITION_CODE(X) ((arm_cc) (((int)X) ^ 1)) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1x2_t __attribute__ ((__always_inline__)) -+vld2_p64 (const poly64_t * __a) -+{ -+ union { poly64x1x2_t __i; __builtin_neon_ti __o; } __rv; -+ __rv.__o = __builtin_neon_vld2di ((const __builtin_neon_di *) __a); -+ return __rv.__i; -+} ++/* The maximaum number of instructions that is beneficial to ++ conditionally execute. */ ++#undef MAX_CONDITIONAL_EXECUTE ++#define MAX_CONDITIONAL_EXECUTE arm_max_conditional_execute () + -+#endif - __extension__ static __inline int64x1x2_t __attribute__ ((__always_inline__)) - vld2_s64 (const int64_t * __a) - { -@@ -9017,6 +9310,16 @@ - return __rv.__i; - } + extern int arm_target_label; + extern int arm_ccfsm_state; + extern GTY(()) rtx arm_target_insn; +@@ -350,10 +355,16 @@ + #define TARGET_HAVE_LDREXD (((arm_arch6k && TARGET_ARM) || arm_arch7) \ + && arm_arch_notm) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1x2_t __attribute__ ((__always_inline__)) -+vld2_dup_p64 (const poly64_t * __a) -+{ -+ union { poly64x1x2_t __i; __builtin_neon_ti __o; } __rv; -+ __rv.__o = __builtin_neon_vld2_dupdi ((const __builtin_neon_di *) __a); -+ return __rv.__i; -+} ++/* Nonzero if this chip supports load-acquire and store-release. */ ++#define TARGET_HAVE_LDACQ (TARGET_ARM_ARCH >= 8) + -+#endif - __extension__ static __inline int64x1x2_t __attribute__ ((__always_inline__)) - vld2_dup_s64 (const int64_t * __a) - { -@@ -9096,7 +9399,16 @@ - __builtin_neon_vst2v4hi ((__builtin_neon_hi *) __a, __bu.__o); - } + /* Nonzero if integer division instructions supported. */ + #define TARGET_IDIV ((TARGET_ARM && arm_arch_arm_hwdiv) \ + || (TARGET_THUMB2 && arm_arch_thumb_hwdiv)) -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline void __attribute__ ((__always_inline__)) -+vst2_p64 (poly64_t * __a, poly64x1x2_t __b) -+{ -+ union { poly64x1x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; -+ __builtin_neon_vst2di ((__builtin_neon_di *) __a, __bu.__o); -+} ++/* Should NEON be used for 64-bits bitops. */ ++#define TARGET_PREFER_NEON_64BITS (prefer_neon_for_64bits) + -+#endif -+__extension__ static __inline void __attribute__ ((__always_inline__)) - vst2_s64 (int64_t * __a, int64x1x2_t __b) - { - union { int64x1x2_t __i; __builtin_neon_ti __o; } __bu = { __b }; -@@ -9350,6 +9662,16 @@ - return __rv.__i; - } + /* True iff the full BPABI is being used. If TARGET_BPABI is true, + then TARGET_AAPCS_BASED must be true -- but the converse does not + hold. TARGET_BPABI implies the use of the BPABI runtime library, +@@ -539,6 +550,10 @@ + /* Nonzero if chip supports integer division instruction in Thumb mode. */ + extern int arm_arch_thumb_hwdiv; -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1x3_t __attribute__ ((__always_inline__)) -+vld3_p64 (const poly64_t * __a) -+{ -+ union { poly64x1x3_t __i; __builtin_neon_ei __o; } __rv; -+ __rv.__o = __builtin_neon_vld3di ((const __builtin_neon_di *) __a); -+ return __rv.__i; -+} ++/* Nonzero if we should use Neon to handle 64-bits operations rather ++ than core registers. */ ++extern int prefer_neon_for_64bits; + -+#endif - __extension__ static __inline int64x1x3_t __attribute__ ((__always_inline__)) - vld3_s64 (const int64_t * __a) - { -@@ -9645,6 +9967,16 @@ - return __rv.__i; - } + #ifndef TARGET_DEFAULT + #define TARGET_DEFAULT (MASK_APCS_FRAME) + #endif +@@ -630,6 +645,8 @@ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1x3_t __attribute__ ((__always_inline__)) -+vld3_dup_p64 (const poly64_t * __a) -+{ -+ union { poly64x1x3_t __i; __builtin_neon_ei __o; } __rv; -+ __rv.__o = __builtin_neon_vld3_dupdi ((const __builtin_neon_di *) __a); -+ return __rv.__i; -+} -+ -+#endif - __extension__ static __inline int64x1x3_t __attribute__ ((__always_inline__)) - vld3_dup_s64 (const int64_t * __a) - { -@@ -9724,7 +10056,16 @@ - __builtin_neon_vst3v4hi ((__builtin_neon_hi *) __a, __bu.__o); - } + #define BIGGEST_ALIGNMENT (ARM_DOUBLEWORD_ALIGN ? DOUBLEWORD_ALIGNMENT : 32) -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline void __attribute__ ((__always_inline__)) -+vst3_p64 (poly64_t * __a, poly64x1x3_t __b) -+{ -+ union { poly64x1x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; -+ __builtin_neon_vst3di ((__builtin_neon_di *) __a, __bu.__o); -+} ++#define MALLOC_ABI_ALIGNMENT BIGGEST_ALIGNMENT + -+#endif -+__extension__ static __inline void __attribute__ ((__always_inline__)) - vst3_s64 (int64_t * __a, int64x1x3_t __b) - { - union { int64x1x3_t __i; __builtin_neon_ei __o; } __bu = { __b }; -@@ -9978,6 +10319,16 @@ - return __rv.__i; - } + /* XXX Blah -- this macro is used directly by libobjc. Since it + supports no vector modes, cut out the complexity and fall back + on BIGGEST_FIELD_ALIGNMENT. */ +@@ -1040,7 +1057,7 @@ + /* Modes valid for Neon D registers. */ + #define VALID_NEON_DREG_MODE(MODE) \ + ((MODE) == V2SImode || (MODE) == V4HImode || (MODE) == V8QImode \ +- || (MODE) == V2SFmode || (MODE) == DImode) ++ || (MODE) == V4HFmode || (MODE) == V2SFmode || (MODE) == DImode) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1x4_t __attribute__ ((__always_inline__)) -+vld4_p64 (const poly64_t * __a) -+{ -+ union { poly64x1x4_t __i; __builtin_neon_oi __o; } __rv; -+ __rv.__o = __builtin_neon_vld4di ((const __builtin_neon_di *) __a); -+ return __rv.__i; -+} -+ -+#endif - __extension__ static __inline int64x1x4_t __attribute__ ((__always_inline__)) - vld4_s64 (const int64_t * __a) - { -@@ -10273,6 +10624,16 @@ - return __rv.__i; - } + /* Modes valid for Neon Q registers. */ + #define VALID_NEON_QREG_MODE(MODE) \ +@@ -1130,6 +1147,7 @@ + STACK_REG, + BASE_REGS, + HI_REGS, ++ CALLER_SAVE_REGS, + GENERAL_REGS, + CORE_REGS, + VFP_D0_D7_REGS, +@@ -1156,6 +1174,7 @@ + "STACK_REG", \ + "BASE_REGS", \ + "HI_REGS", \ ++ "CALLER_SAVE_REGS", \ + "GENERAL_REGS", \ + "CORE_REGS", \ + "VFP_D0_D7_REGS", \ +@@ -1181,6 +1200,7 @@ + { 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ + { 0x000020FF, 0x00000000, 0x00000000, 0x00000000 }, /* BASE_REGS */ \ + { 0x00005F00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \ ++ { 0x0000100F, 0x00000000, 0x00000000, 0x00000000 }, /* CALLER_SAVE_REGS */ \ + { 0x00005FFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \ + { 0x00007FFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \ + { 0xFFFF0000, 0x00000000, 0x00000000, 0x00000000 }, /* VFP_D0_D7_REGS */ \ +@@ -1639,7 +1659,7 @@ + frame. */ + #define EXIT_IGNORE_STACK 1 -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1x4_t __attribute__ ((__always_inline__)) -+vld4_dup_p64 (const poly64_t * __a) -+{ -+ union { poly64x1x4_t __i; __builtin_neon_oi __o; } __rv; -+ __rv.__o = __builtin_neon_vld4_dupdi ((const __builtin_neon_di *) __a); -+ return __rv.__i; -+} -+ -+#endif - __extension__ static __inline int64x1x4_t __attribute__ ((__always_inline__)) - vld4_dup_s64 (const int64_t * __a) - { -@@ -10352,7 +10713,16 @@ - __builtin_neon_vst4v4hi ((__builtin_neon_hi *) __a, __bu.__o); - } +-#define EPILOGUE_USES(REGNO) ((REGNO) == LR_REGNUM) ++#define EPILOGUE_USES(REGNO) (epilogue_completed && (REGNO) == LR_REGNUM) -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline void __attribute__ ((__always_inline__)) -+vst4_p64 (poly64_t * __a, poly64x1x4_t __b) -+{ -+ union { poly64x1x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; -+ __builtin_neon_vst4di ((__builtin_neon_di *) __a, __bu.__o); -+} -+ -+#endif -+__extension__ static __inline void __attribute__ ((__always_inline__)) - vst4_s64 (int64_t * __a, int64x1x4_t __b) - { - union { int64x1x4_t __i; __builtin_neon_oi __o; } __bu = { __b }; -@@ -11016,23 +11386,25 @@ + /* Determine if the epilogue should be output as RTL. + You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ +--- a/src/gcc/config/arm/cortex-a8.md ++++ b/src/gcc/config/arm/cortex-a8.md +@@ -85,30 +85,27 @@ + ;; (source read in E2 and destination available at the end of that cycle). + (define_insn_reservation "cortex_a8_alu" 2 + (and (eq_attr "tune" "cortexa8") +- (ior (and (and (eq_attr "type" "alu_reg,simple_alu_imm") +- (eq_attr "neon_type" "none")) +- (not (eq_attr "insn" "mov,mvn"))) +- (eq_attr "insn" "clz"))) ++ (ior (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") ++ (eq_attr "neon_type" "none")) ++ (eq_attr "type" "clz"))) + "cortex_a8_default") + (define_insn_reservation "cortex_a8_alu_shift" 2 + (and (eq_attr "tune" "cortexa8") +- (and (eq_attr "type" "simple_alu_shift,alu_shift") +- (not (eq_attr "insn" "mov,mvn")))) ++ (eq_attr "type" "extend,arlo_shift")) + "cortex_a8_default") - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_s8 (int8x8_t __a) -+vreinterpret_p8_p16 (poly16x4_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qiv8qi (__a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); - } + (define_insn_reservation "cortex_a8_alu_shift_reg" 2 + (and (eq_attr "tune" "cortexa8") +- (and (eq_attr "type" "alu_shift_reg") +- (not (eq_attr "insn" "mov,mvn")))) ++ (eq_attr "type" "arlo_shift_reg")) + "cortex_a8_default") - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_s16 (int16x4_t __a) -+vreinterpret_p8_f32 (float32x2_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qiv4hi (__a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qiv2sf (__a); - } + ;; Move instructions. -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_s32 (int32x2_t __a) -+vreinterpret_p8_p64 (poly64x1_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qiv2si (__a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qidi (__a); - } + (define_insn_reservation "cortex_a8_mov" 1 + (and (eq_attr "tune" "cortexa8") +- (and (eq_attr "type" "alu_reg,simple_alu_imm,simple_alu_shift,alu_shift,alu_shift_reg") +- (eq_attr "insn" "mov,mvn"))) ++ (eq_attr "type" "mov_imm,mov_reg,mov_shift,mov_shift_reg,\ ++ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg")) + "cortex_a8_default") -+#endif - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) - vreinterpret_p8_s64 (int64x1_t __a) - { -@@ -11040,101 +11412,79 @@ - } + ;; Exceptions to the default latencies for data processing instructions. +@@ -139,22 +136,22 @@ - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_f32 (float32x2_t __a) -+vreinterpret_p8_u64 (uint64x1_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qiv2sf (__a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qidi ((int64x1_t) __a); - } + (define_insn_reservation "cortex_a8_mul" 6 + (and (eq_attr "tune" "cortexa8") +- (eq_attr "insn" "mul,smulxy,smmul")) ++ (eq_attr "type" "mul,smulxy,smmul")) + "cortex_a8_multiply_2") - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_u8 (uint8x8_t __a) -+vreinterpret_p8_s8 (int8x8_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qiv8qi (__a); - } + (define_insn_reservation "cortex_a8_mla" 6 + (and (eq_attr "tune" "cortexa8") +- (eq_attr "insn" "mla,smlaxy,smlawy,smmla,smlad,smlsd")) ++ (eq_attr "type" "mla,smlaxy,smlawy,smmla,smlad,smlsd")) + "cortex_a8_multiply_2") - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_u16 (uint16x4_t __a) -+vreinterpret_p8_s16 (int16x4_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qiv4hi (__a); - } + (define_insn_reservation "cortex_a8_mull" 7 + (and (eq_attr "tune" "cortexa8") +- (eq_attr "insn" "smull,umull,smlal,umlal,umaal,smlalxy")) ++ (eq_attr "type" "smull,umull,smlal,umlal,umaal,smlalxy")) + "cortex_a8_multiply_3") - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_u32 (uint32x2_t __a) -+vreinterpret_p8_s32 (int32x2_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qiv2si ((int32x2_t) __a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qiv2si (__a); - } + (define_insn_reservation "cortex_a8_smulwy" 5 + (and (eq_attr "tune" "cortexa8") +- (eq_attr "insn" "smulwy,smuad,smusd")) ++ (eq_attr "type" "smulwy,smuad,smusd")) + "cortex_a8_multiply") - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_u64 (uint64x1_t __a) -+vreinterpret_p8_u8 (uint8x8_t __a) - { -- return (poly8x8_t)__builtin_neon_vreinterpretv8qidi ((int64x1_t) __a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); - } + ;; smlald and smlsld are multiply-accumulate instructions but do not +@@ -162,7 +159,7 @@ + ;; cannot go in cortex_a8_mla above. (See below for bypass details.) + (define_insn_reservation "cortex_a8_smlald" 6 + (and (eq_attr "tune" "cortexa8") +- (eq_attr "insn" "smlald,smlsld")) ++ (eq_attr "type" "smlald,smlsld")) + "cortex_a8_multiply_2") - __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) --vreinterpret_p8_p16 (poly16x4_t __a) -+vreinterpret_p8_u16 (uint16x4_t __a) - { - return (poly8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); - } + ;; A multiply with a single-register result or an MLA, followed by an +--- a/src/gcc/config/arm/arm-fixed.md ++++ b/src/gcc/config/arm/arm-fixed.md +@@ -19,12 +19,13 @@ + ;; This file contains ARM instructions that support fixed-point operations. --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_s8 (int8x16_t __a) -+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_p8_u32 (uint32x2_t __a) - { -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv16qi (__a); -+ return (poly8x8_t)__builtin_neon_vreinterpretv8qiv2si ((int32x2_t) __a); - } + (define_insn "add3" +- [(set (match_operand:FIXED 0 "s_register_operand" "=r") +- (plus:FIXED (match_operand:FIXED 1 "s_register_operand" "r") +- (match_operand:FIXED 2 "s_register_operand" "r")))] ++ [(set (match_operand:FIXED 0 "s_register_operand" "=l,r") ++ (plus:FIXED (match_operand:FIXED 1 "s_register_operand" "l,r") ++ (match_operand:FIXED 2 "s_register_operand" "l,r")))] + "TARGET_32BIT" + "add%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "yes,no")]) --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_s16 (int16x8_t __a) -+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_p16_p8 (poly8x8_t __a) - { -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv8hi (__a); -+ return (poly16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); - } + (define_insn "add3" + [(set (match_operand:ADDSUB 0 "s_register_operand" "=r") +@@ -32,7 +33,8 @@ + (match_operand:ADDSUB 2 "s_register_operand" "r")))] + "TARGET_INT_SIMD" + "sadd%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_s32 (int32x4_t __a) -+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_p16_f32 (float32x2_t __a) - { -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv4si (__a); -+ return (poly16x4_t)__builtin_neon_vreinterpretv4hiv2sf (__a); - } + (define_insn "usadd3" + [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r") +@@ -40,7 +42,8 @@ + (match_operand:UQADDSUB 2 "s_register_operand" "r")))] + "TARGET_INT_SIMD" + "uqadd%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_s64 (int64x2_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_p16_p64 (poly64x1_t __a) - { -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv2di (__a); -+ return (poly16x4_t)__builtin_neon_vreinterpretv4hidi (__a); - } + (define_insn "ssadd3" + [(set (match_operand:QADDSUB 0 "s_register_operand" "=r") +@@ -48,15 +51,17 @@ + (match_operand:QADDSUB 2 "s_register_operand" "r")))] + "TARGET_INT_SIMD" + "qadd%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_f32 (float32x4_t __a) -+#endif -+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_p16_s64 (int64x1_t __a) - { -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv4sf (__a); -+ return (poly16x4_t)__builtin_neon_vreinterpretv4hidi (__a); - } + (define_insn "sub3" +- [(set (match_operand:FIXED 0 "s_register_operand" "=r") +- (minus:FIXED (match_operand:FIXED 1 "s_register_operand" "r") +- (match_operand:FIXED 2 "s_register_operand" "r")))] ++ [(set (match_operand:FIXED 0 "s_register_operand" "=l,r") ++ (minus:FIXED (match_operand:FIXED 1 "s_register_operand" "l,r") ++ (match_operand:FIXED 2 "s_register_operand" "l,r")))] + "TARGET_32BIT" + "sub%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "yes,no")]) --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_u8 (uint8x16_t __a) -+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_p16_u64 (uint64x1_t __a) - { -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); -+ return (poly16x4_t)__builtin_neon_vreinterpretv4hidi ((int64x1_t) __a); - } + (define_insn "sub3" + [(set (match_operand:ADDSUB 0 "s_register_operand" "=r") +@@ -64,7 +69,8 @@ + (match_operand:ADDSUB 2 "s_register_operand" "r")))] + "TARGET_INT_SIMD" + "ssub%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_u16 (uint16x8_t __a) --{ -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); --} -- --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_u32 (uint32x4_t __a) --{ -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv4si ((int32x4_t) __a); --} -- --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_u64 (uint64x2_t __a) --{ -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); --} -- --__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_p8_p16 (poly16x8_t __a) --{ -- return (poly8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); --} -- - __extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) - vreinterpret_p16_s8 (int8x8_t __a) - { -@@ -11154,18 +11504,6 @@ - } + (define_insn "ussub3" + [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r") +@@ -73,7 +79,8 @@ + (match_operand:UQADDSUB 2 "s_register_operand" "r")))] + "TARGET_INT_SIMD" + "uqsub%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) - __extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) --vreinterpret_p16_s64 (int64x1_t __a) --{ -- return (poly16x4_t)__builtin_neon_vreinterpretv4hidi (__a); --} -- --__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) --vreinterpret_p16_f32 (float32x2_t __a) --{ -- return (poly16x4_t)__builtin_neon_vreinterpretv4hiv2sf (__a); --} -- --__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) - vreinterpret_p16_u8 (uint8x8_t __a) - { - return (poly16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); -@@ -11183,78 +11521,38 @@ - return (poly16x4_t)__builtin_neon_vreinterpretv4hiv2si ((int32x2_t) __a); - } + (define_insn "sssub3" + [(set (match_operand:QADDSUB 0 "s_register_operand" "=r") +@@ -81,7 +88,8 @@ + (match_operand:QADDSUB 2 "s_register_operand" "r")))] + "TARGET_INT_SIMD" + "qsub%?\\t%0, %1, %2" +- [(set_attr "predicable" "yes")]) ++ [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) --vreinterpret_p16_u64 (uint64x1_t __a) -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_f32_p8 (poly8x8_t __a) - { -- return (poly16x4_t)__builtin_neon_vreinterpretv4hidi ((int64x1_t) __a); -+ return (float32x2_t)__builtin_neon_vreinterpretv2sfv8qi ((int8x8_t) __a); - } + ;; Fractional multiplies. --__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) --vreinterpret_p16_p8 (poly8x8_t __a) -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_f32_p16 (poly16x4_t __a) - { -- return (poly16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); -+ return (float32x2_t)__builtin_neon_vreinterpretv2sfv4hi ((int16x4_t) __a); - } +@@ -96,7 +104,7 @@ + rtx tmp1 = gen_reg_rtx (HImode); + rtx tmp2 = gen_reg_rtx (HImode); + rtx tmp3 = gen_reg_rtx (SImode); +- ++ + emit_insn (gen_extendqihi2 (tmp1, gen_lowpart (QImode, operands[1]))); + emit_insn (gen_extendqihi2 (tmp2, gen_lowpart (QImode, operands[2]))); + emit_insn (gen_mulhisi3 (tmp3, tmp1, tmp2)); +@@ -132,7 +140,7 @@ + rtx tmp1 = gen_reg_rtx (DImode); + rtx tmp2 = gen_reg_rtx (SImode); + rtx tmp3 = gen_reg_rtx (SImode); +- ++ + /* s.31 * s.31 -> s.62 multiplication. */ + emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))); +@@ -154,7 +162,7 @@ + rtx tmp1 = gen_reg_rtx (DImode); + rtx tmp2 = gen_reg_rtx (SImode); + rtx tmp3 = gen_reg_rtx (SImode); +- ++ + emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))); + emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (15))); +@@ -173,13 +181,13 @@ + rtx tmp1 = gen_reg_rtx (DImode); + rtx tmp2 = gen_reg_rtx (SImode); + rtx tmp3 = gen_reg_rtx (SImode); +- ++ + emit_insn (gen_umulsidi3 (tmp1, gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))); + emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (16))); + emit_insn (gen_ashlsi3 (tmp3, gen_highpart (SImode, tmp1), GEN_INT (16))); + emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3)); +- ++ + DONE; + }) --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_s8 (int8x16_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_f32_p64 (poly64x1_t __a) - { -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv16qi (__a); -+ return (float32x2_t)__builtin_neon_vreinterpretv2sfdi (__a); - } +@@ -209,7 +217,7 @@ + } --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_s16 (int16x8_t __a) -+#endif -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_f32_s64 (int64x1_t __a) - { -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv8hi (__a); -+ return (float32x2_t)__builtin_neon_vreinterpretv2sfdi (__a); - } + /* We have: +- 31 high word 0 31 low word 0 ++ 31 high word 0 31 low word 0 --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_s32 (int32x4_t __a) -+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_f32_u64 (uint64x1_t __a) - { -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv4si (__a); -+ return (float32x2_t)__builtin_neon_vreinterpretv2sfdi ((int64x1_t) __a); - } + [ S i i .... i i i ] [ i f f f ... f f ] + | +@@ -221,9 +229,18 @@ + output_asm_insn ("ssat\\t%R3, #15, %R3", operands); + output_asm_insn ("mrs\\t%4, APSR", operands); + output_asm_insn ("tst\\t%4, #1<<27", operands); +- if (TARGET_THUMB2) +- output_asm_insn ("it\\tne", operands); +- output_asm_insn ("mvnne\\t%Q3, %R3, asr #32", operands); ++ if (arm_restrict_it) ++ { ++ output_asm_insn ("mvn\\t%4, %R3, asr #32", operands); ++ output_asm_insn ("it\\tne", operands); ++ output_asm_insn ("movne\\t%Q3, %4", operands); ++ } ++ else ++ { ++ if (TARGET_THUMB2) ++ output_asm_insn ("it\\tne", operands); ++ output_asm_insn ("mvnne\\t%Q3, %R3, asr #32", operands); ++ } + output_asm_insn ("mov\\t%0, %Q3, lsr #15", operands); + output_asm_insn ("orr\\t%0, %0, %R3, asl #17", operands); + return ""; +@@ -231,7 +248,9 @@ + [(set_attr "conds" "clob") + (set (attr "length") + (if_then_else (eq_attr "is_thumb" "yes") +- (const_int 38) ++ (if_then_else (match_test "arm_restrict_it") ++ (const_int 40) ++ (const_int 38)) + (const_int 32)))]) --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_s64 (int64x2_t __a) --{ -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv2di (__a); --} -- --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_f32 (float32x4_t __a) --{ -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv4sf (__a); --} -- --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_u8 (uint8x16_t __a) --{ -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); --} -- --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_u16 (uint16x8_t __a) --{ -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); --} -- --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_u32 (uint32x4_t __a) --{ -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv4si ((int32x4_t) __a); --} -- --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_u64 (uint64x2_t __a) --{ -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); --} -- --__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_p16_p8 (poly8x16_t __a) --{ -- return (poly16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); --} -- - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) - vreinterpret_f32_s8 (int8x8_t __a) - { -@@ -11274,12 +11572,6 @@ - } + ;; Same goes for this. +@@ -257,7 +276,7 @@ + } - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vreinterpret_f32_s64 (int64x1_t __a) --{ -- return (float32x2_t)__builtin_neon_vreinterpretv2sfdi (__a); --} -- --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) - vreinterpret_f32_u8 (uint8x8_t __a) - { - return (float32x2_t)__builtin_neon_vreinterpretv2sfv8qi ((int8x8_t) __a); -@@ -11297,85 +11589,127 @@ - return (float32x2_t)__builtin_neon_vreinterpretv2sfv2si ((int32x2_t) __a); - } + /* We have: +- 31 high word 0 31 low word 0 ++ 31 high word 0 31 low word 0 --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vreinterpret_f32_u64 (uint64x1_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_p8 (poly8x8_t __a) - { -- return (float32x2_t)__builtin_neon_vreinterpretv2sfdi ((int64x1_t) __a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); - } + [ i i i .... i i i ] [ f f f f ... f f ] + | +@@ -269,9 +288,18 @@ + output_asm_insn ("usat\\t%R3, #16, %R3", operands); + output_asm_insn ("mrs\\t%4, APSR", operands); + output_asm_insn ("tst\\t%4, #1<<27", operands); +- if (TARGET_THUMB2) +- output_asm_insn ("it\\tne", operands); +- output_asm_insn ("sbfxne\\t%Q3, %R3, #15, #1", operands); ++ if (arm_restrict_it) ++ { ++ output_asm_insn ("sbfx\\t%4, %R3, #15, #1", operands); ++ output_asm_insn ("it\\tne", operands); ++ output_asm_insn ("movne\\t%Q3, %4", operands); ++ } ++ else ++ { ++ if (TARGET_THUMB2) ++ output_asm_insn ("it\\tne", operands); ++ output_asm_insn ("sbfxne\\t%Q3, %R3, #15, #1", operands); ++ } + output_asm_insn ("lsr\\t%0, %Q3, #16", operands); + output_asm_insn ("orr\\t%0, %0, %R3, asl #16", operands); + return ""; +@@ -279,7 +307,9 @@ + [(set_attr "conds" "clob") + (set (attr "length") + (if_then_else (eq_attr "is_thumb" "yes") +- (const_int 38) ++ (if_then_else (match_test "arm_restrict_it") ++ (const_int 40) ++ (const_int 38)) + (const_int 32)))]) --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vreinterpret_f32_p8 (poly8x8_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_p16 (poly16x4_t __a) + (define_expand "mulha3" +@@ -289,7 +319,7 @@ + "TARGET_DSP_MULTIPLY && arm_arch_thumb2" { -- return (float32x2_t)__builtin_neon_vreinterpretv2sfv8qi ((int8x8_t) __a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); - } - --__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) --vreinterpret_f32_p16 (poly16x4_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_f32 (float32x2_t __a) + rtx tmp = gen_reg_rtx (SImode); +- ++ + emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]), + gen_lowpart (HImode, operands[2]))); + emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp, GEN_INT (16), +@@ -307,7 +337,7 @@ + rtx tmp1 = gen_reg_rtx (SImode); + rtx tmp2 = gen_reg_rtx (SImode); + rtx tmp3 = gen_reg_rtx (SImode); +- ++ + /* 8.8 * 8.8 -> 16.16 multiply. */ + emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1]))); + emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2]))); +@@ -326,7 +356,7 @@ { -- return (float32x2_t)__builtin_neon_vreinterpretv2sfv4hi ((int16x4_t) __a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv2sf (__a); - } + rtx tmp = gen_reg_rtx (SImode); + rtx rshift; +- ++ + emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]), + gen_lowpart (HImode, operands[2]))); --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_s8 (int8x16_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_s64 (int64x1_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv16qi (__a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdidi (__a); - } +@@ -348,12 +378,12 @@ + rtx tmp2 = gen_reg_rtx (SImode); + rtx tmp3 = gen_reg_rtx (SImode); + rtx rshift_tmp = gen_reg_rtx (SImode); +- ++ + /* Note: there's no smul[bt][bt] equivalent for unsigned multiplies. Use a + normal 32x32->32-bit multiply instead. */ + emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1]))); + emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2]))); +- ++ + emit_insn (gen_mulsi3 (tmp3, tmp1, tmp2)); --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_s16 (int16x8_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_u64 (uint64x1_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv8hi (__a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdidi ((int64x1_t) __a); - } + /* The operand to "usat" is signed, so we cannot use the "..., asr #8" +@@ -374,9 +404,9 @@ + "TARGET_32BIT && arm_arch6" + "ssat%?\\t%0, #16, %2%S1" + [(set_attr "predicable" "yes") +- (set_attr "insn" "sat") ++ (set_attr "predicable_short_it" "no") + (set_attr "shift" "1") +- (set_attr "type" "alu_shift")]) ++ (set_attr "type" "arlo_shift")]) --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_s32 (int32x4_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_s8 (int8x8_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv4si (__a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv8qi (__a); - } + (define_insn "arm_usatsihi" + [(set (match_operand:HI 0 "s_register_operand" "=r") +@@ -384,4 +414,5 @@ + "TARGET_INT_SIMD" + "usat%?\\t%0, #16, %1" + [(set_attr "predicable" "yes") +- (set_attr "insn" "sat")]) ++ (set_attr "predicable_short_it" "no")] ++) +--- a/src/gcc/config/arm/unspecs.md ++++ b/src/gcc/config/arm/unspecs.md +@@ -139,6 +139,10 @@ + VUNSPEC_ATOMIC_OP ; Represent an atomic operation. + VUNSPEC_LL ; Represent a load-register-exclusive. + VUNSPEC_SC ; Represent a store-register-exclusive. ++ VUNSPEC_LAX ; Represent a load-register-acquire-exclusive. ++ VUNSPEC_SLX ; Represent a store-register-release-exclusive. ++ VUNSPEC_LDA ; Represent a store-register-acquire. ++ VUNSPEC_STL ; Represent a store-register-release. + ]) --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_s64 (int64x2_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_s16 (int16x4_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv2di (__a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv4hi (__a); - } + ;; Enumerators for NEON unspecs. +--- a/src/gcc/config/arm/cortex-m4.md ++++ b/src/gcc/config/arm/cortex-m4.md +@@ -31,7 +31,12 @@ + ;; ALU and multiply is one cycle. + (define_insn_reservation "cortex_m4_alu" 1 + (and (eq_attr "tune" "cortexm4") +- (eq_attr "type" "alu_reg,simple_alu_imm,simple_alu_shift,alu_shift,alu_shift_reg,mult")) ++ (ior (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,\ ++ arlo_shift,arlo_shift_reg,\ ++ mov_imm,mov_reg,mov_shift,mov_shift_reg,\ ++ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg") ++ (ior (eq_attr "mul32" "yes") ++ (eq_attr "mul64" "yes")))) + "cortex_m4_ex") --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_u8 (uint8x16_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_s32 (int32x2_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv16qi ((int8x16_t) __a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv2si (__a); - } + ;; Byte, half-word and word load is two cycles. +--- a/src/gcc/config/arm/linux-eabi.h ++++ b/src/gcc/config/arm/linux-eabi.h +@@ -84,10 +84,14 @@ + LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ + LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_u16 (uint16x8_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_u8 (uint8x8_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv8hi ((int16x8_t) __a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); - } ++#undef ASAN_CC1_SPEC ++#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}" ++ + #undef CC1_SPEC + #define CC1_SPEC \ +- LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ +- GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) ++ LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ ++ GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ ++ ANDROID_CC1_SPEC) --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_u32 (uint32x4_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_u16 (uint16x4_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv4si ((int32x4_t) __a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); - } + #define CC1PLUS_SPEC \ + LINUX_OR_ANDROID_CC ("", ANDROID_CC1PLUS_SPEC) +@@ -95,7 +99,7 @@ + #undef LIB_SPEC + #define LIB_SPEC \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \ +- GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC) ++ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC " " ANDROID_LIB_SPEC) --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_u64 (uint64x2_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_p64_u32 (uint32x2_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv2di ((int64x2_t) __a); -+ return (poly64x1_t)__builtin_neon_vreinterpretdiv2si ((int32x2_t) __a); - } + #undef STARTFILE_SPEC + #define STARTFILE_SPEC \ +--- a/src/gcc/config/arm/arm-cores.def ++++ b/src/gcc/config/arm/arm-cores.def +@@ -129,9 +129,11 @@ + ARM_CORE("cortex-a8", cortexa8, 7A, FL_LDSCHED, cortex) + ARM_CORE("cortex-a9", cortexa9, 7A, FL_LDSCHED, cortex_a9) + ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15) ++ARM_CORE("cortex-a53", cortexa53, 8A, FL_LDSCHED, cortex_a5) + ARM_CORE("cortex-r4", cortexr4, 7R, FL_LDSCHED, cortex) + ARM_CORE("cortex-r4f", cortexr4f, 7R, FL_LDSCHED, cortex) + ARM_CORE("cortex-r5", cortexr5, 7R, FL_LDSCHED | FL_ARM_DIV, cortex) ++ARM_CORE("cortex-r7", cortexr7, 7R, FL_LDSCHED | FL_ARM_DIV, cortex) + ARM_CORE("cortex-m4", cortexm4, 7EM, FL_LDSCHED, cortex) + ARM_CORE("cortex-m3", cortexm3, 7M, FL_LDSCHED, cortex) + ARM_CORE("cortex-m1", cortexm1, 6M, FL_LDSCHED, v6m) +--- a/src/gcc/config/arm/cortex-r4.md ++++ b/src/gcc/config/arm/cortex-r4.md +@@ -78,24 +78,22 @@ + ;; for the purposes of the dual-issue constraints above. + (define_insn_reservation "cortex_r4_alu" 2 + (and (eq_attr "tune_cortexr4" "yes") +- (and (eq_attr "type" "alu_reg,simple_alu_imm") +- (not (eq_attr "insn" "mov")))) ++ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,mvn_imm,mvn_reg")) + "cortex_r4_alu") --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_p8 (poly8x16_t __a) -+#endif -+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_s64_p8 (poly8x8_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv16qi ((int8x16_t) __a); -+ return (int64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); - } + (define_insn_reservation "cortex_r4_mov" 2 + (and (eq_attr "tune_cortexr4" "yes") +- (and (eq_attr "type" "alu_reg,simple_alu_imm") +- (eq_attr "insn" "mov"))) ++ (eq_attr "type" "mov_imm,mov_reg")) + "cortex_r4_mov") --__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_f32_p16 (poly16x8_t __a) -+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_s64_p16 (poly16x4_t __a) - { -- return (float32x4_t)__builtin_neon_vreinterpretv4sfv8hi ((int16x8_t) __a); -+ return (int64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); - } + (define_insn_reservation "cortex_r4_alu_shift" 2 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "type" "simple_alu_shift,alu_shift")) ++ (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + "cortex_r4_alu") - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_s64_f32 (float32x2_t __a) -+{ -+ return (int64x1_t)__builtin_neon_vreinterpretdiv2sf (__a); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_s64_p64 (poly64x1_t __a) -+{ -+ return (int64x1_t)__builtin_neon_vreinterpretdidi (__a); -+} -+ -+#endif -+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_s64_u64 (uint64x1_t __a) -+{ -+ return (int64x1_t)__builtin_neon_vreinterpretdidi ((int64x1_t) __a); -+} -+ -+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vreinterpret_s64_s8 (int8x8_t __a) - { - return (int64x1_t)__builtin_neon_vreinterpretdiv8qi (__a); -@@ -11394,12 +11728,6 @@ - } + (define_insn_reservation "cortex_r4_alu_shift_reg" 2 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "type" "alu_shift_reg")) ++ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + "cortex_r4_alu_shift_reg") - __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) --vreinterpret_s64_f32 (float32x2_t __a) --{ -- return (int64x1_t)__builtin_neon_vreinterpretdiv2sf (__a); --} -- --__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) - vreinterpret_s64_u8 (uint8x8_t __a) - { - return (int64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); -@@ -11417,552 +11745,1206 @@ - return (int64x1_t)__builtin_neon_vreinterpretdiv2si ((int32x2_t) __a); - } + ;; An ALU instruction followed by an ALU instruction with no early dep. +@@ -128,32 +126,32 @@ --__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) --vreinterpret_s64_u64 (uint64x1_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_p8 (poly8x8_t __a) - { -- return (int64x1_t)__builtin_neon_vreinterpretdidi ((int64x1_t) __a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); - } + (define_insn_reservation "cortex_r4_mul_4" 4 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "mul,smmul")) ++ (eq_attr "type" "mul,smmul")) + "cortex_r4_mul_2") --__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) --vreinterpret_s64_p8 (poly8x8_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_p16 (poly16x4_t __a) - { -- return (int64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); - } + (define_insn_reservation "cortex_r4_mul_3" 3 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "smulxy,smulwy,smuad,smusd")) ++ (eq_attr "type" "smulxy,smulwy,smuad,smusd")) + "cortex_r4_mul") --__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) --vreinterpret_s64_p16 (poly16x4_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_f32 (float32x2_t __a) - { -- return (int64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv2sf (__a); - } + (define_insn_reservation "cortex_r4_mla_4" 4 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "mla,smmla")) ++ (eq_attr "type" "mla,smmla")) + "cortex_r4_mul_2") --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_s8 (int8x16_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_p64 (poly64x1_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div16qi (__a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdidi (__a); - } + (define_insn_reservation "cortex_r4_mla_3" 3 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "smlaxy,smlawy,smlad,smlsd")) ++ (eq_attr "type" "smlaxy,smlawy,smlad,smlsd")) + "cortex_r4_mul") --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_s16 (int16x8_t __a) -+#endif -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_s64 (int64x1_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div8hi (__a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdidi (__a); - } + (define_insn_reservation "cortex_r4_smlald" 3 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "smlald,smlsld")) ++ (eq_attr "type" "smlald,smlsld")) + "cortex_r4_mul") --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_s32 (int32x4_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_s8 (int8x8_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div4si (__a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv8qi (__a); - } + (define_insn_reservation "cortex_r4_mull" 4 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "smull,umull,umlal,umaal")) ++ (eq_attr "type" "smull,umull,umlal,umaal")) + "cortex_r4_mul_2") --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_f32 (float32x4_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_s16 (int16x4_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div4sf (__a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv4hi (__a); - } + ;; A multiply or an MLA with a single-register result, followed by an +@@ -196,12 +194,12 @@ + ;; This gives a latency of nine for udiv and ten for sdiv. + (define_insn_reservation "cortex_r4_udiv" 9 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "udiv")) ++ (eq_attr "type" "udiv")) + "cortex_r4_div_9") --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_u8 (uint8x16_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_s32 (int32x2_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv2si (__a); - } + (define_insn_reservation "cortex_r4_sdiv" 10 + (and (eq_attr "tune_cortexr4" "yes") +- (eq_attr "insn" "sdiv")) ++ (eq_attr "type" "sdiv")) + "cortex_r4_div_10") --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_u16 (uint16x8_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_u8 (uint8x8_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); - } + ;; Branches. We assume correct prediction. +--- a/src/gcc/config/arm/arm-tune.md ++++ b/src/gcc/config/arm/arm-tune.md +@@ -1,5 +1,5 @@ + ;; -*- buffer-read-only: t -*- + ;; Generated automatically by gentune.sh from arm-cores.def + (define_attr "tune" +- "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,fa526,fa626,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,genericv7a,cortexa5,cortexa7,cortexa8,cortexa9,cortexa15,cortexr4,cortexr4f,cortexr5,cortexm4,cortexm3,cortexm1,cortexm0,cortexm0plus,marvell_pj4" ++ "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,fa526,fa626,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,genericv7a,cortexa5,cortexa7,cortexa8,cortexa9,cortexa15,cortexa53,cortexr4,cortexr4f,cortexr5,cortexr7,cortexm4,cortexm3,cortexm1,cortexm0,cortexm0plus,marvell_pj4" + (const (symbol_ref "((enum attr_tune) arm_tune)"))) +--- a/src/gcc/config/arm/arm-protos.h ++++ b/src/gcc/config/arm/arm-protos.h +@@ -24,12 +24,13 @@ --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_u32 (uint32x4_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_u16 (uint16x4_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div4si ((int32x4_t) __a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); - } + extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *); + extern int use_return_insn (int, rtx); ++extern bool use_simple_return_p (void); + extern enum reg_class arm_regno_class (int); + extern void arm_load_pic_register (unsigned long); + extern int arm_volatile_func (void); + extern void arm_expand_prologue (void); + extern void arm_expand_epilogue (bool); +-extern void thumb2_expand_return (void); ++extern void thumb2_expand_return (bool); + extern const char *arm_strip_name_encoding (const char *); + extern void arm_asm_output_labelref (FILE *, const char *); + extern void thumb2_asm_output_opcode (FILE *); +@@ -78,6 +79,7 @@ + extern void neon_pairwise_reduce (rtx, rtx, enum machine_mode, + rtx (*) (rtx, rtx, rtx)); + extern rtx neon_make_constant (rtx); ++extern tree arm_builtin_vectorized_function (tree, tree, tree); + extern void neon_expand_vector_init (rtx, rtx); + extern void neon_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT); + extern void neon_const_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT); +@@ -117,7 +119,9 @@ + extern rtx arm_gen_store_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *); + extern bool offset_ok_for_ldrd_strd (HOST_WIDE_INT); + extern bool operands_ok_ldrd_strd (rtx, rtx, rtx, HOST_WIDE_INT, bool, bool); ++extern bool gen_operands_ldrd_strd (rtx *, bool, bool, bool); + extern int arm_gen_movmemqi (rtx *); ++extern bool gen_movmem_ldrd_strd (rtx *); + extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx); + extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx, + HOST_WIDE_INT); +@@ -224,6 +228,8 @@ --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_u64 (uint64x2_t __a) -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vreinterpret_u64_u32 (uint32x2_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div2di ((int64x2_t) __a); -+ return (uint64x1_t)__builtin_neon_vreinterpretdiv2si ((int32x2_t) __a); - } + extern void arm_order_regs_for_local_alloc (void); --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_p8 (poly8x16_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_p8 (poly8x8_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); - } ++extern int arm_max_conditional_execute (); ++ + /* Vectorizer cost model implementation. */ + struct cpu_vec_costs { + const int scalar_stmt_cost; /* Cost of any scalar operation, excluding +@@ -253,8 +259,7 @@ + bool (*rtx_costs) (rtx, RTX_CODE, RTX_CODE, int *, bool); + bool (*sched_adjust_cost) (rtx, rtx, rtx, int *); + int constant_limit; +- /* Maximum number of instructions to conditionalise in +- arm_final_prescan_insn. */ ++ /* Maximum number of instructions to conditionalise. */ + int max_insns_skipped; + int num_prefetch_slots; + int l1_cache_size; +@@ -269,6 +274,8 @@ + bool logical_op_non_short_circuit[2]; + /* Vectorizer costs. */ + const struct cpu_vec_costs* vec_costs; ++ /* Prefer Neon for 64-bit bitops. */ ++ bool prefer_neon_for_64bits; + }; --__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_s64_p16 (poly16x8_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_p16 (poly16x4_t __a) - { -- return (int64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); - } + extern const struct tune_params *current_tune; +--- a/src/gcc/config/arm/vfp.md ++++ b/src/gcc/config/arm/vfp.md +@@ -18,31 +18,6 @@ + ;; along with GCC; see the file COPYING3. If not see + ;; . */ --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_s8 (int8x8_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_f32 (float32x2_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv8qi (__a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv2sf (__a); - } +-;; The VFP "type" attributes differ from those used in the FPA model. +-;; fcpys Single precision cpy. +-;; ffariths Single precision abs, neg. +-;; ffarithd Double precision abs, neg, cpy. +-;; fadds Single precision add/sub. +-;; faddd Double precision add/sub. +-;; fconsts Single precision load immediate. +-;; fconstd Double precision load immediate. +-;; fcmps Single precision comparison. +-;; fcmpd Double precision comparison. +-;; fmuls Single precision multiply. +-;; fmuld Double precision multiply. +-;; fmacs Single precision multiply-accumulate. +-;; fmacd Double precision multiply-accumulate. +-;; ffmas Single precision fused multiply-accumulate. +-;; ffmad Double precision fused multiply-accumulate. +-;; fdivs Single precision sqrt or division. +-;; fdivd Double precision sqrt or division. +-;; f_flag fmstat operation +-;; f_load[sd] Floating point load from memory. +-;; f_store[sd] Floating point store to memory. +-;; f_2_r Transfer vfp to arm reg. +-;; r_2_f Transfer arm to vfp reg. +-;; f_cvt Convert floating<->integral +- + ;; SImode moves + ;; ??? For now do not allow loading constants into vfp regs. This causes + ;; problems because small constants get converted into adds. +@@ -78,62 +53,67 @@ + } + " + [(set_attr "predicable" "yes") +- (set_attr "type" "*,*,simple_alu_imm,simple_alu_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") ++ (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") + (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") +- (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*") + (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*") + (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")] + ) --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_s16 (int16x4_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_p64 (poly64x1_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv4hi (__a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qidi (__a); - } + ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split + ;; high/low register alternatives for loads and stores here. ++;; The l/Py alternative should come after r/I to ensure that the short variant ++;; is chosen with length 2 when the instruction is predicated for ++;; arm_restrict_it. + (define_insn "*thumb2_movsi_vfp" +- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") +- (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] ++ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") ++ (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] + "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT + && ( s_register_operand (operands[0], SImode) + || s_register_operand (operands[1], SImode))" + "* + switch (which_alternative) + { +- case 0: case 1: ++ case 0: ++ case 1: ++ case 2: + return \"mov%?\\t%0, %1\"; +- case 2: ++ case 3: + return \"mvn%?\\t%0, #%B1\"; +- case 3: ++ case 4: + return \"movw%?\\t%0, %1\"; +- case 4: + case 5: ++ case 6: + return \"ldr%?\\t%0, %1\"; +- case 6: + case 7: ++ case 8: + return \"str%?\\t%1, %0\"; +- case 8: ++ case 9: + return \"fmsr%?\\t%0, %1\\t%@ int\"; +- case 9: ++ case 10: + return \"fmrs%?\\t%0, %1\\t%@ int\"; +- case 10: ++ case 11: + return \"fcpys%?\\t%0, %1\\t%@ int\"; +- case 11: case 12: ++ case 12: case 13: + return output_move_vfp (operands); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") +- (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") +- (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") +- (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*") +- (set_attr "pool_range" "*,*,*,*,1018,4094,*,*,*,*,*,1018,*") +- (set_attr "neg_pool_range" "*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] ++ (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no") ++ (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_reg,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") ++ (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4") ++ (set_attr "neon_type" "*,*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") ++ (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*") ++ (set_attr "neg_pool_range" "*,*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] + ) --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_s32 (int32x2_t __a) -+#endif -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_s64 (int64x1_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv2si (__a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qidi (__a); - } --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_s64 (int64x1_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_u64 (uint64x1_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdidi (__a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qidi ((int64x1_t) __a); - } + ;; DImode moves --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_f32 (float32x2_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_s16 (int16x4_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv2sf (__a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv4hi (__a); - } + (define_insn "*movdi_vfp" +- [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,r,w,w, Uv") +- (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))] ++ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,r,w,w, Uv") ++ (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,q,r,w,w,Uvi,w"))] + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune != cortexa8 + && ( register_operand (operands[0], DImode) + || register_operand (operands[1], DImode)) +@@ -375,9 +355,8 @@ + " + [(set_attr "predicable" "yes") + (set_attr "type" +- "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") ++ "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg") + (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") +- (set_attr "insn" "*,*,*,*,*,*,*,*,mov") + (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*") + (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")] + ) +@@ -412,15 +391,14 @@ + } + " + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" +- "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") ++ "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg") + (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") +- (set_attr "insn" "*,*,*,*,*,*,*,*,mov") + (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*") + (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] + ) --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_u8 (uint8x8_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_s32 (int32x2_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv2si (__a); - } +- + ;; DFmode moves --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_u16 (uint16x4_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_u8 (uint8x8_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); - } + (define_insn "*movdf_vfp" +@@ -550,7 +528,7 @@ + [(match_operand 4 "cc_register" "") (const_int 0)]) + (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") + (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] +- "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP" ++ "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP && !arm_restrict_it" + "@ + it\\t%D3\;fcpys%D3\\t%0, %2 + it\\t%d3\;fcpys%d3\\t%0, %1 +@@ -598,7 +576,7 @@ + [(match_operand 4 "cc_register" "") (const_int 0)]) + (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") + (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] +- "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" ++ "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && !arm_restrict_it" + "@ + it\\t%D3\;fcpyd%D3\\t%P0, %P2 + it\\t%d3\;fcpyd%d3\\t%P0, %P1 +@@ -624,6 +602,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fabss%?\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "ffariths")] + ) --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_u32 (uint32x2_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_u16 (uint16x4_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv2si ((int32x2_t) __a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); - } +@@ -633,6 +612,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fabsd%?\\t%P0, %P1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "ffarithd")] + ) --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_p8 (poly8x8_t __a) -+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_s8_u32 (uint32x2_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv8qi ((int8x8_t) __a); -+ return (int8x8_t)__builtin_neon_vreinterpretv8qiv2si ((int32x2_t) __a); - } +@@ -644,6 +624,7 @@ + fnegs%?\\t%0, %1 + eor%?\\t%0, %1, #-2147483648" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "ffariths")] + ) --__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) --vreinterpret_u64_p16 (poly16x4_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_p8 (poly8x8_t __a) - { -- return (uint64x1_t)__builtin_neon_vreinterpretdiv4hi ((int16x4_t) __a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); - } +@@ -689,6 +670,7 @@ + } + " + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "length" "4,4,8") + (set_attr "type" "ffarithd")] + ) +@@ -703,6 +685,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fadds%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fadds")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_s8 (int8x16_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_p16 (poly16x4_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div16qi (__a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv4hi ((int16x4_t) __a); - } +@@ -713,6 +696,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "faddd%?\\t%P0, %P1, %P2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "faddd")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_s16 (int16x8_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_f32 (float32x2_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div8hi (__a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv2sf (__a); - } +@@ -724,6 +708,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fsubs%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fadds")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_s32 (int32x4_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_p64 (poly64x1_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div4si (__a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hidi (__a); - } +@@ -734,6 +719,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fsubd%?\\t%P0, %P1, %P2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "faddd")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_s64 (int64x2_t __a) -+#endif -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_s64 (int64x1_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div2di (__a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hidi (__a); - } +@@ -747,6 +733,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fdivs%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fdivs")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_f32 (float32x4_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_u64 (uint64x1_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div4sf (__a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hidi ((int64x1_t) __a); - } +@@ -757,6 +744,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fdivd%?\\t%P0, %P1, %P2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fdivd")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_u8 (uint8x16_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_s8 (int8x8_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv8qi (__a); - } +@@ -770,6 +758,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fmuls%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmuls")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_u16 (uint16x8_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_s32 (int32x2_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv2si (__a); - } +@@ -780,6 +769,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fmuld%?\\t%P0, %P1, %P2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmuld")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_u32 (uint32x4_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_u8 (uint8x8_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div4si ((int32x4_t) __a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); - } +@@ -790,6 +780,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fnmuls%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmuls")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_p8 (poly8x16_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_u16 (uint16x4_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv4hi ((int16x4_t) __a); - } +@@ -800,6 +791,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fnmuld%?\\t%P0, %P1, %P2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmuld")] + ) --__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) --vreinterpretq_u64_p16 (poly16x8_t __a) -+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_s16_u32 (uint32x2_t __a) - { -- return (uint64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+ return (int16x4_t)__builtin_neon_vreinterpretv4hiv2si ((int32x2_t) __a); - } +@@ -815,6 +807,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fmacs%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacs")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_s16 (int16x4_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_p8 (poly8x8_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv4hi (__a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); - } +@@ -826,6 +819,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fmacd%?\\t%P0, %P2, %P3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacd")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_s32 (int32x2_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_p16 (poly16x4_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv2si (__a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); - } +@@ -838,6 +832,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fmscs%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacs")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_s64 (int64x1_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_f32 (float32x2_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qidi (__a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv2sf (__a); - } +@@ -849,6 +844,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fmscd%?\\t%P0, %P2, %P3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacd")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_f32 (float32x2_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_p64 (poly64x1_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv2sf (__a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2sidi (__a); - } +@@ -861,6 +857,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fnmacs%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacs")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_u8 (uint8x8_t __a) -+#endif -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_s64 (int64x1_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2sidi (__a); - } +@@ -872,6 +869,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fnmacd%?\\t%P0, %P2, %P3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacd")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_u16 (uint16x4_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_u64 (uint64x1_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2sidi ((int64x1_t) __a); - } +@@ -886,6 +884,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fnmscs%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacs")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_u32 (uint32x2_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_s8 (int8x8_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv2si ((int32x2_t) __a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv8qi (__a); - } +@@ -898,6 +897,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fnmscd%?\\t%P0, %P2, %P3" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fmacd")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_u64 (uint64x1_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_s16 (int16x4_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qidi ((int64x1_t) __a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv4hi (__a); - } +@@ -911,6 +911,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" + "vfma%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "ffma")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_p8 (poly8x8_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_u8 (uint8x8_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); - } +@@ -923,6 +924,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" + "vfms%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "ffma")] + ) --__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) --vreinterpret_s8_p16 (poly16x4_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_u16 (uint16x4_t __a) - { -- return (int8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); - } +@@ -934,6 +936,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" + "vfnms%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "ffma")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_s16 (int16x8_t __a) -+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_s32_u32 (uint32x2_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv8hi (__a); -+ return (int32x2_t)__builtin_neon_vreinterpretv2siv2si ((int32x2_t) __a); - } +@@ -946,6 +949,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" + "vfnma%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "ffma")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_s32 (int32x4_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_p8 (poly8x8_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv4si (__a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); - } +@@ -958,6 +962,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fcvtds%?\\t%P0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_s64 (int64x2_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_p16 (poly16x4_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv2di (__a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); - } +@@ -967,6 +972,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fcvtsd%?\\t%0, %P1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_f32 (float32x4_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_f32 (float32x2_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv4sf (__a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv2sf (__a); - } +@@ -976,6 +982,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" + "vcvtb%?.f32.f16\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_u8 (uint8x16_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_p64 (poly64x1_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qidi (__a); - } +@@ -985,6 +992,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" + "vcvtb%?.f16.f32\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_u16 (uint16x8_t __a) -+#endif -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_s64 (int64x1_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qidi (__a); - } +@@ -994,6 +1002,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "ftosizs%?\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_u32 (uint32x4_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_u64 (uint64x1_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv4si ((int32x4_t) __a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qidi ((int64x1_t) __a); - } +@@ -1003,6 +1012,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "ftosizd%?\\t%0, %P1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_u64 (uint64x2_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_s8 (int8x8_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv8qi (__a); - } +@@ -1013,6 +1023,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "ftouizs%?\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_p8 (poly8x16_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_s16 (int16x4_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv4hi (__a); - } +@@ -1022,6 +1033,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "ftouizd%?\\t%0, %P1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_s8_p16 (poly16x8_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_s32 (int32x2_t __a) - { -- return (int8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv2si (__a); - } +@@ -1032,6 +1044,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fsitos%?\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_s8 (int8x8_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_u16 (uint16x4_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv8qi (__a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); - } +@@ -1041,6 +1054,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fsitod%?\\t%P0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_s32 (int32x2_t __a) -+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -+vreinterpret_u8_u32 (uint32x2_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv2si (__a); -+ return (uint8x8_t)__builtin_neon_vreinterpretv8qiv2si ((int32x2_t) __a); - } +@@ -1051,6 +1065,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fuitos%?\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_s64 (int64x1_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_p8 (poly8x8_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hidi (__a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); - } +@@ -1060,6 +1075,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fuitod%?\\t%P0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvt")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_f32 (float32x2_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_p16 (poly16x4_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv2sf (__a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv4hi ((int16x4_t) __a); - } +@@ -1072,6 +1088,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "fsqrts%?\\t%0, %1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fdivs")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_u8 (uint8x8_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_f32 (float32x2_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv2sf (__a); - } +@@ -1081,6 +1098,7 @@ + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" + "fsqrtd%?\\t%P0, %P1" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fdivd")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_u16 (uint16x4_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_p64 (poly64x1_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv4hi ((int16x4_t) __a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hidi (__a); - } +@@ -1168,6 +1186,7 @@ + fcmps%?\\t%0, %1 + fcmpzs%?\\t%0" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fcmps")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_u32 (uint32x2_t __a) -+#endif -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_s64 (int64x1_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv2si ((int32x2_t) __a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hidi (__a); - } +@@ -1180,6 +1199,7 @@ + fcmpes%?\\t%0, %1 + fcmpezs%?\\t%0" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fcmps")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_u64 (uint64x1_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_u64 (uint64x1_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hidi ((int64x1_t) __a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hidi ((int64x1_t) __a); - } +@@ -1192,6 +1212,7 @@ + fcmpd%?\\t%P0, %P1 + fcmpzd%?\\t%P0" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fcmpd")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_p8 (poly8x8_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_s8 (int8x8_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv8qi (__a); - } +@@ -1204,6 +1225,7 @@ + fcmped%?\\t%P0, %P1 + fcmpezd%?\\t%P0" + [(set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no") + (set_attr "type" "fcmpd")] + ) --__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) --vreinterpret_s16_p16 (poly16x4_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_s16 (int16x4_t __a) - { -- return (int16x4_t)__builtin_neon_vreinterpretv4hiv4hi ((int16x4_t) __a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv4hi (__a); - } +@@ -1264,6 +1264,7 @@ + "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 " + "vrint%?.\\t%0, %1" + [(set_attr "predicable" "") ++ (set_attr "predicable_short_it" "no") + (set_attr "conds" "") + (set_attr "type" "f_rint")] + ) +--- a/src/gcc/config/arm/t-linux-eabi ++++ b/src/gcc/config/arm/t-linux-eabi +@@ -18,6 +18,8 @@ --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_s8 (int8x16_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_s32 (int32x2_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv16qi (__a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv2si (__a); - } + # We do not build a Thumb multilib for Linux because the definition of + # CLEAR_INSN_CACHE in linux-gas.h does not work in Thumb mode. ++# If you set MULTILIB_OPTIONS to a non-empty value you should also set ++# MULTILIB_DEFAULTS in linux-elf.h. + MULTILIB_OPTIONS = + MULTILIB_DIRNAMES = --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_s32 (int32x4_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_u8 (uint8x8_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv4si (__a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); +--- a/src/gcc/config/arm/neon.md ++++ b/src/gcc/config/arm/neon.md +@@ -61,8 +61,7 @@ + } } - --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_s64 (int64x2_t __a) -+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -+vreinterpret_u16_u32 (uint32x2_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv2di (__a); -+ return (uint16x4_t)__builtin_neon_vreinterpretv4hiv2si ((int32x2_t) __a); + [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*") +- (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu_reg,load2,store2") +- (set_attr "insn" "*,*,*,*,*,*,mov,*,*") ++ (set_attr "type" "*,f_stored,*,f_loadd,*,*,mov_reg,load2,store2") + (set_attr "length" "4,4,4,4,4,4,8,8,8") + (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*") + (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") +@@ -107,8 +106,7 @@ } + [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\ + neon_mrrc,neon_mcr_2_mcrr,*,*,*") +- (set_attr "type" "*,*,*,*,*,*,alu_reg,load4,store4") +- (set_attr "insn" "*,*,*,*,*,*,mov,*,*") ++ (set_attr "type" "*,*,*,*,*,*,mov_reg,load4,store4") + (set_attr "length" "4,8,4,8,8,8,16,8,16") + (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*") + (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") +@@ -487,7 +485,7 @@ + [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*") + (set_attr "conds" "*,clob,clob,*,clob,clob,clob") + (set_attr "length" "*,8,8,*,8,8,8") +- (set_attr "arch" "nota8,*,*,onlya8,*,*,*")] ++ (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits,*,*,*")] + ) --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_f32 (float32x4_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_p8 (poly8x8_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv4sf (__a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); - } + (define_insn "*sub3_neon" +@@ -524,7 +522,7 @@ + [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2") + (set_attr "conds" "*,clob,clob,clob,*") + (set_attr "length" "*,8,8,8,*") +- (set_attr "arch" "nota8,*,*,*,onlya8")] ++ (set_attr "arch" "neon_for_64bits,*,*,*,avoid_neon_for_64bits")] + ) --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_u8 (uint8x16_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_p16 (poly16x4_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); - } + (define_insn "*mul3_neon" +@@ -679,29 +677,6 @@ + [(set_attr "neon_type" "neon_int_1")] + ) --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_u16 (uint16x8_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_f32 (float32x2_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv2sf (__a); - } +-(define_insn "iordi3_neon" +- [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w") +- (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0") +- (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r,w,Dl")))] +- "TARGET_NEON" +-{ +- switch (which_alternative) +- { +- case 0: /* fall through */ +- case 4: return "vorr\t%P0, %P1, %P2"; +- case 1: /* fall through */ +- case 5: return neon_output_logic_immediate ("vorr", &operands[2], +- DImode, 0, VALID_NEON_QREG_MODE (DImode)); +- case 2: return "#"; +- case 3: return "#"; +- default: gcc_unreachable (); +- } +-} +- [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1") +- (set_attr "length" "*,*,8,8,*,*") +- (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")] +-) +- + ;; The concrete forms of the Neon immediate-logic instructions are vbic and + ;; vorr. We support the pseudo-instruction vand instead, because that + ;; corresponds to the canonical form the middle-end expects to use for +@@ -724,29 +699,6 @@ + [(set_attr "neon_type" "neon_int_1")] + ) --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_u32 (uint32x4_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_p64 (poly64x1_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv4si ((int32x4_t) __a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2sidi (__a); - } +-(define_insn "anddi3_neon" +- [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w") +- (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0") +- (match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r,w,DL")))] +- "TARGET_NEON" +-{ +- switch (which_alternative) +- { +- case 0: /* fall through */ +- case 4: return "vand\t%P0, %P1, %P2"; +- case 1: /* fall through */ +- case 5: return neon_output_logic_immediate ("vand", &operands[2], +- DImode, 1, VALID_NEON_QREG_MODE (DImode)); +- case 2: return "#"; +- case 3: return "#"; +- default: gcc_unreachable (); +- } +-} +- [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1") +- (set_attr "length" "*,*,8,8,*,*") +- (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")] +-) +- + (define_insn "orn3_neon" + [(set (match_operand:VDQ 0 "s_register_operand" "=w") + (ior:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w")) +@@ -828,21 +780,6 @@ + [(set_attr "neon_type" "neon_int_1")] + ) --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_u64 (uint64x2_t __a) -+#endif -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_s64 (int64x1_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2sidi (__a); - } +-(define_insn "xordi3_neon" +- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w") +- (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w") +- (match_operand:DI 2 "s_register_operand" "w,r,r,w")))] +- "TARGET_NEON" +- "@ +- veor\t%P0, %P1, %P2 +- # +- # +- veor\t%P0, %P1, %P2" +- [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1") +- (set_attr "length" "*,8,8,*") +- (set_attr "arch" "nota8,*,*,onlya8")] +-) +- + (define_insn "one_cmpl2" + [(set (match_operand:VDQ 0 "s_register_operand" "=w") + (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))] +@@ -1162,7 +1099,7 @@ + } + DONE; + }" +- [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8") ++ [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits") + (set_attr "opt" "*,*,speed,speed,*,*")] + ) --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_p8 (poly8x16_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_u64 (uint64x1_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2sidi ((int64x1_t) __a); - } +@@ -1263,7 +1200,7 @@ --__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_s16_p16 (poly16x8_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_s8 (int8x8_t __a) - { -- return (int16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv8qi (__a); - } + DONE; + }" +- [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8") ++ [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits") + (set_attr "opt" "*,*,speed,speed,*,*")] + ) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_s8 (int8x8_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_s16 (int16x4_t __a) - { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv8qi (__a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv4hi (__a); - } +@@ -3305,6 +3242,24 @@ + (const_string "neon_fp_vadd_qqq_vabs_qq")))] + ) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_s16 (int16x4_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_s32 (int32x2_t __a) - { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv4hi (__a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv2si (__a); - } ++(define_insn "neon_vcvtv4sfv4hf" ++ [(set (match_operand:V4SF 0 "s_register_operand" "=w") ++ (unspec:V4SF [(match_operand:V4HF 1 "s_register_operand" "w")] ++ UNSPEC_VCVT))] ++ "TARGET_NEON && TARGET_FP16" ++ "vcvt.f32.f16\t%q0, %P1" ++ [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")] ++) ++ ++(define_insn "neon_vcvtv4hfv4sf" ++ [(set (match_operand:V4HF 0 "s_register_operand" "=w") ++ (unspec:V4HF [(match_operand:V4SF 1 "s_register_operand" "w")] ++ UNSPEC_VCVT))] ++ "TARGET_NEON && TARGET_FP16" ++ "vcvt.f16.f32\t%P0, %q1" ++ [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")] ++) ++ + (define_insn "neon_vcvt_n" + [(set (match_operand: 0 "s_register_operand" "=w") + (unspec: [(match_operand:VCVTF 1 "s_register_operand" "w") +@@ -4660,21 +4615,22 @@ + ) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_s64 (int64x1_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_u8 (uint8x8_t __a) - { -- return (int32x2_t)__builtin_neon_vreinterpretv2sidi (__a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); - } + (define_insn "neon_vld1_dup" +- [(set (match_operand:VDX 0 "s_register_operand" "=w") +- (vec_duplicate:VDX (match_operand: 1 "neon_struct_operand" "Um")))] ++ [(set (match_operand:VD 0 "s_register_operand" "=w") ++ (vec_duplicate:VD (match_operand: 1 "neon_struct_operand" "Um")))] + "TARGET_NEON" +-{ +- if (GET_MODE_NUNITS (mode) > 1) +- return "vld1.\t{%P0[]}, %A1"; +- else +- return "vld1.\t%h0, %A1"; +-} +- [(set (attr "neon_type") +- (if_then_else (gt (const_string "") (const_string "1")) +- (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes") +- (const_string "neon_vld1_1_2_regs")))] ++ "vld1.\t{%P0[]}, %A1" ++ [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] + ) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_f32 (float32x2_t __a) -+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -+vreinterpret_u32_u16 (uint16x4_t __a) ++;; Special case for DImode. Treat it exactly like a simple load. ++(define_expand "neon_vld1_dupdi" ++ [(set (match_operand:DI 0 "s_register_operand" "") ++ (unspec:DI [(match_operand:DI 1 "neon_struct_operand" "")] ++ UNSPEC_VLD1))] ++ "TARGET_NEON" ++ "" ++) ++ + (define_insn "neon_vld1_dup" + [(set (match_operand:VQ 0 "s_register_operand" "=w") + (vec_duplicate:VQ (match_operand: 1 "neon_struct_operand" "Um")))] +@@ -5635,7 +5591,7 @@ + (match_operand:SI 3 "immediate_operand" "")] + "TARGET_NEON" { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv2sf (__a); -+ return (uint32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); - } +- emit_insn (gen_and3 (operands[0], operands[1], operands[2])); ++ emit_insn (gen_and3 (operands[0], operands[1], operands[2])); + DONE; + }) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_u8 (uint8x8_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_p16 (poly16x8_t __a) +@@ -5646,7 +5602,7 @@ + (match_operand:SI 3 "immediate_operand" "")] + "TARGET_NEON" { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); - } +- emit_insn (gen_ior3 (operands[0], operands[1], operands[2])); ++ emit_insn (gen_ior3 (operands[0], operands[1], operands[2])); + DONE; + }) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_u16 (uint16x4_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_f32 (float32x4_t __a) +@@ -5657,7 +5613,7 @@ + (match_operand:SI 3 "immediate_operand" "")] + "TARGET_NEON" { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv4sf (__a); - } +- emit_insn (gen_xor3 (operands[0], operands[1], operands[2])); ++ emit_insn (gen_xor3 (operands[0], operands[1], operands[2])); + DONE; + }) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_u32 (uint32x2_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_p64 (poly64x2_t __a) - { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv2si ((int32x2_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); - } +--- a/src/gcc/config/arm/ldmstm.md ++++ b/src/gcc/config/arm/ldmstm.md +@@ -37,7 +37,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "ldm%(ia%)\t%5, {%1, %2, %3, %4}" + [(set_attr "type" "load4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_u64 (uint64x1_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_p128 (poly128_t __a) - { -- return (int32x2_t)__builtin_neon_vreinterpretv2sidi ((int64x1_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiti ((__builtin_neon_ti) __a); - } + (define_insn "*thumb_ldm4_ia" + [(match_parallel 0 "load_multiple_operation" +@@ -74,7 +75,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" + "ldm%(ia%)\t%5!, {%1, %2, %3, %4}" + [(set_attr "type" "load4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_p8 (poly8x8_t __a) -+#endif -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_s64 (int64x2_t __a) - { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv2di (__a); - } + (define_insn "*thumb_ldm4_ia_update" + [(match_parallel 0 "load_multiple_operation" +@@ -108,7 +110,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "stm%(ia%)\t%5, {%1, %2, %3, %4}" + [(set_attr "type" "store4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) --vreinterpret_s32_p16 (poly16x4_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_u64 (uint64x2_t __a) - { -- return (int32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); - } + (define_insn "*stm4_ia_update" + [(match_parallel 0 "store_multiple_operation" +@@ -125,7 +128,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" + "stm%(ia%)\t%5!, {%1, %2, %3, %4}" + [(set_attr "type" "store4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_s8 (int8x16_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_s8 (int8x16_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv16qi (__a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv16qi (__a); - } + (define_insn "*thumb_stm4_ia_update" + [(match_parallel 0 "store_multiple_operation" +@@ -302,7 +306,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "ldm%(db%)\t%5, {%1, %2, %3, %4}" + [(set_attr "type" "load4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_s16 (int16x8_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_s16 (int16x8_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv8hi (__a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv8hi (__a); - } + (define_insn "*ldm4_db_update" + [(match_parallel 0 "load_multiple_operation" +@@ -323,7 +328,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" + "ldm%(db%)\t%5!, {%1, %2, %3, %4}" + [(set_attr "type" "load4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_s64 (int64x2_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_s32 (int32x4_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv2di (__a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv4si (__a); - } + (define_insn "*stm4_db" + [(match_parallel 0 "store_multiple_operation" +@@ -338,7 +344,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "stm%(db%)\t%5, {%1, %2, %3, %4}" + [(set_attr "type" "store4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_f32 (float32x4_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_u8 (uint8x16_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv4sf (__a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); - } + (define_insn "*stm4_db_update" + [(match_parallel 0 "store_multiple_operation" +@@ -355,7 +362,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 5" + "stm%(db%)\t%5!, {%1, %2, %3, %4}" + [(set_attr "type" "store4") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_u8 (uint8x16_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_u16 (uint16x8_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv16qi ((int8x16_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); - } + (define_peephole2 + [(set (match_operand:SI 0 "s_register_operand" "") +@@ -477,7 +485,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "ldm%(ia%)\t%4, {%1, %2, %3}" + [(set_attr "type" "load3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_u16 (uint16x8_t __a) -+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_p8_u32 (uint32x4_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv8hi ((int16x8_t) __a); -+ return (poly8x16_t)__builtin_neon_vreinterpretv16qiv4si ((int32x4_t) __a); - } + (define_insn "*thumb_ldm3_ia" + [(match_parallel 0 "load_multiple_operation" +@@ -508,7 +517,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "ldm%(ia%)\t%4!, {%1, %2, %3}" + [(set_attr "type" "load3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_u32 (uint32x4_t __a) -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_p8 (poly8x16_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv4si ((int32x4_t) __a); -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); - } + (define_insn "*thumb_ldm3_ia_update" + [(match_parallel 0 "load_multiple_operation" +@@ -537,7 +547,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "stm%(ia%)\t%4, {%1, %2, %3}" + [(set_attr "type" "store3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_s32_u64 (uint64x2_t __a) -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_f32 (float32x4_t __a) - { -- return (int32x4_t)__builtin_neon_vreinterpretv4siv2di ((int64x2_t) __a); -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv4sf (__a); - } + (define_insn "*stm3_ia_update" + [(match_parallel 0 "store_multiple_operation" +@@ -552,7 +563,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "stm%(ia%)\t%4!, {%1, %2, %3}" + [(set_attr "type" "store3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_p64 (poly64x2_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_p128 (poly128_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiti ((__builtin_neon_ti) __a); -+} -+ -+#endif -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_s64 (int64x2_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv2di (__a); -+} -+ -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_u64 (uint64x2_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); -+} -+ -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_s8 (int8x16_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv16qi (__a); -+} -+ -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_s16 (int16x8_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv8hi (__a); -+} -+ -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_s32 (int32x4_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv4si (__a); -+} -+ -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_u8 (uint8x16_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_u16 (uint16x8_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_p16_u32 (uint32x4_t __a) -+{ -+ return (poly16x8_t)__builtin_neon_vreinterpretv8hiv4si ((int32x4_t) __a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_p8 (poly8x16_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_p16 (poly16x8_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv8hi ((int16x8_t) __a); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_p64 (poly64x2_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_p128 (poly128_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfti ((__builtin_neon_ti) __a); -+} -+ -+#endif -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_s64 (int64x2_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv2di (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_u64 (uint64x2_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv2di ((int64x2_t) __a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_s8 (int8x16_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv16qi (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_s16 (int16x8_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv8hi (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_s32 (int32x4_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv4si (__a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_u8 (uint8x16_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_u16 (uint16x8_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_f32_u32 (uint32x4_t __a) -+{ -+ return (float32x4_t)__builtin_neon_vreinterpretv4sfv4si ((int32x4_t) __a); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_p8 (poly8x16_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_p16 (poly16x8_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_f32 (float32x4_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div4sf (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_p128 (poly128_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2diti ((__builtin_neon_ti) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_s64 (int64x2_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div2di (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_u64 (uint64x2_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_s8 (int8x16_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div16qi (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_s16 (int16x8_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div8hi (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_s32 (int32x4_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div4si (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_u8 (uint8x16_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_u16 (uint16x8_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_p64_u32 (uint32x4_t __a) -+{ -+ return (poly64x2_t)__builtin_neon_vreinterpretv2div4si ((int32x4_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_p8 (poly8x16_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv16qi ((int8x16_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_p16 (poly16x8_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv8hi ((int16x8_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_f32 (float32x4_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv4sf (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_p64 (poly64x2_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_s64 (int64x2_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv2di (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_u64 (uint64x2_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_s8 (int8x16_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv16qi (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_s16 (int16x8_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv8hi (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_s32 (int32x4_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv4si (__a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_u8 (uint8x16_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv16qi ((int8x16_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_u16 (uint16x8_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv8hi ((int16x8_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vreinterpretq_p128_u32 (uint32x4_t __a) -+{ -+ return (poly128_t)__builtin_neon_vreinterprettiv4si ((int32x4_t) __a); -+} -+ -+#endif -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_p8 (poly8x16_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_p16 (poly16x8_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_f32 (float32x4_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div4sf (__a); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_p64 (poly64x2_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_p128 (poly128_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2diti ((__builtin_neon_ti) __a); -+} -+ -+#endif -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_u64 (uint64x2_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div2di ((int64x2_t) __a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_s8 (int8x16_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div16qi (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_s16 (int16x8_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div8hi (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_s32 (int32x4_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div4si (__a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_u8 (uint8x16_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_u16 (uint16x8_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_s64_u32 (uint32x4_t __a) -+{ -+ return (int64x2_t)__builtin_neon_vreinterpretv2div4si ((int32x4_t) __a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_p8 (poly8x16_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_p16 (poly16x8_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_f32 (float32x4_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div4sf (__a); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_p64 (poly64x2_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_p128 (poly128_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2diti ((__builtin_neon_ti) __a); -+} -+ -+#endif -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_s64 (int64x2_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div2di (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_s8 (int8x16_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div16qi (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_s16 (int16x8_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div8hi (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_s32 (int32x4_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div4si (__a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_u8 (uint8x16_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_u16 (uint16x8_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -+vreinterpretq_u64_u32 (uint32x4_t __a) -+{ -+ return (uint64x2_t)__builtin_neon_vreinterpretv2div4si ((int32x4_t) __a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_p8 (poly8x16_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_p16 (poly16x8_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_f32 (float32x4_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv4sf (__a); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_p64 (poly64x2_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_p128 (poly128_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiti ((__builtin_neon_ti) __a); -+} -+ -+#endif -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_s64 (int64x2_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv2di (__a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_u64 (uint64x2_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_s16 (int16x8_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv8hi (__a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_s32 (int32x4_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv4si (__a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_u8 (uint8x16_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_u16 (uint16x8_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_s8_u32 (uint32x4_t __a) -+{ -+ return (int8x16_t)__builtin_neon_vreinterpretv16qiv4si ((int32x4_t) __a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_p8 (poly8x16_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_p16 (poly16x8_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_f32 (float32x4_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv4sf (__a); -+} -+ -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_p64 (poly64x2_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); -+} -+ -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_p128 (poly128_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiti ((__builtin_neon_ti) __a); -+} -+ -+#endif -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_s64 (int64x2_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv2di (__a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_u64 (uint64x2_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_s8 (int8x16_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv16qi (__a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_s32 (int32x4_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv4si (__a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_u8 (uint8x16_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_u16 (uint16x8_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); -+} -+ -+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_s16_u32 (uint32x4_t __a) -+{ -+ return (int16x8_t)__builtin_neon_vreinterpretv8hiv4si ((int32x4_t) __a); -+} -+ - __extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) - vreinterpretq_s32_p8 (poly8x16_t __a) - { -@@ -11975,109 +12957,111 @@ - return (int32x4_t)__builtin_neon_vreinterpretv4siv8hi ((int16x8_t) __a); - } + (define_insn "*thumb_stm3_ia_update" + [(match_parallel 0 "store_multiple_operation" +@@ -704,7 +716,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "ldm%(db%)\t%4, {%1, %2, %3}" + [(set_attr "type" "load3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_s8 (int8x8_t __a) -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_f32 (float32x4_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv8qi (__a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv4sf (__a); - } + (define_insn "*ldm3_db_update" + [(match_parallel 0 "load_multiple_operation" +@@ -722,7 +735,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "ldm%(db%)\t%4!, {%1, %2, %3}" + [(set_attr "type" "load3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_s16 (int16x4_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_p64 (poly64x2_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv4hi (__a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv2di ((int64x2_t) __a); - } + (define_insn "*stm3_db" + [(match_parallel 0 "store_multiple_operation" +@@ -735,7 +749,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "stm%(db%)\t%4, {%1, %2, %3}" + [(set_attr "type" "store3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_s32 (int32x2_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_p128 (poly128_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv2si (__a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siti ((__builtin_neon_ti) __a); - } + (define_insn "*stm3_db_update" + [(match_parallel 0 "store_multiple_operation" +@@ -750,7 +765,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 4" + "stm%(db%)\t%4!, {%1, %2, %3}" + [(set_attr "type" "store3") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_s64 (int64x1_t __a) -+#endif -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_s64 (int64x2_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qidi (__a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv2di (__a); - } + (define_peephole2 + [(set (match_operand:SI 0 "s_register_operand" "") +@@ -855,7 +871,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" + "ldm%(ia%)\t%3, {%1, %2}" + [(set_attr "type" "load2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_f32 (float32x2_t __a) -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_u64 (uint64x2_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv2sf (__a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv2di ((int64x2_t) __a); - } + (define_insn "*thumb_ldm2_ia" + [(match_parallel 0 "load_multiple_operation" +@@ -880,7 +897,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "ldm%(ia%)\t%3!, {%1, %2}" + [(set_attr "type" "load2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_u16 (uint16x4_t __a) -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_s8 (int8x16_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv16qi (__a); - } + (define_insn "*thumb_ldm2_ia_update" + [(match_parallel 0 "load_multiple_operation" +@@ -904,7 +922,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" + "stm%(ia%)\t%3, {%1, %2}" + [(set_attr "type" "store2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_u32 (uint32x2_t __a) -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_s16 (int16x8_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv2si ((int32x2_t) __a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv8hi (__a); - } + (define_insn "*stm2_ia_update" + [(match_parallel 0 "store_multiple_operation" +@@ -917,7 +936,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "stm%(ia%)\t%3!, {%1, %2}" + [(set_attr "type" "store2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_u64 (uint64x1_t __a) -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_u8 (uint8x16_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qidi ((int64x1_t) __a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv16qi ((int8x16_t) __a); - } + (define_insn "*thumb_stm2_ia_update" + [(match_parallel 0 "store_multiple_operation" +@@ -1044,7 +1064,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" + "ldm%(db%)\t%3, {%1, %2}" + [(set_attr "type" "load2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_p8 (poly8x8_t __a) -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_u16 (uint16x8_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv8qi ((int8x8_t) __a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv8hi ((int16x8_t) __a); - } + (define_insn "*ldm2_db_update" + [(match_parallel 0 "load_multiple_operation" +@@ -1059,7 +1080,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "ldm%(db%)\t%3!, {%1, %2}" + [(set_attr "type" "load2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) --__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) --vreinterpret_u8_p16 (poly16x4_t __a) -+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_s32_u32 (uint32x4_t __a) - { -- return (uint8x8_t)__builtin_neon_vreinterpretv8qiv4hi ((int16x4_t) __a); -+ return (int32x4_t)__builtin_neon_vreinterpretv4siv4si ((int32x4_t) __a); - } + (define_insn "*stm2_db" + [(match_parallel 0 "store_multiple_operation" +@@ -1070,7 +1092,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" + "stm%(db%)\t%3, {%1, %2}" + [(set_attr "type" "store2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_s8 (int8x16_t __a) -+vreinterpretq_u8_p8 (poly8x16_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv16qi (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); - } + (define_insn "*stm2_db_update" + [(match_parallel 0 "store_multiple_operation" +@@ -1083,7 +1106,8 @@ + "TARGET_32BIT && XVECLEN (operands[0], 0) == 3" + "stm%(db%)\t%3!, {%1, %2}" + [(set_attr "type" "store2") +- (set_attr "predicable" "yes")]) ++ (set_attr "predicable" "yes") ++ (set_attr "predicable_short_it" "no")]) - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_s16 (int16x8_t __a) -+vreinterpretq_u8_p16 (poly16x8_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv8hi (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); - } + (define_peephole2 + [(set (match_operand:SI 0 "s_register_operand" "") +--- a/src/gcc/config/arm/arm_neon_builtins.def ++++ b/src/gcc/config/arm/arm_neon_builtins.def +@@ -0,0 +1,212 @@ ++/* NEON builtin definitions for ARM. ++ Copyright (C) 2013 ++ Free Software Foundation, Inc. ++ Contributed by ARM Ltd. ++ ++ This file is part of GCC. ++ ++ GCC is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published ++ by the Free Software Foundation; either version 3, or (at your ++ option) any later version. ++ ++ GCC is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ++ License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GCC; see the file COPYING3. If not see ++ . */ ++ ++VAR10 (BINOP, vadd, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR3 (BINOP, vaddl, v8qi, v4hi, v2si), ++VAR3 (BINOP, vaddw, v8qi, v4hi, v2si), ++VAR6 (BINOP, vhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR8 (BINOP, vqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR3 (BINOP, vaddhn, v8hi, v4si, v2di), ++VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si), ++VAR2 (TERNOP, vfma, v2sf, v4sf), ++VAR2 (TERNOP, vfms, v2sf, v4sf), ++VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si), ++VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si), ++VAR2 (TERNOP, vqdmlal, v4hi, v2si), ++VAR2 (TERNOP, vqdmlsl, v4hi, v2si), ++VAR3 (BINOP, vmull, v8qi, v4hi, v2si), ++VAR2 (SCALARMULL, vmull_n, v4hi, v2si), ++VAR2 (LANEMULL, vmull_lane, v4hi, v2si), ++VAR2 (SCALARMULL, vqdmull_n, v4hi, v2si), ++VAR2 (LANEMULL, vqdmull_lane, v4hi, v2si), ++VAR4 (SCALARMULH, vqdmulh_n, v4hi, v2si, v8hi, v4si), ++VAR4 (LANEMULH, vqdmulh_lane, v4hi, v2si, v8hi, v4si), ++VAR2 (BINOP, vqdmull, v4hi, v2si), ++VAR8 (BINOP, vshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR8 (BINOP, vqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR8 (SHIFTIMM, vshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR3 (SHIFTIMM, vshrn_n, v8hi, v4si, v2di), ++VAR3 (SHIFTIMM, vqshrn_n, v8hi, v4si, v2di), ++VAR3 (SHIFTIMM, vqshrun_n, v8hi, v4si, v2di), ++VAR8 (SHIFTIMM, vshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR8 (SHIFTIMM, vqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR8 (SHIFTIMM, vqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR3 (SHIFTIMM, vshll_n, v8qi, v4hi, v2si), ++VAR8 (SHIFTACC, vsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR10 (BINOP, vsub, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR3 (BINOP, vsubl, v8qi, v4hi, v2si), ++VAR3 (BINOP, vsubw, v8qi, v4hi, v2si), ++VAR8 (BINOP, vqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR6 (BINOP, vhsub, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR3 (BINOP, vsubhn, v8hi, v4si, v2di), ++VAR8 (BINOP, vceq, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR8 (BINOP, vcge, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR6 (BINOP, vcgeu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR8 (BINOP, vcgt, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR6 (BINOP, vcgtu, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR2 (BINOP, vcage, v2sf, v4sf), ++VAR2 (BINOP, vcagt, v2sf, v4sf), ++VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR8 (BINOP, vabd, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR3 (BINOP, vabdl, v8qi, v4hi, v2si), ++VAR6 (TERNOP, vaba, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR3 (TERNOP, vabal, v8qi, v4hi, v2si), ++VAR8 (BINOP, vmax, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR8 (BINOP, vmin, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR4 (BINOP, vpadd, v8qi, v4hi, v2si, v2sf), ++VAR6 (UNOP, vpaddl, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR6 (BINOP, vpadal, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR4 (BINOP, vpmax, v8qi, v4hi, v2si, v2sf), ++VAR4 (BINOP, vpmin, v8qi, v4hi, v2si, v2sf), ++VAR2 (BINOP, vrecps, v2sf, v4sf), ++VAR2 (BINOP, vrsqrts, v2sf, v4sf), ++VAR8 (SHIFTINSERT, vsri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR8 (SHIFTINSERT, vsli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di), ++VAR8 (UNOP, vabs, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR6 (UNOP, vqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR8 (UNOP, vneg, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR6 (UNOP, vqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR6 (UNOP, vcls, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR6 (UNOP, vclz, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++VAR2 (UNOP, vcnt, v8qi, v16qi), ++VAR4 (UNOP, vrecpe, v2si, v2sf, v4si, v4sf), ++VAR4 (UNOP, vrsqrte, v2si, v2sf, v4si, v4sf), ++VAR6 (UNOP, vmvn, v8qi, v4hi, v2si, v16qi, v8hi, v4si), ++ /* FIXME: vget_lane supports more variants than this! */ ++VAR10 (GETLANE, vget_lane, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (SETLANE, vset_lane, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR5 (CREATE, vcreate, v8qi, v4hi, v2si, v2sf, di), ++VAR10 (DUP, vdup_n, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (DUPLANE, vdup_lane, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR5 (COMBINE, vcombine, v8qi, v4hi, v2si, v2sf, di), ++VAR5 (SPLIT, vget_high, v16qi, v8hi, v4si, v4sf, v2di), ++VAR5 (SPLIT, vget_low, v16qi, v8hi, v4si, v4sf, v2di), ++VAR3 (UNOP, vmovn, v8hi, v4si, v2di), ++VAR3 (UNOP, vqmovn, v8hi, v4si, v2di), ++VAR3 (UNOP, vqmovun, v8hi, v4si, v2di), ++VAR3 (UNOP, vmovl, v8qi, v4hi, v2si), ++VAR6 (LANEMUL, vmul_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR6 (LANEMAC, vmla_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR2 (LANEMAC, vmlal_lane, v4hi, v2si), ++VAR2 (LANEMAC, vqdmlal_lane, v4hi, v2si), ++VAR6 (LANEMAC, vmls_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR2 (LANEMAC, vmlsl_lane, v4hi, v2si), ++VAR2 (LANEMAC, vqdmlsl_lane, v4hi, v2si), ++VAR6 (SCALARMUL, vmul_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR6 (SCALARMAC, vmla_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR2 (SCALARMAC, vmlal_n, v4hi, v2si), ++VAR2 (SCALARMAC, vqdmlal_n, v4hi, v2si), ++VAR6 (SCALARMAC, vmls_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR2 (SCALARMAC, vmlsl_n, v4hi, v2si), ++VAR2 (SCALARMAC, vqdmlsl_n, v4hi, v2si), ++VAR10 (BINOP, vext, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR8 (UNOP, vrev64, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR4 (UNOP, vrev32, v8qi, v4hi, v16qi, v8hi), ++VAR2 (UNOP, vrev16, v8qi, v16qi), ++VAR4 (CONVERT, vcvt, v2si, v2sf, v4si, v4sf), ++VAR4 (FIXCONV, vcvt_n, v2si, v2sf, v4si, v4sf), ++VAR1 (FLOAT_WIDEN, vcvtv4sf, v4hf), ++VAR1 (FLOAT_NARROW, vcvtv4hf, v4sf), ++VAR10 (SELECT, vbsl, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR2 (RINT, vrintn, v2sf, v4sf), ++VAR2 (RINT, vrinta, v2sf, v4sf), ++VAR2 (RINT, vrintp, v2sf, v4sf), ++VAR2 (RINT, vrintm, v2sf, v4sf), ++VAR2 (RINT, vrintz, v2sf, v4sf), ++VAR2 (RINT, vrintx, v2sf, v4sf), ++VAR1 (VTBL, vtbl1, v8qi), ++VAR1 (VTBL, vtbl2, v8qi), ++VAR1 (VTBL, vtbl3, v8qi), ++VAR1 (VTBL, vtbl4, v8qi), ++VAR1 (VTBX, vtbx1, v8qi), ++VAR1 (VTBX, vtbx2, v8qi), ++VAR1 (VTBX, vtbx3, v8qi), ++VAR1 (VTBX, vtbx4, v8qi), ++VAR8 (RESULTPAIR, vtrn, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR8 (RESULTPAIR, vzip, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR8 (RESULTPAIR, vuzp, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf), ++VAR5 (REINTERP, vreinterpretv8qi, v8qi, v4hi, v2si, v2sf, di), ++VAR5 (REINTERP, vreinterpretv4hi, v8qi, v4hi, v2si, v2sf, di), ++VAR5 (REINTERP, vreinterpretv2si, v8qi, v4hi, v2si, v2sf, di), ++VAR5 (REINTERP, vreinterpretv2sf, v8qi, v4hi, v2si, v2sf, di), ++VAR5 (REINTERP, vreinterpretdi, v8qi, v4hi, v2si, v2sf, di), ++VAR5 (REINTERP, vreinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di), ++VAR5 (REINTERP, vreinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di), ++VAR5 (REINTERP, vreinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di), ++VAR5 (REINTERP, vreinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di), ++VAR5 (REINTERP, vreinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (LOAD1, vld1, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (LOAD1LANE, vld1_lane, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (LOAD1, vld1_dup, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (STORE1, vst1, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (STORE1LANE, vst1_lane, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR9 (LOADSTRUCT, ++ vld2, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), ++VAR7 (LOADSTRUCTLANE, vld2_lane, ++ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR5 (LOADSTRUCT, vld2_dup, v8qi, v4hi, v2si, v2sf, di), ++VAR9 (STORESTRUCT, vst2, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), ++VAR7 (STORESTRUCTLANE, vst2_lane, ++ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR9 (LOADSTRUCT, ++ vld3, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), ++VAR7 (LOADSTRUCTLANE, vld3_lane, ++ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR5 (LOADSTRUCT, vld3_dup, v8qi, v4hi, v2si, v2sf, di), ++VAR9 (STORESTRUCT, vst3, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), ++VAR7 (STORESTRUCTLANE, vst3_lane, ++ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR9 (LOADSTRUCT, vld4, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), ++VAR7 (LOADSTRUCTLANE, vld4_lane, ++ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR5 (LOADSTRUCT, vld4_dup, v8qi, v4hi, v2si, v2sf, di), ++VAR9 (STORESTRUCT, vst4, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf), ++VAR7 (STORESTRUCTLANE, vst4_lane, ++ v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf), ++VAR10 (LOGICBINOP, vand, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (LOGICBINOP, vorr, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (BINOP, veor, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (LOGICBINOP, vbic, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), ++VAR10 (LOGICBINOP, vorn, ++ v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) +--- a/src/gcc/config/arm/neon.ml ++++ b/src/gcc/config/arm/neon.ml +@@ -21,7 +21,7 @@ + . *) - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_s32 (int32x4_t __a) -+vreinterpretq_u8_f32 (float32x4_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv4si (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv4sf (__a); - } + (* Shorthand types for vector elements. *) +-type elts = S8 | S16 | S32 | S64 | F32 | U8 | U16 | U32 | U64 | P8 | P16 ++type elts = S8 | S16 | S32 | S64 | F16 | F32 | U8 | U16 | U32 | U64 | P8 | P16 + | I8 | I16 | I32 | I64 | B8 | B16 | B32 | B64 | Conv of elts * elts + | Cast of elts * elts | NoElts -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_s64 (int64x2_t __a) -+vreinterpretq_u8_p64 (poly64x2_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv2di (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); - } +@@ -37,6 +37,7 @@ + | T_uint16x4 | T_uint16x8 + | T_uint32x2 | T_uint32x4 + | T_uint64x1 | T_uint64x2 ++ | T_float16x4 + | T_float32x2 | T_float32x4 + | T_poly8x8 | T_poly8x16 + | T_poly16x4 | T_poly16x8 +@@ -46,11 +47,13 @@ + | T_uint8 | T_uint16 + | T_uint32 | T_uint64 + | T_poly8 | T_poly16 +- | T_float32 | T_arrayof of int * vectype ++ | T_float16 | T_float32 ++ | T_arrayof of int * vectype + | T_ptrto of vectype | T_const of vectype + | T_void | T_intQI + | T_intHI | T_intSI +- | T_intDI | T_floatSF ++ | T_intDI | T_floatHF ++ | T_floatSF -+#endif -+#ifdef __ARM_FEATURE_CRYPTO - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_f32 (float32x4_t __a) -+vreinterpretq_u8_p128 (poly128_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv4sf (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiti ((__builtin_neon_ti) __a); - } + (* The meanings of the following are: + TImode : "Tetra", two registers (four words). +@@ -92,7 +95,7 @@ + | Arity3 of vectype * vectype * vectype * vectype + | Arity4 of vectype * vectype * vectype * vectype * vectype -+#endif - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_u16 (uint16x8_t __a) -+vreinterpretq_u8_s64 (int64x2_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv2di (__a); - } +-type vecmode = V8QI | V4HI | V2SI | V2SF | DI ++type vecmode = V8QI | V4HI | V4HF |V2SI | V2SF | DI + | V16QI | V8HI | V4SI | V4SF | V2DI + | QI | HI | SI | SF + +@@ -284,18 +287,22 @@ + | Fixed_core_reg + (* Mark that the intrinsic requires __ARM_FEATURE_string to be defined. *) + | Requires_feature of string ++ (* Mark that the intrinsic requires a particular architecture version. *) + | Requires_arch of int ++ (* Mark that the intrinsic requires a particular bit in __ARM_FP to ++ be set. *) ++ | Requires_FP_bit of int + + exception MixedMode of elts * elts + + let rec elt_width = function + S8 | U8 | P8 | I8 | B8 -> 8 +- | S16 | U16 | P16 | I16 | B16 -> 16 ++ | S16 | U16 | P16 | I16 | B16 | F16 -> 16 + | S32 | F32 | U32 | I32 | B32 -> 32 + | S64 | U64 | I64 | B64 -> 64 + | Conv (a, b) -> + let wa = elt_width a and wb = elt_width b in +- if wa = wb then wa else failwith "element width?" ++ if wa = wb then wa else raise (MixedMode (a, b)) + | Cast (a, b) -> raise (MixedMode (a, b)) + | NoElts -> failwith "No elts" + +@@ -303,7 +310,7 @@ + S8 | S16 | S32 | S64 -> Signed + | U8 | U16 | U32 | U64 -> Unsigned + | P8 | P16 -> Poly +- | F32 -> Float ++ | F16 | F32 -> Float + | I8 | I16 | I32 | I64 -> Int + | B8 | B16 | B32 | B64 -> Bits + | Conv (a, b) | Cast (a, b) -> ConvClass (elt_class a, elt_class b) +@@ -315,6 +322,7 @@ + | Signed, 16 -> S16 + | Signed, 32 -> S32 + | Signed, 64 -> S64 ++ | Float, 16 -> F16 + | Float, 32 -> F32 + | Unsigned, 8 -> U8 + | Unsigned, 16 -> U16 +@@ -384,7 +392,12 @@ + in + scan ((Array.length operands) - 1) + +-let rec mode_of_elt elt shape = ++(* Find a vecmode from a shape_elt ELT for an instruction with shape_form ++ SHAPE. For a Use_operands shape, if ARGPOS is passed then return the mode ++ for the given argument position, else determine which argument to return a ++ mode for automatically. *) ++ ++let rec mode_of_elt ?argpos elt shape = + let flt = match elt_class elt with + Float | ConvClass(_, Float) -> true | _ -> false in + let idx = +@@ -394,7 +407,10 @@ + in match shape with + All (_, Dreg) | By_scalar Dreg | Pair_result Dreg | Unary_scalar Dreg + | Binary_imm Dreg | Long_noreg Dreg | Wide_noreg Dreg -> +- [| V8QI; V4HI; if flt then V2SF else V2SI; DI |].(idx) ++ if flt then ++ [| V8QI; V4HF; V2SF; DI |].(idx) ++ else ++ [| V8QI; V4HI; V2SI; DI |].(idx) + | All (_, Qreg) | By_scalar Qreg | Pair_result Qreg | Unary_scalar Qreg + | Binary_imm Qreg | Long_noreg Qreg | Wide_noreg Qreg -> + [| V16QI; V8HI; if flt then V4SF else V4SI; V2DI |].(idx) +@@ -404,7 +420,11 @@ + | Long_imm -> + [| V8QI; V4HI; V2SI; DI |].(idx) + | Narrow | Narrow_imm -> [| V16QI; V8HI; V4SI; V2DI |].(idx) +- | Use_operands ops -> mode_of_elt elt (All (0, (find_key_operand ops))) ++ | Use_operands ops -> ++ begin match argpos with ++ None -> mode_of_elt ?argpos elt (All (0, (find_key_operand ops))) ++ | Some pos -> mode_of_elt ?argpos elt (All (0, ops.(pos))) ++ end + | _ -> failwith "invalid shape" + + (* Modify an element type dependent on the shape of the instruction and the +@@ -454,10 +474,11 @@ + | U16 -> T_uint16x4 + | U32 -> T_uint32x2 + | U64 -> T_uint64x1 ++ | F16 -> T_float16x4 + | F32 -> T_float32x2 + | P8 -> T_poly8x8 + | P16 -> T_poly16x4 +- | _ -> failwith "Bad elt type" ++ | _ -> failwith "Bad elt type for Dreg" + end + | Qreg -> + begin match elt with +@@ -472,7 +493,7 @@ + | F32 -> T_float32x4 + | P8 -> T_poly8x16 + | P16 -> T_poly16x8 +- | _ -> failwith "Bad elt type" ++ | _ -> failwith "Bad elt type for Qreg" + end + | Corereg -> + begin match elt with +@@ -487,7 +508,7 @@ + | P8 -> T_poly8 + | P16 -> T_poly16 + | F32 -> T_float32 +- | _ -> failwith "Bad elt type" ++ | _ -> failwith "Bad elt type for Corereg" + end + | Immed -> + T_immediate (0, 0) +@@ -506,7 +527,7 @@ + let vectype_size = function + T_int8x8 | T_int16x4 | T_int32x2 | T_int64x1 + | T_uint8x8 | T_uint16x4 | T_uint32x2 | T_uint64x1 +- | T_float32x2 | T_poly8x8 | T_poly16x4 -> 64 ++ | T_float32x2 | T_poly8x8 | T_poly16x4 | T_float16x4 -> 64 + | T_int8x16 | T_int16x8 | T_int32x4 | T_int64x2 + | T_uint8x16 | T_uint16x8 | T_uint32x4 | T_uint64x2 + | T_float32x4 | T_poly8x16 | T_poly16x8 -> 128 +@@ -1217,6 +1238,10 @@ + [Conv (S32, F32); Conv (U32, F32); Conv (F32, S32); Conv (F32, U32)]; + Vcvt, [InfoWord], All (2, Qreg), "vcvtQ", conv_1, + [Conv (S32, F32); Conv (U32, F32); Conv (F32, S32); Conv (F32, U32)]; ++ Vcvt, [Builtin_name "vcvt" ; Requires_FP_bit 1], ++ Use_operands [| Dreg; Qreg; |], "vcvt", conv_1, [Conv (F16, F32)]; ++ Vcvt, [Builtin_name "vcvt" ; Requires_FP_bit 1], ++ Use_operands [| Qreg; Dreg; |], "vcvt", conv_1, [Conv (F32, F16)]; + Vcvt_n, [InfoWord], Use_operands [| Dreg; Dreg; Immed |], "vcvt_n", conv_2, + [Conv (S32, F32); Conv (U32, F32); Conv (F32, S32); Conv (F32, U32)]; + Vcvt_n, [InfoWord], Use_operands [| Qreg; Qreg; Immed |], "vcvtQ_n", conv_2, +@@ -1782,7 +1807,7 @@ + | U8 -> "u8" | U16 -> "u16" | U32 -> "u32" | U64 -> "u64" + | I8 -> "i8" | I16 -> "i16" | I32 -> "i32" | I64 -> "i64" + | B8 -> "8" | B16 -> "16" | B32 -> "32" | B64 -> "64" +- | F32 -> "f32" | P8 -> "p8" | P16 -> "p16" ++ | F16 -> "f16" | F32 -> "f32" | P8 -> "p8" | P16 -> "p16" + | Conv (a, b) | Cast (a, b) -> string_of_elt a ^ "_" ^ string_of_elt b + | NoElts -> failwith "No elts" - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_u32 (uint32x4_t __a) --{ -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv4si ((int32x4_t) __a); --} -- --__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) - vreinterpretq_u8_u64 (uint64x2_t __a) - { - return (uint8x16_t)__builtin_neon_vreinterpretv16qiv2di ((int64x2_t) __a); -@@ -12084,75 +13068,79 @@ - } +@@ -1809,6 +1834,7 @@ + | T_uint32x4 -> affix "uint32x4" + | T_uint64x1 -> affix "uint64x1" + | T_uint64x2 -> affix "uint64x2" ++ | T_float16x4 -> affix "float16x4" + | T_float32x2 -> affix "float32x2" + | T_float32x4 -> affix "float32x4" + | T_poly8x8 -> affix "poly8x8" +@@ -1825,6 +1851,7 @@ + | T_uint64 -> affix "uint64" + | T_poly8 -> affix "poly8" + | T_poly16 -> affix "poly16" ++ | T_float16 -> affix "float16" + | T_float32 -> affix "float32" + | T_immediate _ -> "const int" + | T_void -> "void" +@@ -1832,6 +1859,7 @@ + | T_intHI -> "__builtin_neon_hi" + | T_intSI -> "__builtin_neon_si" + | T_intDI -> "__builtin_neon_di" ++ | T_floatHF -> "__builtin_neon_hf" + | T_floatSF -> "__builtin_neon_sf" + | T_arrayof (num, base) -> + let basename = name (fun x -> x) base in +@@ -1853,10 +1881,10 @@ + | B_XImode -> "__builtin_neon_xi" - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_p8 (poly8x16_t __a) -+vreinterpretq_u8_s8 (int8x16_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv16qi ((int8x16_t) __a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv16qi (__a); - } + let string_of_mode = function +- V8QI -> "v8qi" | V4HI -> "v4hi" | V2SI -> "v2si" | V2SF -> "v2sf" +- | DI -> "di" | V16QI -> "v16qi" | V8HI -> "v8hi" | V4SI -> "v4si" +- | V4SF -> "v4sf" | V2DI -> "v2di" | QI -> "qi" | HI -> "hi" | SI -> "si" +- | SF -> "sf" ++ V8QI -> "v8qi" | V4HI -> "v4hi" | V4HF -> "v4hf" | V2SI -> "v2si" ++ | V2SF -> "v2sf" | DI -> "di" | V16QI -> "v16qi" | V8HI -> "v8hi" ++ | V4SI -> "v4si" | V4SF -> "v4sf" | V2DI -> "v2di" | QI -> "qi" ++ | HI -> "hi" | SI -> "si" | SF -> "sf" - __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) --vreinterpretq_u8_p16 (poly16x8_t __a) -+vreinterpretq_u8_s16 (int16x8_t __a) - { -- return (uint8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv8hi (__a); - } + (* Use uppercase chars for letters which form part of the intrinsic name, but + should be omitted from the builtin name (the info is passed in an extra +--- a/src/gcc/config/arm/constraints.md ++++ b/src/gcc/config/arm/constraints.md +@@ -21,7 +21,7 @@ + ;; The following register constraints have been used: + ;; - in ARM/Thumb-2 state: t, w, x, y, z + ;; - in Thumb state: h, b +-;; - in both states: l, c, k ++;; - in both states: l, c, k, q, US + ;; In ARM state, 'l' is an alias for 'r' + ;; 'f' and 'v' were previously used for FPA and MAVERICK registers. --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_s8 (int8x8_t __a) -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_u8_s32 (int32x4_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv8qi (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv4si (__a); - } +@@ -86,6 +86,9 @@ + (define_register_constraint "k" "STACK_REG" + "@internal The stack register.") --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_s16 (int16x4_t __a) -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_u8_u16 (uint16x8_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv4hi (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv8hi ((int16x8_t) __a); - } ++(define_register_constraint "q" "(TARGET_ARM && TARGET_LDRD) ? CORE_REGS : GENERAL_REGS" ++ "@internal In ARM state with LDRD support, core registers, otherwise general registers.") ++ + (define_register_constraint "b" "TARGET_THUMB ? BASE_REGS : NO_REGS" + "@internal + Thumb only. The union of the low registers and the stack register.") +@@ -93,6 +96,9 @@ + (define_register_constraint "c" "CC_REG" + "@internal The condition code register.") --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_s32 (int32x2_t __a) -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vreinterpretq_u8_u32 (uint32x4_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv2si (__a); -+ return (uint8x16_t)__builtin_neon_vreinterpretv16qiv4si ((int32x4_t) __a); - } ++(define_register_constraint "Cs" "CALLER_SAVE_REGS" ++ "@internal The caller save registers. Useful for sibcalls.") ++ + (define_constraint "I" + "In ARM/Thumb-2 state a constant that can be used as an immediate value in a + Data Processing instruction. In Thumb-1 state a constant in the range +@@ -164,9 +170,9 @@ + && ival > 1020 && ival <= 1275"))) --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_s64 (int64x1_t __a) -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_u16_p8 (poly8x16_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hidi (__a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); - } + (define_constraint "Pd" +- "@internal In Thumb-1 state a constant in the range 0 to 7" ++ "@internal In Thumb state a constant in the range 0 to 7" + (and (match_code "const_int") +- (match_test "TARGET_THUMB1 && ival >= 0 && ival <= 7"))) ++ (match_test "TARGET_THUMB && ival >= 0 && ival <= 7"))) --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_f32 (float32x2_t __a) -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_u16_p16 (poly16x8_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv2sf (__a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); - } + (define_constraint "Pe" + "@internal In Thumb-1 state a constant in the range 256 to +510" +@@ -208,6 +214,11 @@ + (and (match_code "const_int") + (match_test "TARGET_THUMB2 && ival >= 0 && ival <= 255"))) --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_u8 (uint8x8_t __a) -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_u16_f32 (float32x4_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv4sf (__a); - } ++(define_constraint "Pz" ++ "@internal In Thumb-2 state the constant 0" ++ (and (match_code "const_int") ++ (match_test "TARGET_THUMB2 && (ival == 0)"))) ++ + (define_constraint "G" + "In ARM/Thumb-2 state the floating-point constant 0." + (and (match_code "const_double") +@@ -248,6 +259,24 @@ + (and (match_code "const_int") + (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)"))) --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_u32 (uint32x2_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_u16_p64 (poly64x2_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv2si ((int32x2_t) __a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); - } ++(define_constraint "De" ++ "@internal ++ In ARM/Thumb-2 state a const_int that can be used by insn anddi." ++ (and (match_code "const_int") ++ (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)"))) ++ ++(define_constraint "Df" ++ "@internal ++ In ARM/Thumb-2 state a const_int that can be used by insn iordi." ++ (and (match_code "const_int") ++ (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, IOR)"))) ++ ++(define_constraint "Dg" ++ "@internal ++ In ARM/Thumb-2 state a const_int that can be used by insn xordi." ++ (and (match_code "const_int") ++ (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, XOR)"))) ++ + (define_constraint "Di" + "@internal + In ARM/Thumb-2 state a const_int or const_double where both the high +@@ -305,6 +334,9 @@ + (and (match_code "const_double") + (match_test "TARGET_32BIT && TARGET_VFP && vfp3_const_double_for_fract_bits (op)"))) --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_u64 (uint64x1_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_u16_p128 (poly128_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hidi ((int64x1_t) __a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiti ((__builtin_neon_ti) __a); - } ++(define_register_constraint "Ts" "(arm_restrict_it) ? LO_REGS : GENERAL_REGS" ++ "For arm_restrict_it the core registers @code{r0}-@code{r7}. GENERAL_REGS otherwise.") ++ + (define_memory_constraint "Ua" + "@internal + An address valid for loading/storing register exclusive" +@@ -385,9 +417,16 @@ + 0) + && GET_CODE (XEXP (op, 0)) != POST_INC"))) --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_p8 (poly8x8_t __a) -+#endif -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_u16_s64 (int64x2_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv8qi ((int8x8_t) __a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv2di (__a); - } ++(define_constraint "US" ++ "@internal ++ US is a symbol reference." ++ (match_code "symbol_ref") ++) ++ + ;; We used to have constraint letters for S and R in ARM state, but + ;; all uses of these now appear to have been removed. --__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) --vreinterpret_u16_p16 (poly16x4_t __a) -+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -+vreinterpretq_u16_u64 (uint64x2_t __a) - { -- return (uint16x4_t)__builtin_neon_vreinterpretv4hiv4hi ((int16x4_t) __a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); - } + ;; Additionally, we used to have a Q constraint in Thumb state, but + ;; this wasn't really a valid memory constraint. Again, all uses of + ;; this now seem to have been removed. ++ +--- a/src/gcc/config/arm/cortex-a7.md ++++ b/src/gcc/config/arm/cortex-a7.md +@@ -88,9 +88,9 @@ + ;; ALU instruction with an immediate operand can dual-issue. + (define_insn_reservation "cortex_a7_alu_imm" 2 + (and (eq_attr "tune" "cortexa7") +- (and (ior (eq_attr "type" "simple_alu_imm") +- (ior (eq_attr "type" "simple_alu_shift") +- (and (eq_attr "insn" "mov") ++ (and (ior (eq_attr "type" "arlo_imm,mov_imm,mvn_imm") ++ (ior (eq_attr "type" "extend") ++ (and (eq_attr "type" "mov_reg,mov_shift,mov_shift_reg") + (not (eq_attr "length" "8"))))) + (eq_attr "neon_type" "none"))) + "cortex_a7_ex2|cortex_a7_ex1") +@@ -99,13 +99,15 @@ + ;; with a younger immediate-based instruction. + (define_insn_reservation "cortex_a7_alu_reg" 2 + (and (eq_attr "tune" "cortexa7") +- (and (eq_attr "type" "alu_reg") ++ (and (eq_attr "type" "arlo_reg,shift,shift_reg,mov_reg,mvn_reg") + (eq_attr "neon_type" "none"))) + "cortex_a7_ex1") - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -@@ -12174,167 +13162,266 @@ - } + (define_insn_reservation "cortex_a7_alu_shift" 2 + (and (eq_attr "tune" "cortexa7") +- (and (eq_attr "type" "alu_shift,alu_shift_reg") ++ (and (eq_attr "type" "arlo_shift,arlo_shift_reg,\ ++ mov_shift,mov_shift_reg,\ ++ mvn_shift,mvn_shift_reg") + (eq_attr "neon_type" "none"))) + "cortex_a7_ex1") - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_u16_s64 (int64x2_t __a) -+vreinterpretq_u16_u8 (uint8x16_t __a) - { -- return (uint16x8_t)__builtin_neon_vreinterpretv8hiv2di (__a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); - } +@@ -127,8 +129,9 @@ - __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_u16_f32 (float32x4_t __a) -+vreinterpretq_u16_u32 (uint32x4_t __a) - { -- return (uint16x8_t)__builtin_neon_vreinterpretv8hiv4sf (__a); -+ return (uint16x8_t)__builtin_neon_vreinterpretv8hiv4si ((int32x4_t) __a); - } + (define_insn_reservation "cortex_a7_mul" 2 + (and (eq_attr "tune" "cortexa7") +- (and (eq_attr "type" "mult") +- (eq_attr "neon_type" "none"))) ++ (and (eq_attr "neon_type" "none") ++ (ior (eq_attr "mul32" "yes") ++ (eq_attr "mul64" "yes")))) + "cortex_a7_both") --__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_u16_u8 (uint8x16_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_p8 (poly8x16_t __a) - { -- return (uint16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv16qi ((int8x16_t) __a); - } + ;; Forward the result of a multiply operation to the accumulator +@@ -140,7 +143,7 @@ + ;; The latency depends on the operands, so we use an estimate here. + (define_insn_reservation "cortex_a7_idiv" 5 + (and (eq_attr "tune" "cortexa7") +- (eq_attr "insn" "udiv,sdiv")) ++ (eq_attr "type" "udiv,sdiv")) + "cortex_a7_both*5") --__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_u16_u32 (uint32x4_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_p16 (poly16x8_t __a) - { -- return (uint16x8_t)__builtin_neon_vreinterpretv8hiv4si ((int32x4_t) __a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv8hi ((int16x8_t) __a); - } + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +--- a/src/gcc/config/arm/arm-arches.def ++++ b/src/gcc/config/arm/arm-arches.def +@@ -53,6 +53,6 @@ + ARM_ARCH("armv7-r", cortexr4, 7R, FL_CO_PROC | FL_FOR_ARCH7R) + ARM_ARCH("armv7-m", cortexm3, 7M, FL_CO_PROC | FL_FOR_ARCH7M) + ARM_ARCH("armv7e-m", cortexm4, 7EM, FL_CO_PROC | FL_FOR_ARCH7EM) +-ARM_ARCH("armv8-a", cortexa15, 8A, FL_CO_PROC | FL_FOR_ARCH8A) ++ARM_ARCH("armv8-a", cortexa53, 8A, FL_CO_PROC | FL_FOR_ARCH8A) + ARM_ARCH("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT) + ARM_ARCH("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2) +--- a/src/gcc/config/arm/t-arm ++++ b/src/gcc/config/arm/t-arm +@@ -39,6 +39,7 @@ + $(srcdir)/config/arm/cortex-a8-neon.md \ + $(srcdir)/config/arm/cortex-a9.md \ + $(srcdir)/config/arm/cortex-a9-neon.md \ ++ $(srcdir)/config/arm/cortex-a53.md \ + $(srcdir)/config/arm/cortex-m4-fpu.md \ + $(srcdir)/config/arm/cortex-m4.md \ + $(srcdir)/config/arm/cortex-r4f.md \ +@@ -52,6 +53,7 @@ + $(srcdir)/config/arm/iwmmxt.md \ + $(srcdir)/config/arm/iwmmxt2.md \ + $(srcdir)/config/arm/ldmstm.md \ ++ $(srcdir)/config/arm/ldrdstrd.md \ + $(srcdir)/config/arm/marvell-f-iwmmxt.md \ + $(srcdir)/config/arm/neon.md \ + $(srcdir)/config/arm/predicates.md \ +@@ -84,7 +86,8 @@ + $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ + $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ + intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) $(srcdir)/config/arm/arm-cores.def \ +- $(srcdir)/config/arm/arm-arches.def $(srcdir)/config/arm/arm-fpus.def ++ $(srcdir)/config/arm/arm-arches.def $(srcdir)/config/arm/arm-fpus.def \ ++ $(srcdir)/config/arm/arm_neon_builtins.def --__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_u16_u64 (uint64x2_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_f32 (float32x4_t __a) - { -- return (uint16x8_t)__builtin_neon_vreinterpretv8hiv2di ((int64x2_t) __a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv4sf (__a); - } + arm-c.o: $(srcdir)/config/arm/arm-c.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) +--- a/src/gcc/config/arm/arm.opt ++++ b/src/gcc/config/arm/arm.opt +@@ -239,6 +239,10 @@ + Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS) + Only generate absolute relocations on word sized values. --__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_u16_p8 (poly8x16_t __a) -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_p64 (poly64x2_t __a) - { -- return (uint16x8_t)__builtin_neon_vreinterpretv8hiv16qi ((int8x16_t) __a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv2di ((int64x2_t) __a); - } ++mrestrict-it ++Target Report Var(arm_restrict_it) Init(2) ++Generate IT blocks appropriate for ARMv8. ++ + mfix-cortex-m3-ldrd + Target Report Var(fix_cm3_ldrd) Init(2) + Avoid overlapping destination and address registers on LDRD instructions +@@ -247,3 +251,7 @@ + munaligned-access + Target Report Var(unaligned_access) Init(2) + Enable unaligned word and halfword accesses to packed data. ++ ++mneon-for-64bits ++Target Report RejectNegative Var(use_neon_for_64bits) Init(0) ++Use Neon to perform 64-bits operations rather than core registers. +--- a/src/gcc/config/arm/arm926ejs.md ++++ b/src/gcc/config/arm/arm926ejs.md +@@ -58,7 +58,9 @@ + ;; ALU operations with no shifted operand + (define_insn_reservation "9_alu_op" 1 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "type" "alu_reg,simple_alu_imm,simple_alu_shift,alu_shift")) ++ (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,arlo_shift,\ ++ mov_imm,mov_reg,mov_shift,\ ++ mvn_imm,mvn_reg,mvn_shift")) + "e,m,w") --__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) --vreinterpretq_u16_p16 (poly16x8_t __a) -+#endif -+#ifdef __ARM_FEATURE_CRYPTO -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_p128 (poly128_t __a) - { -- return (uint16x8_t)__builtin_neon_vreinterpretv8hiv8hi ((int16x8_t) __a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siti ((__builtin_neon_ti) __a); - } + ;; ALU operations with a shift-by-register operand +@@ -67,7 +69,7 @@ + ;; the execute stage. + (define_insn_reservation "9_alu_shift_reg_op" 2 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "type" "alu_shift_reg")) ++ (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + "e*2,m,w") --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_s8 (int8x8_t __a) -+#endif -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_s64 (int64x2_t __a) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv8qi (__a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv2di (__a); - } + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +@@ -81,32 +83,32 @@ --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_s16 (int16x4_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_u64 (uint64x2_t __a) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv4hi (__a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv2di ((int64x2_t) __a); - } + (define_insn_reservation "9_mult1" 3 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "insn" "smlalxy,mul,mla")) ++ (eq_attr "type" "smlalxy,mul,mla")) + "e*2,m,w") --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_s32 (int32x2_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_s8 (int8x16_t __a) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv2si (__a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv16qi (__a); - } + (define_insn_reservation "9_mult2" 4 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "insn" "muls,mlas")) ++ (eq_attr "type" "muls,mlas")) + "e*3,m,w") --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_s64 (int64x1_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_s16 (int16x8_t __a) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2sidi (__a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv8hi (__a); - } + (define_insn_reservation "9_mult3" 4 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "insn" "umull,umlal,smull,smlal")) ++ (eq_attr "type" "umull,umlal,smull,smlal")) + "e*3,m,w") --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_f32 (float32x2_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_s32 (int32x4_t __a) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv2sf (__a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv4si (__a); - } + (define_insn_reservation "9_mult4" 5 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "insn" "umulls,umlals,smulls,smlals")) ++ (eq_attr "type" "umulls,umlals,smulls,smlals")) + "e*4,m,w") --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_u8 (uint8x8_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_u8 (uint8x16_t __a) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv16qi ((int8x16_t) __a); - } + (define_insn_reservation "9_mult5" 2 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "insn" "smulxy,smlaxy,smlawx")) ++ (eq_attr "type" "smulxy,smlaxy,smlawx")) + "e,m,w") --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_u16 (uint16x4_t __a) -+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -+vreinterpretq_u32_u16 (uint16x8_t __a) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); -+ return (uint32x4_t)__builtin_neon_vreinterpretv4siv8hi ((int16x8_t) __a); - } + (define_insn_reservation "9_mult6" 3 + (and (eq_attr "tune" "arm926ejs") +- (eq_attr "insn" "smlalxy")) ++ (eq_attr "type" "smlalxy")) + "e*2,m,w") --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_u64 (uint64x1_t __a) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +--- a/src/gcc/config/arm/ldrdstrd.md ++++ b/src/gcc/config/arm/ldrdstrd.md +@@ -0,0 +1,260 @@ ++;; ARM ldrd/strd peephole optimizations. ++;; ++;; Copyright (C) 2013 Free Software Foundation, Inc. ++;; ++;; Written by Greta Yorsh ++ ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify it ++;; under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, but ++;; WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++;; General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++;; The following peephole optimizations identify consecutive memory ++;; accesses, and try to rearrange the operands to enable generation of ++;; ldrd/strd. ++ ++(define_peephole2 ; ldrd ++ [(set (match_operand:SI 0 "arm_general_register_operand" "") ++ (match_operand:SI 2 "memory_operand" "")) ++ (set (match_operand:SI 1 "arm_general_register_operand" "") ++ (match_operand:SI 3 "memory_operand" ""))] ++ "TARGET_LDRD ++ && current_tune->prefer_ldrd_strd ++ && !optimize_function_for_size_p (cfun)" ++ [(const_int 0)] ++{ ++ if (!gen_operands_ldrd_strd (operands, true, false, false)) ++ FAIL; ++ else if (TARGET_ARM) ++ { ++ /* In ARM state, the destination registers of LDRD/STRD must be ++ consecutive. We emit DImode access. */ ++ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); ++ operands[2] = adjust_address (operands[2], DImode, 0); ++ /* Emit [(set (match_dup 0) (match_dup 2))] */ ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); ++ DONE; ++ } ++ else if (TARGET_THUMB2) ++ { ++ /* Emit the pattern: ++ [(parallel [(set (match_dup 0) (match_dup 2)) ++ (set (match_dup 1) (match_dup 3))])] */ ++ rtx t1 = gen_rtx_SET (VOIDmode, operands[0], operands[2]); ++ rtx t2 = gen_rtx_SET (VOIDmode, operands[1], operands[3]); ++ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); ++ DONE; ++ } ++}) ++ ++(define_peephole2 ; strd ++ [(set (match_operand:SI 2 "memory_operand" "") ++ (match_operand:SI 0 "arm_general_register_operand" "")) ++ (set (match_operand:SI 3 "memory_operand" "") ++ (match_operand:SI 1 "arm_general_register_operand" ""))] ++ "TARGET_LDRD ++ && current_tune->prefer_ldrd_strd ++ && !optimize_function_for_size_p (cfun)" ++ [(const_int 0)] ++{ ++ if (!gen_operands_ldrd_strd (operands, false, false, false)) ++ FAIL; ++ else if (TARGET_ARM) ++ { ++ /* In ARM state, the destination registers of LDRD/STRD must be ++ consecutive. We emit DImode access. */ ++ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); ++ operands[2] = adjust_address (operands[2], DImode, 0); ++ /* Emit [(set (match_dup 2) (match_dup 0))] */ ++ emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[0])); ++ DONE; ++ } ++ else if (TARGET_THUMB2) ++ { ++ /* Emit the pattern: ++ [(parallel [(set (match_dup 2) (match_dup 0)) ++ (set (match_dup 3) (match_dup 1))])] */ ++ rtx t1 = gen_rtx_SET (VOIDmode, operands[2], operands[0]); ++ rtx t2 = gen_rtx_SET (VOIDmode, operands[3], operands[1]); ++ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); ++ DONE; ++ } ++}) + -+#ifdef __ARM_FEATURE_CRYPTO ++;; The following peepholes reorder registers to enable LDRD/STRD. ++(define_peephole2 ; strd of constants ++ [(set (match_operand:SI 0 "arm_general_register_operand" "") ++ (match_operand:SI 4 "const_int_operand" "")) ++ (set (match_operand:SI 2 "memory_operand" "") ++ (match_dup 0)) ++ (set (match_operand:SI 1 "arm_general_register_operand" "") ++ (match_operand:SI 5 "const_int_operand" "")) ++ (set (match_operand:SI 3 "memory_operand" "") ++ (match_dup 1))] ++ "TARGET_LDRD ++ && current_tune->prefer_ldrd_strd ++ && !optimize_function_for_size_p (cfun)" ++ [(const_int 0)] ++{ ++ if (!gen_operands_ldrd_strd (operands, false, true, false)) ++ FAIL; ++ else if (TARGET_ARM) ++ { ++ rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0])); ++ operands[2] = adjust_address (operands[2], DImode, 0); ++ /* Emit the pattern: ++ [(set (match_dup 0) (match_dup 4)) ++ (set (match_dup 1) (match_dup 5)) ++ (set (match_dup 2) tmp)] */ ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); ++ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); ++ emit_insn (gen_rtx_SET (VOIDmode, operands[2], tmp)); ++ DONE; ++ } ++ else if (TARGET_THUMB2) ++ { ++ /* Emit the pattern: ++ [(set (match_dup 0) (match_dup 4)) ++ (set (match_dup 1) (match_dup 5)) ++ (parallel [(set (match_dup 2) (match_dup 0)) ++ (set (match_dup 3) (match_dup 1))])] */ ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); ++ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); ++ rtx t1 = gen_rtx_SET (VOIDmode, operands[2], operands[0]); ++ rtx t2 = gen_rtx_SET (VOIDmode, operands[3], operands[1]); ++ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); ++ DONE; ++ } ++}) + -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vldrq_p128 (poly128_t const * __ptr) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2sidi ((int64x1_t) __a); -+#ifdef __ARM_BIG_ENDIAN -+ poly64_t* __ptmp = (poly64_t*) __ptr; -+ poly64_t __d0 = vld1_p64 (__ptmp); -+ poly64_t __d1 = vld1_p64 (__ptmp + 1); -+ return vreinterpretq_p128_p64 (vcombine_p64 (__d1, __d0)); -+#else -+ return vreinterpretq_p128_p64 (vld1q_p64 ((poly64_t*) __ptr)); -+#endif - } - --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_p8 (poly8x8_t __a) -+__extension__ static __inline void __attribute__ ((__always_inline__)) -+vstrq_p128 (poly128_t * __ptr, poly128_t __val) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv8qi ((int8x8_t) __a); -+#ifdef __ARM_BIG_ENDIAN -+ poly64x2_t __tmp = vreinterpretq_p64_p128 (__val); -+ poly64_t __d0 = vget_high_p64 (__tmp); -+ poly64_t __d1 = vget_low_p64 (__tmp); -+ vst1q_p64 ((poly64_t*) __ptr, vcombine_p64 (__d0, __d1)); -+#else -+ vst1q_p64 ((poly64_t*) __ptr, vreinterpretq_p64_p128 (__val)); -+#endif - } - --__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) --vreinterpret_u32_p16 (poly16x4_t __a) -+/* The vceq_p64 intrinsic does not map to a single instruction. -+ Instead we emulate it by performing a 32-bit variant of the vceq -+ and applying a pairwise min reduction to the result. -+ vceq_u32 will produce two 32-bit halves, each of which will contain either -+ all ones or all zeros depending on whether the corresponding 32-bit -+ halves of the poly64_t were equal. The whole poly64_t values are equal -+ if and only if both halves are equal, i.e. vceq_u32 returns all ones. -+ If the result is all zeroes for any half then the whole result is zeroes. -+ This is what the pairwise min reduction achieves. */ ++(define_peephole2 ; strd of constants ++ [(set (match_operand:SI 0 "arm_general_register_operand" "") ++ (match_operand:SI 4 "const_int_operand" "")) ++ (set (match_operand:SI 1 "arm_general_register_operand" "") ++ (match_operand:SI 5 "const_int_operand" "")) ++ (set (match_operand:SI 2 "memory_operand" "") ++ (match_dup 0)) ++ (set (match_operand:SI 3 "memory_operand" "") ++ (match_dup 1))] ++ "TARGET_LDRD ++ && current_tune->prefer_ldrd_strd ++ && !optimize_function_for_size_p (cfun)" ++ [(const_int 0)] ++{ ++ if (!gen_operands_ldrd_strd (operands, false, true, false)) ++ FAIL; ++ else if (TARGET_ARM) ++ { ++ rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0])); ++ operands[2] = adjust_address (operands[2], DImode, 0); ++ /* Emit the pattern ++ [(set (match_dup 0) (match_dup 4)) ++ (set (match_dup 1) (match_dup 5)) ++ (set (match_dup 2) tmp)] */ ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); ++ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); ++ emit_insn (gen_rtx_SET (VOIDmode, operands[2], tmp)); ++ DONE; ++ } ++ else if (TARGET_THUMB2) ++ { ++ /* Emit the pattern: ++ [(set (match_dup 0) (match_dup 4)) ++ (set (match_dup 1) (match_dup 5)) ++ (parallel [(set (match_dup 2) (match_dup 0)) ++ (set (match_dup 3) (match_dup 1))])] */ ++ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[4])); ++ emit_insn (gen_rtx_SET (VOIDmode, operands[1], operands[5])); ++ rtx t1 = gen_rtx_SET (VOIDmode, operands[2], operands[0]); ++ rtx t2 = gen_rtx_SET (VOIDmode, operands[3], operands[1]); ++ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); ++ DONE; ++ } ++}) + -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vceq_p64 (poly64x1_t __a, poly64x1_t __b) - { -- return (uint32x2_t)__builtin_neon_vreinterpretv2siv4hi ((int16x4_t) __a); -+ uint32x2_t __t_a = vreinterpret_u32_p64 (__a); -+ uint32x2_t __t_b = vreinterpret_u32_p64 (__b); -+ uint32x2_t __c = vceq_u32 (__t_a, __t_b); -+ uint32x2_t __m = vpmin_u32 (__c, __c); -+ return vreinterpret_u64_u32 (__m); - } - --__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_s8 (int8x16_t __a) -+/* The vtst_p64 intrinsic does not map to a single instruction. -+ We emulate it in way similar to vceq_p64 above but here we do -+ a reduction with max since if any two corresponding bits -+ in the two poly64_t's match, then the whole result must be all ones. */ ++;; The following two peephole optimizations are only relevant for ARM ++;; mode where LDRD/STRD require consecutive registers. + -+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -+vtst_p64 (poly64x1_t __a, poly64x1_t __b) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv16qi (__a); -+ uint32x2_t __t_a = vreinterpret_u32_p64 (__a); -+ uint32x2_t __t_b = vreinterpret_u32_p64 (__b); -+ uint32x2_t __c = vtst_u32 (__t_a, __t_b); -+ uint32x2_t __m = vpmax_u32 (__c, __c); -+ return vreinterpret_u64_u32 (__m); - } - -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaeseq_u8 (uint8x16_t __data, uint8x16_t __key) -+{ -+ return __builtin_arm_crypto_aese (__data, __key); -+} ++(define_peephole2 ; swap the destination registers of two loads ++ ; before a commutative operation. ++ [(set (match_operand:SI 0 "arm_general_register_operand" "") ++ (match_operand:SI 2 "memory_operand" "")) ++ (set (match_operand:SI 1 "arm_general_register_operand" "") ++ (match_operand:SI 3 "memory_operand" "")) ++ (set (match_operand:SI 4 "arm_general_register_operand" "") ++ (match_operator:SI 5 "commutative_binary_operator" ++ [(match_operand 6 "arm_general_register_operand" "") ++ (match_operand 7 "arm_general_register_operand" "") ]))] ++ "TARGET_LDRD && TARGET_ARM ++ && current_tune->prefer_ldrd_strd ++ && !optimize_function_for_size_p (cfun) ++ && ( ((rtx_equal_p(operands[0], operands[6])) && (rtx_equal_p(operands[1], operands[7]))) ++ ||((rtx_equal_p(operands[0], operands[7])) && (rtx_equal_p(operands[1], operands[6])))) ++ && (peep2_reg_dead_p (3, operands[0]) || rtx_equal_p (operands[0], operands[4])) ++ && (peep2_reg_dead_p (3, operands[1]) || rtx_equal_p (operands[1], operands[4]))" ++ [(set (match_dup 0) (match_dup 2)) ++ (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))] ++ { ++ if (!gen_operands_ldrd_strd (operands, true, false, true)) ++ { ++ FAIL; ++ } ++ else ++ { ++ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); ++ operands[2] = adjust_address (operands[2], DImode, 0); ++ } ++ } ++) + -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaesdq_u8 (uint8x16_t __data, uint8x16_t __key) -+{ -+ return __builtin_arm_crypto_aesd (__data, __key); -+} ++(define_peephole2 ; swap the destination registers of two loads ++ ; before a commutative operation that sets the flags. ++ [(set (match_operand:SI 0 "arm_general_register_operand" "") ++ (match_operand:SI 2 "memory_operand" "")) ++ (set (match_operand:SI 1 "arm_general_register_operand" "") ++ (match_operand:SI 3 "memory_operand" "")) ++ (parallel ++ [(set (match_operand:SI 4 "arm_general_register_operand" "") ++ (match_operator:SI 5 "commutative_binary_operator" ++ [(match_operand 6 "arm_general_register_operand" "") ++ (match_operand 7 "arm_general_register_operand" "") ])) ++ (clobber (reg:CC CC_REGNUM))])] ++ "TARGET_LDRD && TARGET_ARM ++ && current_tune->prefer_ldrd_strd ++ && !optimize_function_for_size_p (cfun) ++ && ( ((rtx_equal_p(operands[0], operands[6])) && (rtx_equal_p(operands[1], operands[7]))) ++ ||((rtx_equal_p(operands[0], operands[7])) && (rtx_equal_p(operands[1], operands[6])))) ++ && (peep2_reg_dead_p (3, operands[0]) || rtx_equal_p (operands[0], operands[4])) ++ && (peep2_reg_dead_p (3, operands[1]) || rtx_equal_p (operands[1], operands[4]))" ++ [(set (match_dup 0) (match_dup 2)) ++ (parallel ++ [(set (match_dup 4) ++ (match_op_dup 5 [(match_dup 6) (match_dup 7)])) ++ (clobber (reg:CC CC_REGNUM))])] ++ { ++ if (!gen_operands_ldrd_strd (operands, true, false, true)) ++ { ++ FAIL; ++ } ++ else ++ { ++ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); ++ operands[2] = adjust_address (operands[2], DImode, 0); ++ } ++ } ++) + -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaesmcq_u8 (uint8x16_t __data) ++;; TODO: Handle LDRD/STRD with writeback: ++;; (a) memory operands can be POST_INC, POST_DEC, PRE_MODIFY, POST_MODIFY ++;; (b) Patterns may be followed by an update of the base address. +--- a/src/gcc/config/arm/predicates.md ++++ b/src/gcc/config/arm/predicates.md +@@ -31,6 +31,28 @@ + || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); + }) + ++(define_predicate "imm_for_neon_inv_logic_operand" ++ (match_code "const_vector") +{ -+ return __builtin_arm_crypto_aesmc (__data); -+} ++ return (TARGET_NEON ++ && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); ++}) + -+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -+vaesimcq_u8 (uint8x16_t __data) -+{ -+ return __builtin_arm_crypto_aesimc (__data); -+} ++(define_predicate "neon_inv_logic_op2" ++ (ior (match_operand 0 "imm_for_neon_inv_logic_operand") ++ (match_operand 0 "s_register_operand"))) + -+__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -+vsha1h_u32 (uint32_t __hash_e) ++(define_predicate "imm_for_neon_logic_operand" ++ (match_code "const_vector") +{ -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ __t = __builtin_arm_crypto_sha1h (__t); -+ return vgetq_lane_u32 (__t, 0); -+} ++ return (TARGET_NEON ++ && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); ++}) + - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_s16 (int16x8_t __a) -+vsha1cq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv8hi (__a); -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ return __builtin_arm_crypto_sha1c (__hash_abcd, __t, __wk); - } - - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_s32 (int32x4_t __a) -+vsha1pq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv4si (__a); -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ return __builtin_arm_crypto_sha1p (__hash_abcd, __t, __wk); - } - - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_s64 (int64x2_t __a) -+vsha1mq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv2di (__a); -+ uint32x4_t __t = vdupq_n_u32 (0); -+ __t = vsetq_lane_u32 (__hash_e, __t, 0); -+ return __builtin_arm_crypto_sha1m (__hash_abcd, __t, __wk); - } ++(define_predicate "neon_logic_op2" ++ (ior (match_operand 0 "imm_for_neon_logic_operand") ++ (match_operand 0 "s_register_operand"))) ++ + ;; Any hard register. + (define_predicate "arm_hard_register_operand" + (match_code "reg") +@@ -145,6 +167,23 @@ + (ior (match_operand 0 "arm_rhs_operand") + (match_operand 0 "arm_neg_immediate_operand"))) - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_f32 (float32x4_t __a) -+vsha1su0q_u32 (uint32x4_t __w0_3, uint32x4_t __w4_7, uint32x4_t __w8_11) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv4sf (__a); -+ return __builtin_arm_crypto_sha1su0 (__w0_3, __w4_7, __w8_11); - } ++(define_predicate "arm_anddi_operand_neon" ++ (ior (match_operand 0 "s_register_operand") ++ (and (match_code "const_int") ++ (match_test "const_ok_for_dimode_op (INTVAL (op), AND)")) ++ (match_operand 0 "neon_inv_logic_op2"))) ++ ++(define_predicate "arm_iordi_operand_neon" ++ (ior (match_operand 0 "s_register_operand") ++ (and (match_code "const_int") ++ (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)")) ++ (match_operand 0 "neon_logic_op2"))) ++ ++(define_predicate "arm_xordi_operand" ++ (ior (match_operand 0 "s_register_operand") ++ (and (match_code "const_int") ++ (match_test "const_ok_for_dimode_op (INTVAL (op), XOR)")))) ++ + (define_predicate "arm_adddi_operand" + (ior (match_operand 0 "s_register_operand") + (and (match_code "const_int") +@@ -207,6 +246,10 @@ + (and (match_code "plus,minus,ior,xor,and") + (match_test "mode == GET_MODE (op)"))) - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_u8 (uint8x16_t __a) -+vsha1su1q_u32 (uint32x4_t __tw0_3, uint32x4_t __w12_15) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv16qi ((int8x16_t) __a); -+ return __builtin_arm_crypto_sha1su1 (__tw0_3, __w12_15); - } ++(define_special_predicate "shiftable_operator_strict_it" ++ (and (match_code "plus,and") ++ (match_test "mode == GET_MODE (op)"))) ++ + ;; True for logical binary operators. + (define_special_predicate "logical_binary_operator" + (and (match_code "ior,xor,and") +@@ -270,6 +313,24 @@ + (define_special_predicate "lt_ge_comparison_operator" + (match_code "lt,ge")) - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_u16 (uint16x8_t __a) -+vsha256hq_u32 (uint32x4_t __hash_abcd, uint32x4_t __hash_efgh, uint32x4_t __wk) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv8hi ((int16x8_t) __a); -+ return __builtin_arm_crypto_sha256h (__hash_abcd, __hash_efgh, __wk); - } ++;; The vsel instruction only accepts the ARM condition codes listed below. ++(define_special_predicate "arm_vsel_comparison_operator" ++ (and (match_operand 0 "expandable_comparison_operator") ++ (match_test "maybe_get_arm_condition_code (op) == ARM_GE ++ || maybe_get_arm_condition_code (op) == ARM_GT ++ || maybe_get_arm_condition_code (op) == ARM_EQ ++ || maybe_get_arm_condition_code (op) == ARM_VS ++ || maybe_get_arm_condition_code (op) == ARM_LT ++ || maybe_get_arm_condition_code (op) == ARM_LE ++ || maybe_get_arm_condition_code (op) == ARM_NE ++ || maybe_get_arm_condition_code (op) == ARM_VC"))) ++ ++(define_special_predicate "arm_cond_move_operator" ++ (if_then_else (match_test "arm_restrict_it") ++ (and (match_test "TARGET_FPU_ARMV8") ++ (match_operand 0 "arm_vsel_comparison_operator")) ++ (match_operand 0 "expandable_comparison_operator"))) ++ + (define_special_predicate "noov_comparison_operator" + (match_code "lt,ge,eq,ne")) - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_u64 (uint64x2_t __a) -+vsha256h2q_u32 (uint32x4_t __hash_abcd, uint32x4_t __hash_efgh, uint32x4_t __wk) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv2di ((int64x2_t) __a); -+ return __builtin_arm_crypto_sha256h2 (__hash_abcd, __hash_efgh, __wk); - } +@@ -506,28 +567,6 @@ + (ior (match_operand 0 "s_register_operand") + (match_operand 0 "imm_for_neon_rshift_operand"))) - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_p8 (poly8x16_t __a) -+vsha256su0q_u32 (uint32x4_t __w0_3, uint32x4_t __w4_7) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv16qi ((int8x16_t) __a); -+ return __builtin_arm_crypto_sha256su0 (__w0_3, __w4_7); - } +-(define_predicate "imm_for_neon_logic_operand" +- (match_code "const_vector") +-{ +- return (TARGET_NEON +- && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); +-}) +- +-(define_predicate "imm_for_neon_inv_logic_operand" +- (match_code "const_vector") +-{ +- return (TARGET_NEON +- && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); +-}) +- +-(define_predicate "neon_logic_op2" +- (ior (match_operand 0 "imm_for_neon_logic_operand") +- (match_operand 0 "s_register_operand"))) +- +-(define_predicate "neon_inv_logic_op2" +- (ior (match_operand 0 "imm_for_neon_inv_logic_operand") +- (match_operand 0 "s_register_operand"))) +- + ;; Predicates for named expanders that overlap multiple ISAs. - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) --vreinterpretq_u32_p16 (poly16x8_t __a) -+vsha256su1q_u32 (uint32x4_t __tw0_3, uint32x4_t __w8_11, uint32x4_t __w12_15) - { -- return (uint32x4_t)__builtin_neon_vreinterpretv4siv8hi ((int16x8_t) __a); -+ return __builtin_arm_crypto_sha256su1 (__tw0_3, __w8_11, __w12_15); + (define_predicate "cmpdi_operand" +@@ -617,3 +656,7 @@ + (define_predicate "mem_noofs_operand" + (and (match_code "mem") + (match_code "reg" "0"))) ++ ++(define_predicate "call_insn_operand" ++ (ior (match_code "symbol_ref") ++ (match_operand 0 "s_register_operand"))) +--- a/src/gcc/config/arm/arm_neon.h ++++ b/src/gcc/config/arm/arm_neon.h +@@ -43,6 +43,7 @@ + typedef __builtin_neon_si int32x2_t __attribute__ ((__vector_size__ (8))); + typedef __builtin_neon_di int64x1_t; + typedef __builtin_neon_sf float32x2_t __attribute__ ((__vector_size__ (8))); ++typedef __builtin_neon_hf float16x4_t __attribute__ ((__vector_size__ (8))); + typedef __builtin_neon_poly8 poly8x8_t __attribute__ ((__vector_size__ (8))); + typedef __builtin_neon_poly16 poly16x4_t __attribute__ ((__vector_size__ (8))); + typedef __builtin_neon_uqi uint8x8_t __attribute__ ((__vector_size__ (8))); +@@ -6016,6 +6017,22 @@ + return (uint32x4_t)__builtin_neon_vcvtv4sf (__a, 0); } -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vmull_p64 (poly64_t __a, poly64_t __b) ++#if ((__ARM_FP & 0x2) != 0) ++__extension__ static __inline float16x4_t __attribute__ ((__always_inline__)) ++vcvt_f16_f32 (float32x4_t __a) +{ -+ return (poly128_t) __builtin_arm_crypto_vmullp64 ((uint64_t) __a, (uint64_t) __b); ++ return (float16x4_t)__builtin_neon_vcvtv4hfv4sf (__a); +} + -+__extension__ static __inline poly128_t __attribute__ ((__always_inline__)) -+vmull_high_p64 (poly64x2_t __a, poly64x2_t __b) ++#endif ++#if ((__ARM_FP & 0x2) != 0) ++__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) ++vcvt_f32_f16 (float16x4_t __a) +{ -+ poly64_t __t1 = vget_high_p64 (__a); -+ poly64_t __t2 = vget_high_p64 (__b); -+ -+ return (poly128_t) __builtin_arm_crypto_vmullp64 ((uint64_t) __t1, (uint64_t) __t2); ++ return (float32x4_t)__builtin_neon_vcvtv4sfv4hf (__a); +} + +#endif - #ifdef __cplusplus - } - #endif + __extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) + vcvt_n_s32_f32 (float32x2_t __a, const int __b) + { --- a/src/gcc/config/arm/arm-ldmstm.ml +++ b/src/gcc/config/arm/arm-ldmstm.ml -@@ -149,6 +149,8 @@ +@@ -146,12 +146,15 @@ | IA, true, true -> true | _ -> false @@ -43466,7 +31984,6 @@ let target addrmode thumb = match addrmode, thumb with IA, true -> "TARGET_THUMB1" -@@ -155,6 +157,7 @@ | IA, false -> "TARGET_32BIT" | DB, false -> "TARGET_32BIT" | _, false -> "TARGET_ARM" @@ -43474,7 +31991,7 @@ let write_pattern_1 name ls addrmode nregs write_set_fn update thumb = let astr = string_of_addrmode addrmode in -@@ -184,8 +187,10 @@ +@@ -181,8 +184,10 @@ done; Printf.printf "}\"\n"; Printf.printf " [(set_attr \"type\" \"%s%d\")" ls nregs; @@ -44996,100 +33513,12 @@ - (eq_attr "wtype" "wldr")) + (eq_attr "type" "wmmx_wldr")) "mf_iwmmxt_pipeline") ---- a/src/gcc/config/arm/t-mlibs -+++ b/src/gcc/config/arm/t-mlibs -@@ -0,0 +1,21 @@ -+# A set of predefined MULTILIB for different ARM targets. -+# Through the configure option --with-multilib-list, user can customize the -+# final MULTILIB implementation. -+ -+comma := , -+space := -+space += -+ -+MULTILIB_OPTIONS = marm -+MULTILIB_DIRNAMES = arm -+MULTILIB_OPTIONS += march=armv4t -+MULTILIB_DIRNAMES += armv4t -+MULTILIB_OPTIONS += mfloat-abi=soft -+MULTILIB_DIRNAMES += soft -+ -+MULTILIB_EXCEPTIONS = -+ -+MULTILIB_REQUIRED = marm/march=armv4t/mfloat-abi=soft -+ -+MULTILIB_OSDIRNAMES = marm/march.armv4t/mfloat-abi.soft=!arm-linux-gnueabi -+ --- a/src/gcc/config/arm/iterators.md +++ b/src/gcc/config/arm/iterators.md -@@ -201,6 +201,20 @@ - (define_int_iterator NEON_VRINT [UNSPEC_NVRINTP UNSPEC_NVRINTZ UNSPEC_NVRINTM - UNSPEC_NVRINTX UNSPEC_NVRINTA UNSPEC_NVRINTN]) - -+(define_int_iterator CRC [UNSPEC_CRC32B UNSPEC_CRC32H UNSPEC_CRC32W -+ UNSPEC_CRC32CB UNSPEC_CRC32CH UNSPEC_CRC32CW]) -+ -+(define_int_iterator CRYPTO_UNARY [UNSPEC_AESMC UNSPEC_AESIMC]) -+ -+(define_int_iterator CRYPTO_BINARY [UNSPEC_AESD UNSPEC_AESE -+ UNSPEC_SHA1SU1 UNSPEC_SHA256SU0]) -+ -+(define_int_iterator CRYPTO_TERNARY [UNSPEC_SHA1SU0 UNSPEC_SHA256H -+ UNSPEC_SHA256H2 UNSPEC_SHA256SU1]) -+ -+(define_int_iterator CRYPTO_SELECTING [UNSPEC_SHA1C UNSPEC_SHA1M -+ UNSPEC_SHA1P]) -+ - ;;---------------------------------------------------------------------------- - ;; Mode attributes - ;;---------------------------------------------------------------------------- -@@ -500,3 +514,54 @@ +@@ -496,3 +496,11 @@ (define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p") (UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m") (UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")]) -+ -+(define_int_attr crc_variant [(UNSPEC_CRC32B "crc32b") (UNSPEC_CRC32H "crc32h") -+ (UNSPEC_CRC32W "crc32w") (UNSPEC_CRC32CB "crc32cb") -+ (UNSPEC_CRC32CH "crc32ch") (UNSPEC_CRC32CW "crc32cw")]) -+ -+(define_int_attr crc_mode [(UNSPEC_CRC32B "QI") (UNSPEC_CRC32H "HI") -+ (UNSPEC_CRC32W "SI") (UNSPEC_CRC32CB "QI") -+ (UNSPEC_CRC32CH "HI") (UNSPEC_CRC32CW "SI")]) -+ -+(define_int_attr crypto_pattern [(UNSPEC_SHA1H "sha1h") (UNSPEC_AESMC "aesmc") -+ (UNSPEC_AESIMC "aesimc") (UNSPEC_AESD "aesd") -+ (UNSPEC_AESE "aese") (UNSPEC_SHA1SU1 "sha1su1") -+ (UNSPEC_SHA256SU0 "sha256su0") (UNSPEC_SHA1C "sha1c") -+ (UNSPEC_SHA1M "sha1m") (UNSPEC_SHA1P "sha1p") -+ (UNSPEC_SHA1SU0 "sha1su0") (UNSPEC_SHA256H "sha256h") -+ (UNSPEC_SHA256H2 "sha256h2") -+ (UNSPEC_SHA256SU1 "sha256su1")]) -+ -+(define_int_attr crypto_type -+ [(UNSPEC_AESE "neon_crypto_aes") (UNSPEC_AESD "neon_crypto_aes") -+ (UNSPEC_AESMC "neon_crypto_aes") (UNSPEC_AESIMC "neon_crypto_aes") -+ (UNSPEC_SHA1C "neon_crypto_sha1_slow") (UNSPEC_SHA1P "neon_crypto_sha1_slow") -+ (UNSPEC_SHA1M "neon_crypto_sha1_slow") (UNSPEC_SHA1SU1 "neon_crypto_sha1_fast") -+ (UNSPEC_SHA1SU0 "neon_crypto_sha1_xor") (UNSPEC_SHA256H "neon_crypto_sha256_slow") -+ (UNSPEC_SHA256H2 "neon_crypto_sha256_slow") (UNSPEC_SHA256SU0 "neon_crypto_sha256_fast") -+ (UNSPEC_SHA256SU1 "neon_crypto_sha256_slow")]) -+ -+(define_int_attr crypto_size_sfx [(UNSPEC_SHA1H "32") (UNSPEC_AESMC "8") -+ (UNSPEC_AESIMC "8") (UNSPEC_AESD "8") -+ (UNSPEC_AESE "8") (UNSPEC_SHA1SU1 "32") -+ (UNSPEC_SHA256SU0 "32") (UNSPEC_SHA1C "32") -+ (UNSPEC_SHA1M "32") (UNSPEC_SHA1P "32") -+ (UNSPEC_SHA1SU0 "32") (UNSPEC_SHA256H "32") -+ (UNSPEC_SHA256H2 "32") (UNSPEC_SHA256SU1 "32")]) -+ -+(define_int_attr crypto_mode [(UNSPEC_SHA1H "V4SI") (UNSPEC_AESMC "V16QI") -+ (UNSPEC_AESIMC "V16QI") (UNSPEC_AESD "V16QI") -+ (UNSPEC_AESE "V16QI") (UNSPEC_SHA1SU1 "V4SI") -+ (UNSPEC_SHA256SU0 "V4SI") (UNSPEC_SHA1C "V4SI") -+ (UNSPEC_SHA1M "V4SI") (UNSPEC_SHA1P "V4SI") -+ (UNSPEC_SHA1SU0 "V4SI") (UNSPEC_SHA256H "V4SI") -+ (UNSPEC_SHA256H2 "V4SI") (UNSPEC_SHA256SU1 "V4SI")]) -+ +;; Both kinds of return insn. +(define_code_iterator returns [return simple_return]) +(define_code_attr return_str [(return "") (simple_return "simple_")]) @@ -45254,9 +33683,24 @@ + "stlex%?\t%0, %2, %C1" + [(set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no")]) +--- a/src/gcc/config/arm/neon-testgen.ml ++++ b/src/gcc/config/arm/neon-testgen.ml +@@ -163,10 +163,12 @@ + match List.find (fun feature -> + match feature with Requires_feature _ -> true + | Requires_arch _ -> true ++ | Requires_FP_bit 1 -> true + | _ -> false) + features with + Requires_feature "FMA" -> "arm_neonv2" + | Requires_arch 8 -> "arm_v8_neon" ++ | Requires_FP_bit 1 -> "arm_neon_fp16" + | _ -> assert false + with Not_found -> "arm_neon" + --- a/src/gcc/config/arm/fa726te.md +++ b/src/gcc/config/arm/fa726te.md -@@ -78,7 +78,8 @@ +@@ -78,15 +78,15 @@ ;; Move instructions. (define_insn_reservation "726te_shift_op" 1 (and (eq_attr "tune" "fa726te") @@ -45266,7 +33710,6 @@ "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") ;; ALU operations with no shifted operand will finished in 1 cycle -@@ -85,8 +86,7 @@ ;; Other ALU instructions 2 cycles. (define_insn_reservation "726te_alu_op" 1 (and (eq_attr "tune" "fa726te") @@ -45302,29 +33745,6 @@ umulls,umlals,smulls,smlals,smlawx,smulxy,smlaxy")) "fa726te_issue+fa726te_mac_pipe") ---- a/src/gcc/config/arm/neon-testgen.ml -+++ b/src/gcc/config/arm/neon-testgen.ml -@@ -163,10 +163,13 @@ - match List.find (fun feature -> - match feature with Requires_feature _ -> true - | Requires_arch _ -> true -+ | Requires_FP_bit 1 -> true - | _ -> false) - features with - Requires_feature "FMA" -> "arm_neonv2" -+ | Requires_feature "CRYPTO" -> "arm_crypto" - | Requires_arch 8 -> "arm_v8_neon" -+ | Requires_FP_bit 1 -> "arm_neon_fp16" - | _ -> assert false - with Not_found -> "arm_neon" - -@@ -298,5 +301,5 @@ - (* Program entry point. *) - let _ = - let directory = if Array.length Sys.argv <> 1 then Sys.argv.(1) else "." in -- List.iter (test_intrinsic_group directory) (reinterp @ ops) -+ List.iter (test_intrinsic_group directory) (reinterp @ reinterpq @ ops) - --- a/src/gcc/config/arm/arm.md +++ b/src/gcc/config/arm/arm.md @@ -74,6 +74,15 @@ @@ -45408,7 +33828,7 @@ (eq_attr "arch_enabled" "no") (const_string "no") -@@ -214,126 +226,341 @@ +@@ -214,126 +226,340 @@ (set_attr "length" "4") (set_attr "pool_range" "250")]) @@ -45640,7 +34060,6 @@ + branch,\ + call,\ + clz,\ -+ crc,\ + extend,\ + f_2_r,\ + f_cvt,\ @@ -45847,21 +34266,7 @@ ; Load scheduling, set from the arm_ld_sched variable ; initialized by arm_option_override() (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched"))) -@@ -402,6 +629,13 @@ - neon_mrrc,\ - neon_ldm_2,\ - neon_stm_2,\ -+ neon_crypto_aes,\ -+ neon_crypto_sha1_xor,\ -+ neon_crypto_sha1_fast,\ -+ neon_crypto_sha1_slow,\ -+ neon_crypto_sha256_fast,\ -+ neon_crypto_sha256_slow,\ -+ neon_mul_d_long,\ - none" - (const_string "none")) - -@@ -458,9 +692,19 @@ +@@ -458,9 +684,19 @@ ; than one on the main cpu execution unit. (define_attr "core_cycles" "single,multi" (if_then_else (eq_attr "type" @@ -45884,7 +34289,7 @@ (const_string "single") (const_string "multi"))) -@@ -502,7 +746,7 @@ +@@ -502,7 +738,7 @@ (define_attr "generic_sched" "yes,no" (const (if_then_else @@ -45893,7 +34298,7 @@ (eq_attr "tune_cortexr4" "yes")) (const_string "no") (const_string "yes")))) -@@ -510,7 +754,7 @@ +@@ -510,7 +746,7 @@ (define_attr "generic_vfp" "yes,no" (const (if_then_else (and (eq_attr "fpu" "vfp") @@ -45902,7 +34307,7 @@ (eq_attr "tune_cortexr4" "no")) (const_string "yes") (const_string "no")))) -@@ -531,6 +775,7 @@ +@@ -531,6 +767,7 @@ (include "cortex-a8.md") (include "cortex-a9.md") (include "cortex-a15.md") @@ -45910,7 +34315,7 @@ (include "cortex-r4.md") (include "cortex-r4f.md") (include "cortex-m4.md") -@@ -697,14 +942,17 @@ +@@ -697,14 +934,17 @@ ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will ;; put the duplicated register first, and not try the commutative version. (define_insn_and_split "*arm_addsi3" @@ -45931,7 +34336,7 @@ add%?\\t%0, %2, %1 addw%?\\t%0, %1, %2 addw%?\\t%0, %1, %2 -@@ -725,12 +973,13 @@ +@@ -725,12 +965,13 @@ operands[1], 0); DONE; " @@ -45949,7 +34354,7 @@ ] ) -@@ -811,7 +1060,7 @@ +@@ -811,7 +1052,7 @@ sub%.\\t%0, %1, #%n2 add%.\\t%0, %1, %2" [(set_attr "conds" "set") @@ -45958,7 +34363,7 @@ ) (define_insn "*addsi3_compare0_scratch" -@@ -827,7 +1076,7 @@ +@@ -827,24 +1068,27 @@ cmn%?\\t%0, %1" [(set_attr "conds" "set") (set_attr "predicable" "yes") @@ -45967,7 +34372,6 @@ ] ) -@@ -834,17 +1083,20 @@ (define_insn "*compare_negsi_si" [(set (reg:CC_Z CC_REGNUM) (compare:CC_Z @@ -45992,7 +34396,7 @@ [(set (reg:CC CC_REGNUM) (compare:CC (match_operand:SI 1 "s_register_operand" "r,r") -@@ -914,7 +1166,7 @@ +@@ -914,7 +1158,7 @@ sub%.\\t%0, %1, #%n2 add%.\\t%0, %1, %2" [(set_attr "conds" "set") @@ -46001,7 +34405,7 @@ ) (define_insn "*addsi3_compare_op2" -@@ -931,63 +1183,84 @@ +@@ -931,63 +1175,84 @@ add%.\\t%0, %1, %2 sub%.\\t%0, %1, #%n2" [(set_attr "conds" "set") @@ -46108,7 +34512,7 @@ ) (define_insn "*addsi3_carryin_shift_" -@@ -1001,9 +1274,11 @@ +@@ -1001,9 +1266,11 @@ "TARGET_32BIT" "adc%?\\t%0, %1, %3%S2" [(set_attr "conds" "use") @@ -46122,7 +34526,7 @@ ) (define_insn "*addsi3_carryin_clobercc_" -@@ -1017,26 +1292,89 @@ +@@ -1017,26 +1284,89 @@ [(set_attr "conds" "set")] ) @@ -46226,7 +34630,7 @@ ) ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant. -@@ -1087,13 +1425,27 @@ +@@ -1087,13 +1417,27 @@ " ) @@ -46256,7 +34660,7 @@ [(set_attr "conds" "clob") (set_attr "length" "8")] ) -@@ -1108,7 +1460,7 @@ +@@ -1108,55 +1452,113 @@ [(set_attr "length" "4")] ) @@ -46265,7 +34669,6 @@ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") (zero_extend:DI -@@ -1115,12 +1467,25 @@ (match_operand:SI 2 "s_register_operand" "r,r")))) (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" @@ -46293,7 +34696,6 @@ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") (sign_extend:DI -@@ -1127,12 +1492,26 @@ (match_operand:SI 2 "s_register_operand" "r,r")))) (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" @@ -46322,7 +34724,6 @@ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (minus:DI (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")) -@@ -1139,12 +1518,26 @@ (match_operand:DI 1 "s_register_operand" "0,r"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" @@ -46351,7 +34752,6 @@ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (minus:DI (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")) -@@ -1151,12 +1544,29 @@ (match_operand:DI 1 "s_register_operand" "0,r"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" @@ -46383,7 +34783,7 @@ [(set (match_operand:DI 0 "s_register_operand" "=r") (minus:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")) -@@ -1164,7 +1574,17 @@ +@@ -1164,7 +1566,17 @@ (match_operand:SI 2 "s_register_operand" "r")))) (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" @@ -46402,7 +34802,7 @@ [(set_attr "conds" "clob") (set_attr "length" "8")] ) -@@ -1201,12 +1621,16 @@ +@@ -1201,12 +1613,16 @@ ; ??? Check Thumb-2 split length (define_insn_and_split "*arm_subsi3_insn" @@ -46422,7 +34822,7 @@ sub%?\\t%0, %1, %2 sub%?\\t%0, %1, %2 sub%?\\t%0, %1, %2 -@@ -1219,9 +1643,11 @@ +@@ -1219,9 +1635,11 @@ INTVAL (operands[1]), operands[0], operands[2], 0); DONE; " @@ -46436,7 +34836,7 @@ ) (define_peephole2 -@@ -1251,10 +1677,10 @@ +@@ -1251,10 +1669,10 @@ sub%.\\t%0, %1, %2 rsb%.\\t%0, %2, %1" [(set_attr "conds" "set") @@ -46449,7 +34849,7 @@ [(set (reg:CC CC_REGNUM) (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I") (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))) -@@ -1266,32 +1692,9 @@ +@@ -1266,32 +1684,9 @@ sub%.\\t%0, %1, %2 rsb%.\\t%0, %2, %1" [(set_attr "conds" "set") @@ -46483,7 +34883,7 @@ (define_expand "subsf3" [(set (match_operand:SF 0 "s_register_operand" "") (minus:SF (match_operand:SF 1 "s_register_operand" "") -@@ -1311,6 +1714,20 @@ +@@ -1311,6 +1706,20 @@ ;; Multiplication insns @@ -46504,7 +34904,7 @@ (define_expand "mulsi3" [(set (match_operand:SI 0 "s_register_operand" "") (mult:SI (match_operand:SI 2 "s_register_operand" "") -@@ -1326,18 +1743,21 @@ +@@ -1326,18 +1735,21 @@ (match_operand:SI 1 "s_register_operand" "%0,r")))] "TARGET_32BIT && !arm_arch6" "mul%?\\t%0, %2, %1" @@ -46532,7 +34932,7 @@ ) ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands -@@ -1357,7 +1777,7 @@ +@@ -1357,7 +1769,7 @@ return \"mul\\t%0, %2\"; " [(set_attr "length" "4,4,2") @@ -46541,7 +34941,7 @@ ) (define_insn "*thumb_mulsi3_v6" -@@ -1370,7 +1790,7 @@ +@@ -1370,7 +1782,7 @@ mul\\t%0, %1 mul\\t%0, %1" [(set_attr "length" "2") @@ -46550,7 +34950,7 @@ ) (define_insn "*mulsi3_compare0" -@@ -1384,7 +1804,7 @@ +@@ -1384,7 +1796,7 @@ "TARGET_ARM && !arm_arch6" "mul%.\\t%0, %2, %1" [(set_attr "conds" "set") @@ -46559,7 +34959,7 @@ ) (define_insn "*mulsi3_compare0_v6" -@@ -1398,7 +1818,7 @@ +@@ -1398,7 +1810,7 @@ "TARGET_ARM && arm_arch6 && optimize_size" "mul%.\\t%0, %2, %1" [(set_attr "conds" "set") @@ -46568,7 +34968,7 @@ ) (define_insn "*mulsi_compare0_scratch" -@@ -1411,7 +1831,7 @@ +@@ -1411,7 +1823,7 @@ "TARGET_ARM && !arm_arch6" "mul%.\\t%0, %2, %1" [(set_attr "conds" "set") @@ -46577,7 +34977,7 @@ ) (define_insn "*mulsi_compare0_scratch_v6" -@@ -1424,7 +1844,7 @@ +@@ -1424,7 +1836,7 @@ "TARGET_ARM && arm_arch6 && optimize_size" "mul%.\\t%0, %2, %1" [(set_attr "conds" "set") @@ -46586,7 +34986,7 @@ ) ;; Unnamed templates to match MLA instruction. -@@ -1437,7 +1857,7 @@ +@@ -1437,7 +1849,7 @@ (match_operand:SI 3 "s_register_operand" "r,r,0,0")))] "TARGET_32BIT && !arm_arch6" "mla%?\\t%0, %2, %1, %3" @@ -46595,7 +34995,7 @@ (set_attr "predicable" "yes")] ) -@@ -1449,8 +1869,9 @@ +@@ -1449,8 +1861,9 @@ (match_operand:SI 3 "s_register_operand" "r")))] "TARGET_32BIT && arm_arch6" "mla%?\\t%0, %2, %1, %3" @@ -46607,7 +35007,7 @@ ) (define_insn "*mulsi3addsi_compare0" -@@ -1467,7 +1888,7 @@ +@@ -1467,7 +1880,7 @@ "TARGET_ARM && arm_arch6" "mla%.\\t%0, %2, %1, %3" [(set_attr "conds" "set") @@ -46616,7 +35016,7 @@ ) (define_insn "*mulsi3addsi_compare0_v6" -@@ -1484,7 +1905,7 @@ +@@ -1484,7 +1897,7 @@ "TARGET_ARM && arm_arch6 && optimize_size" "mla%.\\t%0, %2, %1, %3" [(set_attr "conds" "set") @@ -46625,7 +35025,7 @@ ) (define_insn "*mulsi3addsi_compare0_scratch" -@@ -1499,7 +1920,7 @@ +@@ -1499,7 +1912,7 @@ "TARGET_ARM && !arm_arch6" "mla%.\\t%0, %2, %1, %3" [(set_attr "conds" "set") @@ -46634,7 +35034,7 @@ ) (define_insn "*mulsi3addsi_compare0_scratch_v6" -@@ -1514,7 +1935,7 @@ +@@ -1514,7 +1927,7 @@ "TARGET_ARM && arm_arch6 && optimize_size" "mla%.\\t%0, %2, %1, %3" [(set_attr "conds" "set") @@ -46643,7 +35043,7 @@ ) (define_insn "*mulsi3subsi" -@@ -1525,8 +1946,9 @@ +@@ -1525,8 +1938,9 @@ (match_operand:SI 1 "s_register_operand" "r"))))] "TARGET_32BIT && arm_arch_thumb2" "mls%?\\t%0, %2, %1, %3" @@ -46655,7 +35055,7 @@ ) (define_expand "maddsidi4" -@@ -1548,7 +1970,7 @@ +@@ -1548,7 +1962,7 @@ (match_operand:DI 1 "s_register_operand" "0")))] "TARGET_32BIT && arm_arch3m && !arm_arch6" "smlal%?\\t%Q0, %R0, %3, %2" @@ -46664,7 +35064,7 @@ (set_attr "predicable" "yes")] ) -@@ -1561,8 +1983,9 @@ +@@ -1561,8 +1975,9 @@ (match_operand:DI 1 "s_register_operand" "0")))] "TARGET_32BIT && arm_arch6" "smlal%?\\t%Q0, %R0, %3, %2" @@ -46676,7 +35076,7 @@ ) ;; 32x32->64 widening multiply. -@@ -1587,7 +2010,7 @@ +@@ -1587,7 +2002,7 @@ (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] "TARGET_32BIT && arm_arch3m && !arm_arch6" "smull%?\\t%Q0, %R0, %1, %2" @@ -46685,7 +35085,7 @@ (set_attr "predicable" "yes")] ) -@@ -1598,8 +2021,9 @@ +@@ -1598,8 +2013,9 @@ (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] "TARGET_32BIT && arm_arch6" "smull%?\\t%Q0, %R0, %1, %2" @@ -46697,7 +35097,7 @@ ) (define_expand "umulsidi3" -@@ -1618,7 +2042,7 @@ +@@ -1618,7 +2034,7 @@ (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] "TARGET_32BIT && arm_arch3m && !arm_arch6" "umull%?\\t%Q0, %R0, %1, %2" @@ -46706,7 +35106,7 @@ (set_attr "predicable" "yes")] ) -@@ -1629,8 +2053,9 @@ +@@ -1629,8 +2045,9 @@ (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] "TARGET_32BIT && arm_arch6" "umull%?\\t%Q0, %R0, %1, %2" @@ -46718,7 +35118,7 @@ ) (define_expand "umaddsidi4" -@@ -1652,7 +2077,7 @@ +@@ -1652,7 +2069,7 @@ (match_operand:DI 1 "s_register_operand" "0")))] "TARGET_32BIT && arm_arch3m && !arm_arch6" "umlal%?\\t%Q0, %R0, %3, %2" @@ -46727,7 +35127,7 @@ (set_attr "predicable" "yes")] ) -@@ -1665,8 +2090,9 @@ +@@ -1665,8 +2082,9 @@ (match_operand:DI 1 "s_register_operand" "0")))] "TARGET_32BIT && arm_arch6" "umlal%?\\t%Q0, %R0, %3, %2" @@ -46739,7 +35139,7 @@ ) (define_expand "smulsi3_highpart" -@@ -1694,7 +2120,7 @@ +@@ -1694,7 +2112,7 @@ (clobber (match_scratch:SI 3 "=&r,&r"))] "TARGET_32BIT && arm_arch3m && !arm_arch6" "smull%?\\t%3, %0, %2, %1" @@ -46748,7 +35148,7 @@ (set_attr "predicable" "yes")] ) -@@ -1709,8 +2135,9 @@ +@@ -1709,8 +2127,9 @@ (clobber (match_scratch:SI 3 "=r"))] "TARGET_32BIT && arm_arch6" "smull%?\\t%3, %0, %2, %1" @@ -46760,7 +35160,7 @@ ) (define_expand "umulsi3_highpart" -@@ -1738,7 +2165,7 @@ +@@ -1738,7 +2157,7 @@ (clobber (match_scratch:SI 3 "=&r,&r"))] "TARGET_32BIT && arm_arch3m && !arm_arch6" "umull%?\\t%3, %0, %2, %1" @@ -46769,7 +35169,7 @@ (set_attr "predicable" "yes")] ) -@@ -1753,8 +2180,9 @@ +@@ -1753,8 +2172,9 @@ (clobber (match_scratch:SI 3 "=r"))] "TARGET_32BIT && arm_arch6" "umull%?\\t%3, %0, %2, %1" @@ -46781,7 +35181,7 @@ ) (define_insn "mulhisi3" -@@ -1765,7 +2193,7 @@ +@@ -1765,7 +2185,7 @@ (match_operand:HI 2 "s_register_operand" "r"))))] "TARGET_DSP_MULTIPLY" "smulbb%?\\t%0, %1, %2" @@ -46790,7 +35190,7 @@ (set_attr "predicable" "yes")] ) -@@ -1778,8 +2206,9 @@ +@@ -1778,8 +2198,9 @@ (match_operand:HI 2 "s_register_operand" "r"))))] "TARGET_DSP_MULTIPLY" "smultb%?\\t%0, %1, %2" @@ -46802,7 +35202,7 @@ ) (define_insn "*mulhisi3bt" -@@ -1791,8 +2220,9 @@ +@@ -1791,8 +2212,9 @@ (const_int 16))))] "TARGET_DSP_MULTIPLY" "smulbt%?\\t%0, %1, %2" @@ -46814,7 +35214,7 @@ ) (define_insn "*mulhisi3tt" -@@ -1805,8 +2235,9 @@ +@@ -1805,8 +2227,9 @@ (const_int 16))))] "TARGET_DSP_MULTIPLY" "smultt%?\\t%0, %1, %2" @@ -46826,7 +35226,7 @@ ) (define_insn "maddhisi4" -@@ -1818,8 +2249,9 @@ +@@ -1818,8 +2241,9 @@ (match_operand:SI 3 "s_register_operand" "r")))] "TARGET_DSP_MULTIPLY" "smlabb%?\\t%0, %1, %2, %3" @@ -46838,7 +35238,7 @@ ) ;; Note: there is no maddhisi4ibt because this one is canonical form -@@ -1833,8 +2265,9 @@ +@@ -1833,8 +2257,9 @@ (match_operand:SI 3 "s_register_operand" "r")))] "TARGET_DSP_MULTIPLY" "smlatb%?\\t%0, %1, %2, %3" @@ -46850,7 +35250,7 @@ ) (define_insn "*maddhisi4tt" -@@ -1848,8 +2281,9 @@ +@@ -1848,22 +2273,24 @@ (match_operand:SI 3 "s_register_operand" "r")))] "TARGET_DSP_MULTIPLY" "smlatt%?\\t%0, %1, %2, %3" @@ -46862,7 +35262,6 @@ ) (define_insn "maddhidi4" -@@ -1856,14 +2290,15 @@ [(set (match_operand:DI 0 "s_register_operand" "=r") (plus:DI (mult:DI (sign_extend:DI @@ -46881,7 +35280,7 @@ ;; Note: there is no maddhidi4ibt because this one is canonical form (define_insn "*maddhidi4tb" -@@ -1878,8 +2313,9 @@ +@@ -1878,8 +2305,9 @@ (match_operand:DI 3 "s_register_operand" "0")))] "TARGET_DSP_MULTIPLY" "smlaltb%?\\t%Q0, %R0, %1, %2" @@ -46893,7 +35292,7 @@ (define_insn "*maddhidi4tt" [(set (match_operand:DI 0 "s_register_operand" "=r") -@@ -1895,8 +2331,9 @@ +@@ -1895,8 +2323,9 @@ (match_operand:DI 3 "s_register_operand" "0")))] "TARGET_DSP_MULTIPLY" "smlaltt%?\\t%Q0, %R0, %1, %2" @@ -46905,7 +35304,7 @@ (define_expand "mulsf3" [(set (match_operand:SF 0 "s_register_operand" "") -@@ -2024,13 +2461,49 @@ +@@ -2024,13 +2453,49 @@ "" ) @@ -46962,7 +35361,7 @@ ) (define_insn_and_split "*anddi_zesidi_di" -@@ -2145,12 +2618,13 @@ +@@ -2145,12 +2610,13 @@ ; ??? Check split length for Thumb-2 (define_insn_and_split "*arm_andsi3_insn" @@ -46979,7 +35378,7 @@ bic%?\\t%0, %1, #%B2 and%?\\t%0, %1, %2 #" -@@ -2164,9 +2638,11 @@ +@@ -2164,9 +2630,11 @@ INTVAL (operands[2]), operands[0], operands[1], 0); DONE; " @@ -46993,7 +35392,7 @@ ) (define_insn "*thumb1_andsi3_insn" -@@ -2176,7 +2652,7 @@ +@@ -2176,7 +2644,7 @@ "TARGET_THUMB1" "and\\t%0, %2" [(set_attr "length" "2") @@ -47002,7 +35401,7 @@ (set_attr "conds" "set")]) (define_insn "*andsi3_compare0" -@@ -2193,7 +2669,7 @@ +@@ -2193,7 +2661,7 @@ bic%.\\t%0, %1, #%B2 and%.\\t%0, %1, %2" [(set_attr "conds" "set") @@ -47011,7 +35410,7 @@ ) (define_insn "*andsi3_compare0_scratch" -@@ -2209,7 +2685,7 @@ +@@ -2209,14 +2677,14 @@ bic%.\\t%2, %0, #%B1 tst%?\\t%0, %1" [(set_attr "conds" "set") @@ -47020,7 +35419,6 @@ ) (define_insn "*zeroextractsi_compare0_scratch" -@@ -2216,7 +2692,7 @@ [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (zero_extract:SI (match_operand:SI 0 "s_register_operand" "r") @@ -47029,7 +35427,7 @@ (match_operand 2 "const_int_operand" "n")) (const_int 0)))] "TARGET_32BIT -@@ -2232,7 +2708,8 @@ +@@ -2232,7 +2700,8 @@ " [(set_attr "conds" "set") (set_attr "predicable" "yes") @@ -47039,7 +35437,7 @@ ) (define_insn_and_split "*ne_zeroextractsi" -@@ -2659,7 +3136,8 @@ +@@ -2659,7 +3128,8 @@ "arm_arch_thumb2" "bfc%?\t%0, %2, %1" [(set_attr "length" "4") @@ -47049,7 +35447,7 @@ ) (define_insn "insv_t2" -@@ -2670,7 +3148,8 @@ +@@ -2670,7 +3140,8 @@ "arm_arch_thumb2" "bfi%?\t%0, %3, %2, %1" [(set_attr "length" "4") @@ -47059,7 +35457,7 @@ ) ; constants for op 2 will never be given to these patterns. -@@ -2697,7 +3176,7 @@ +@@ -2697,7 +3168,7 @@ [(set_attr "length" "8") (set_attr "predicable" "yes")] ) @@ -47068,7 +35466,7 @@ (define_insn_and_split "*anddi_notzesidi_di" [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (and:DI (not:DI (zero_extend:DI -@@ -2722,9 +3201,10 @@ +@@ -2722,9 +3193,10 @@ operands[1] = gen_lowpart (SImode, operands[1]); }" [(set_attr "length" "4,8") @@ -47081,7 +35479,7 @@ (define_insn_and_split "*anddi_notsesidi_di" [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (and:DI (not:DI (sign_extend:DI -@@ -2745,9 +3225,10 @@ +@@ -2745,16 +3217,18 @@ operands[1] = gen_lowpart (SImode, operands[1]); }" [(set_attr "length" "8") @@ -47094,7 +35492,6 @@ (define_insn "andsi_notsi_si" [(set (match_operand:SI 0 "s_register_operand" "=r") (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) -@@ -2754,7 +3235,8 @@ (match_operand:SI 1 "s_register_operand" "r")))] "TARGET_32BIT" "bic%?\\t%0, %1, %2" @@ -47104,7 +35501,7 @@ ) (define_insn "thumb1_bicsi3" -@@ -2777,8 +3259,8 @@ +@@ -2777,8 +3251,8 @@ [(set_attr "predicable" "yes") (set_attr "shift" "2") (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") @@ -47115,7 +35512,7 @@ ) (define_insn "*andsi_notsi_si_compare0" -@@ -2814,14 +3296,47 @@ +@@ -2814,14 +3288,47 @@ "" ) @@ -47171,7 +35568,7 @@ ) (define_insn "*iordi_zesidi_di" -@@ -2834,7 +3349,8 @@ +@@ -2834,7 +3341,8 @@ orr%?\\t%Q0, %Q1, %2 #" [(set_attr "length" "4,8") @@ -47181,7 +35578,7 @@ ) (define_insn "*iordi_sesidi_di" -@@ -2879,12 +3395,13 @@ +@@ -2879,12 +3387,13 @@ ) (define_insn_and_split "*iorsi3_insn" @@ -47198,7 +35595,7 @@ orn%?\\t%0, %1, #%B2 orr%?\\t%0, %1, %2 #" -@@ -2894,14 +3411,15 @@ +@@ -2894,14 +3403,15 @@ || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))" [(clobber (const_int 0))] { @@ -47218,7 +35615,7 @@ ) (define_insn "*thumb1_iorsi3_insn" -@@ -2936,7 +3454,7 @@ +@@ -2936,7 +3446,7 @@ "TARGET_32BIT" "orr%.\\t%0, %1, %2" [(set_attr "conds" "set") @@ -47227,7 +35624,7 @@ ) (define_insn "*iorsi3_compare0_scratch" -@@ -2948,25 +3466,55 @@ +@@ -2948,25 +3458,55 @@ "TARGET_32BIT" "orr%.\\t%0, %1, %2" [(set_attr "conds" "set") @@ -47293,7 +35690,7 @@ ) (define_insn "*xordi_zesidi_di" -@@ -2979,7 +3527,8 @@ +@@ -2979,7 +3519,8 @@ eor%?\\t%Q0, %Q1, %2 #" [(set_attr "length" "4,8") @@ -47303,7 +35700,7 @@ ) (define_insn "*xordi_sesidi_di" -@@ -3022,13 +3571,14 @@ +@@ -3022,13 +3563,14 @@ ) (define_insn_and_split "*arm_xorsi3" @@ -47321,7 +35718,7 @@ #" "TARGET_32BIT && CONST_INT_P (operands[2]) -@@ -3039,9 +3589,10 @@ +@@ -3039,9 +3581,10 @@ INTVAL (operands[2]), operands[0], operands[1], 0); DONE; } @@ -47334,7 +35731,7 @@ ) (define_insn "*thumb1_xorsi3_insn" -@@ -3052,7 +3603,7 @@ +@@ -3052,7 +3595,7 @@ "eor\\t%0, %2" [(set_attr "length" "2") (set_attr "conds" "set") @@ -47343,7 +35740,7 @@ ) (define_insn "*xorsi3_compare0" -@@ -3065,7 +3616,7 @@ +@@ -3065,7 +3608,7 @@ "TARGET_32BIT" "eor%.\\t%0, %1, %2" [(set_attr "conds" "set") @@ -47352,7 +35749,7 @@ ) (define_insn "*xorsi3_compare0_scratch" -@@ -3076,7 +3627,7 @@ +@@ -3076,7 +3619,7 @@ "TARGET_32BIT" "teq%?\\t%0, %1" [(set_attr "conds" "set") @@ -47361,7 +35758,7 @@ ) ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), -@@ -3096,16 +3647,21 @@ +@@ -3096,16 +3639,21 @@ "" ) @@ -47386,7 +35783,7 @@ ) ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield -@@ -3241,7 +3797,8 @@ +@@ -3241,7 +3789,8 @@ (const_int 0)))] "TARGET_32BIT" "bic%?\\t%0, %1, %1, asr #31" @@ -47396,7 +35793,7 @@ ) (define_insn "*smax_m1" -@@ -3250,18 +3807,27 @@ +@@ -3250,18 +3799,27 @@ (const_int -1)))] "TARGET_32BIT" "orr%?\\t%0, %1, %1, asr #31" @@ -47429,7 +35826,7 @@ [(set_attr "conds" "clob") (set_attr "length" "8,12")] ) -@@ -3290,18 +3856,27 @@ +@@ -3290,18 +3848,27 @@ (const_int 0)))] "TARGET_32BIT" "and%?\\t%0, %1, %1, asr #31" @@ -47462,7 +35859,7 @@ [(set_attr "conds" "clob") (set_attr "length" "8,12")] ) -@@ -3316,16 +3891,24 @@ +@@ -3316,16 +3883,24 @@ "" ) @@ -47492,7 +35889,7 @@ [(set_attr "conds" "clob") (set_attr "length" "8,8,12")] ) -@@ -3340,16 +3923,24 @@ +@@ -3340,16 +3915,24 @@ "" ) @@ -47522,7 +35919,7 @@ [(set_attr "conds" "clob") (set_attr "length" "8,8,12")] ) -@@ -3360,7 +3951,7 @@ +@@ -3360,7 +3943,7 @@ [(match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "s_register_operand" "r")])) (clobber (reg:CC CC_REGNUM))] @@ -47531,7 +35928,7 @@ "* operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode, operands[1], operands[2]); -@@ -3389,7 +3980,7 @@ +@@ -3389,7 +3972,7 @@ (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) (match_operand:SI 1 "s_register_operand" "0,?r")])) (clobber (reg:CC CC_REGNUM))] @@ -47540,7 +35937,7 @@ "* { enum rtx_code code = GET_CODE (operands[4]); -@@ -3423,6 +4014,54 @@ +@@ -3423,6 +4006,54 @@ (const_int 12)))] ) @@ -47595,7 +35992,7 @@ (define_code_iterator SAT [smin smax]) (define_code_iterator SATrev [smin smax]) (define_code_attr SATlo [(smin "1") (smax "2")]) -@@ -3449,7 +4088,8 @@ +@@ -3449,7 +4080,8 @@ return "usat%?\t%0, %1, %3"; } [(set_attr "predicable" "yes") @@ -47605,7 +36002,7 @@ (define_insn "*satsi__shift" [(set (match_operand:SI 0 "s_register_operand" "=r") -@@ -3474,9 +4114,9 @@ +@@ -3474,9 +4106,9 @@ return "usat%?\t%0, %1, %4%S3"; } [(set_attr "predicable" "yes") @@ -47617,7 +36014,7 @@ ;; Shift and rotation insns -@@ -3566,6 +4206,7 @@ +@@ -3566,6 +4198,7 @@ "TARGET_THUMB1" "lsl\\t%0, %1, %2" [(set_attr "length" "2") @@ -47625,7 +36022,7 @@ (set_attr "conds" "set")]) (define_expand "ashrdi3" -@@ -3623,7 +4264,6 @@ +@@ -3623,7 +4256,6 @@ "TARGET_32BIT" "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx" [(set_attr "conds" "clob") @@ -47633,7 +36030,7 @@ (set_attr "length" "8")] ) -@@ -3646,6 +4286,7 @@ +@@ -3646,6 +4278,7 @@ "TARGET_THUMB1" "asr\\t%0, %1, %2" [(set_attr "length" "2") @@ -47641,7 +36038,7 @@ (set_attr "conds" "set")]) (define_expand "lshrdi3" -@@ -3703,7 +4344,6 @@ +@@ -3703,7 +4336,6 @@ "TARGET_32BIT" "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx" [(set_attr "conds" "clob") @@ -47649,7 +36046,7 @@ (set_attr "length" "8")] ) -@@ -3729,6 +4369,7 @@ +@@ -3729,6 +4361,7 @@ "TARGET_THUMB1" "lsr\\t%0, %1, %2" [(set_attr "length" "2") @@ -47657,7 +36054,7 @@ (set_attr "conds" "set")]) (define_expand "rotlsi3" -@@ -3774,51 +4415,52 @@ +@@ -3774,51 +4407,52 @@ (match_operand:SI 2 "register_operand" "l")))] "TARGET_THUMB1" "ror\\t%0, %0, %2" @@ -47727,7 +36124,7 @@ ) (define_insn "*not_shiftsi" -@@ -3829,10 +4471,10 @@ +@@ -3829,10 +4463,10 @@ "TARGET_32BIT" "mvn%?\\t%0, %1%S3" [(set_attr "predicable" "yes") @@ -47740,7 +36137,7 @@ (define_insn "*not_shiftsi_compare0" [(set (reg:CC_NOOV CC_REGNUM) -@@ -3847,9 +4489,8 @@ +@@ -3847,9 +4481,8 @@ "mvn%.\\t%0, %1%S3" [(set_attr "conds" "set") (set_attr "shift" "1") @@ -47751,7 +36148,7 @@ (define_insn "*not_shiftsi_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) -@@ -3863,9 +4504,8 @@ +@@ -3863,9 +4496,8 @@ "mvn%.\\t%0, %1%S3" [(set_attr "conds" "set") (set_attr "shift" "1") @@ -47762,7 +36159,7 @@ ;; We don't really have extzv, but defining this using shifts helps ;; to reduce register pressure later on. -@@ -4042,6 +4682,7 @@ +@@ -4042,6 +4674,7 @@ [(set_attr "arch" "t2,any") (set_attr "length" "2,4") (set_attr "predicable" "yes") @@ -47770,7 +36167,7 @@ (set_attr "type" "load1")]) (define_insn "unaligned_loadhis" -@@ -4054,6 +4695,7 @@ +@@ -4054,6 +4687,7 @@ [(set_attr "arch" "t2,any") (set_attr "length" "2,4") (set_attr "predicable" "yes") @@ -47778,7 +36175,7 @@ (set_attr "type" "load_byte")]) (define_insn "unaligned_loadhiu" -@@ -4066,6 +4708,7 @@ +@@ -4066,6 +4700,7 @@ [(set_attr "arch" "t2,any") (set_attr "length" "2,4") (set_attr "predicable" "yes") @@ -47786,7 +36183,7 @@ (set_attr "type" "load_byte")]) (define_insn "unaligned_storesi" -@@ -4077,6 +4720,7 @@ +@@ -4077,6 +4712,7 @@ [(set_attr "arch" "t2,any") (set_attr "length" "2,4") (set_attr "predicable" "yes") @@ -47794,7 +36191,7 @@ (set_attr "type" "store1")]) (define_insn "unaligned_storehi" -@@ -4088,8 +4732,67 @@ +@@ -4088,8 +4724,67 @@ [(set_attr "arch" "t2,any") (set_attr "length" "2,4") (set_attr "predicable" "yes") @@ -47862,7 +36259,7 @@ (define_insn "*extv_reg" [(set (match_operand:SI 0 "s_register_operand" "=r") (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") -@@ -4098,7 +4801,8 @@ +@@ -4098,7 +4793,8 @@ "arm_arch_thumb2" "sbfx%?\t%0, %1, %3, %2" [(set_attr "length" "4") @@ -47872,7 +36269,7 @@ ) (define_insn "extzv_t2" -@@ -4109,7 +4813,8 @@ +@@ -4109,7 +4805,8 @@ "arm_arch_thumb2" "ubfx%?\t%0, %1, %3, %2" [(set_attr "length" "4") @@ -47882,7 +36279,7 @@ ) -@@ -4121,7 +4826,8 @@ +@@ -4121,7 +4818,8 @@ "TARGET_IDIV" "sdiv%?\t%0, %1, %2" [(set_attr "predicable" "yes") @@ -47892,7 +36289,7 @@ ) (define_insn "udivsi3" -@@ -4131,7 +4837,8 @@ +@@ -4131,7 +4829,8 @@ "TARGET_IDIV" "udiv%?\t%0, %1, %2" [(set_attr "predicable" "yes") @@ -47902,7 +36299,7 @@ ) -@@ -4154,12 +4861,24 @@ +@@ -4154,12 +4853,24 @@ ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). ;; The first alternative allows the common case of a *full* overlap. @@ -47929,7 +36326,7 @@ [(set_attr "conds" "clob") (set_attr "length" "8")] ) -@@ -4181,11 +4900,14 @@ +@@ -4181,11 +4892,14 @@ ) (define_insn "*arm_negsi2" @@ -47947,7 +36344,7 @@ ) (define_insn "*thumb1_negsi2" -@@ -4227,14 +4949,67 @@ +@@ -4227,14 +4941,67 @@ operands[2] = gen_rtx_REG (CCmode, CC_REGNUM); ") @@ -48019,7 +36416,7 @@ [(set_attr "conds" "clob,*") (set_attr "shift" "1") (set_attr "predicable" "no, yes") -@@ -4255,14 +5030,56 @@ +@@ -4255,14 +5022,56 @@ [(set_attr "length" "6")] ) @@ -48080,7 +36477,7 @@ [(set_attr "conds" "clob,*") (set_attr "shift" "1") (set_attr "predicable" "no, yes") -@@ -4330,7 +5147,7 @@ +@@ -4330,7 +5139,7 @@ [(set_attr "length" "*,8,8,*") (set_attr "predicable" "no,yes,yes,no") (set_attr "neon_type" "neon_int_1,*,*,neon_int_1") @@ -48089,7 +36486,7 @@ ) (define_expand "one_cmplsi2" -@@ -4341,12 +5158,15 @@ +@@ -4341,12 +5150,15 @@ ) (define_insn "*arm_one_cmplsi2" @@ -48108,7 +36505,7 @@ ) (define_insn "*thumb1_one_cmplsi2" -@@ -4355,7 +5175,7 @@ +@@ -4355,7 +5167,7 @@ "TARGET_THUMB1" "mvn\\t%0, %1" [(set_attr "length" "2") @@ -48117,7 +36514,7 @@ ) (define_insn "*notsi_compare0" -@@ -4367,7 +5187,7 @@ +@@ -4367,7 +5179,7 @@ "TARGET_32BIT" "mvn%.\\t%0, %1" [(set_attr "conds" "set") @@ -48126,7 +36523,7 @@ ) (define_insn "*notsi_compare0_scratch" -@@ -4378,7 +5198,7 @@ +@@ -4378,7 +5190,7 @@ "TARGET_32BIT" "mvn%.\\t%0, %1" [(set_attr "conds" "set") @@ -48135,7 +36532,7 @@ ) ;; Fixed <--> Floating conversion insns -@@ -4498,7 +5318,7 @@ +@@ -4498,7 +5310,7 @@ "TARGET_32BIT " "#" [(set_attr "length" "8,4,8,8") @@ -48144,7 +36541,7 @@ (set_attr "ce_count" "2") (set_attr "predicable" "yes")] ) -@@ -4513,7 +5333,7 @@ +@@ -4513,7 +5325,7 @@ (set_attr "ce_count" "2") (set_attr "shift" "1") (set_attr "predicable" "yes") @@ -48153,7 +36550,7 @@ ) ;; Splits for all extensions to DImode -@@ -4639,7 +5459,7 @@ +@@ -4639,7 +5451,7 @@ [(if_then_else (eq_attr "is_arch6" "yes") (const_int 2) (const_int 4)) (const_int 4)]) @@ -48162,7 +36559,7 @@ ) (define_insn "*arm_zero_extendhisi2" -@@ -4649,7 +5469,7 @@ +@@ -4649,7 +5461,7 @@ "@ # ldr%(h%)\\t%0, %1" @@ -48171,7 +36568,7 @@ (set_attr "predicable" "yes")] ) -@@ -4661,7 +5481,7 @@ +@@ -4661,7 +5473,7 @@ uxth%?\\t%0, %1 ldr%(h%)\\t%0, %1" [(set_attr "predicable" "yes") @@ -48180,7 +36577,7 @@ ) (define_insn "*arm_zero_extendhisi2addsi" -@@ -4670,8 +5490,9 @@ +@@ -4670,8 +5482,9 @@ (match_operand:SI 2 "s_register_operand" "r")))] "TARGET_INT_SIMD" "uxtah%?\\t%0, %2, %1" @@ -48192,7 +36589,7 @@ ) (define_expand "zero_extendqisi2" -@@ -4719,7 +5540,7 @@ +@@ -4719,7 +5532,7 @@ # ldrb\\t%0, %1" [(set_attr "length" "4,2") @@ -48201,7 +36598,7 @@ (set_attr "pool_range" "*,32")] ) -@@ -4731,7 +5552,7 @@ +@@ -4731,7 +5544,7 @@ uxtb\\t%0, %1 ldrb\\t%0, %1" [(set_attr "length" "2") @@ -48210,7 +36607,7 @@ ) (define_insn "*arm_zero_extendqisi2" -@@ -4742,7 +5563,7 @@ +@@ -4742,7 +5555,7 @@ # ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2" [(set_attr "length" "8,4") @@ -48219,7 +36616,7 @@ (set_attr "predicable" "yes")] ) -@@ -4753,7 +5574,7 @@ +@@ -4753,7 +5566,7 @@ "@ uxtb%(%)\\t%0, %1 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2" @@ -48228,7 +36625,7 @@ (set_attr "predicable" "yes")] ) -@@ -4764,8 +5585,8 @@ +@@ -4764,8 +5577,8 @@ "TARGET_INT_SIMD" "uxtab%?\\t%0, %2, %1" [(set_attr "predicable" "yes") @@ -48239,7 +36636,7 @@ ) (define_split -@@ -4816,7 +5637,8 @@ +@@ -4816,7 +5629,8 @@ "TARGET_32BIT" "tst%?\\t%0, #255" [(set_attr "conds" "set") @@ -48249,7 +36646,7 @@ ) (define_expand "extendhisi2" -@@ -4927,7 +5749,7 @@ +@@ -4927,7 +5741,7 @@ [(if_then_else (eq_attr "is_arch6" "yes") (const_int 2) (const_int 4)) (const_int 4)]) @@ -48258,7 +36655,7 @@ (set_attr "pool_range" "*,1018")] ) -@@ -4986,7 +5808,7 @@ +@@ -4986,7 +5800,7 @@ # ldr%(sh%)\\t%0, %1" [(set_attr "length" "8,4") @@ -48267,7 +36664,7 @@ (set_attr "predicable" "yes") (set_attr "pool_range" "*,256") (set_attr "neg_pool_range" "*,244")] -@@ -5000,8 +5822,9 @@ +@@ -5000,8 +5814,9 @@ "@ sxth%?\\t%0, %1 ldr%(sh%)\\t%0, %1" @@ -48278,7 +36675,7 @@ (set_attr "pool_range" "*,256") (set_attr "neg_pool_range" "*,244")] ) -@@ -5086,7 +5909,7 @@ +@@ -5086,7 +5901,7 @@ # ldr%(sb%)\\t%0, %1" [(set_attr "length" "8,4") @@ -48287,7 +36684,7 @@ (set_attr "predicable" "yes") (set_attr "pool_range" "*,256") (set_attr "neg_pool_range" "*,244")] -@@ -5100,7 +5923,7 @@ +@@ -5100,7 +5915,7 @@ "@ sxtb%?\\t%0, %1 ldr%(sb%)\\t%0, %1" @@ -48296,7 +36693,7 @@ (set_attr "predicable" "yes") (set_attr "pool_range" "*,256") (set_attr "neg_pool_range" "*,244")] -@@ -5112,9 +5935,9 @@ +@@ -5112,9 +5927,9 @@ (match_operand:SI 2 "s_register_operand" "r")))] "TARGET_INT_SIMD" "sxtab%?\\t%0, %2, %1" @@ -48309,7 +36706,7 @@ ) (define_split -@@ -5213,7 +6036,7 @@ +@@ -5213,7 +6028,7 @@ (const_int 2) (if_then_else (eq_attr "is_arch6" "yes") (const_int 4) (const_int 6))]) @@ -48318,7 +36715,7 @@ ) (define_expand "extendsfdf2" -@@ -5313,8 +6136,8 @@ +@@ -5313,8 +6128,8 @@ ) (define_insn "*arm_movdi" @@ -48329,7 +36726,7 @@ "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP) && !TARGET_IWMMXT -@@ -5472,8 +6295,7 @@ +@@ -5472,8 +6287,7 @@ } }" [(set_attr "length" "4,4,6,2,2,6,4,4") @@ -48339,7 +36736,7 @@ (set_attr "pool_range" "*,*,*,*,*,1018,*,*")] ) -@@ -5570,6 +6392,7 @@ +@@ -5570,6 +6384,7 @@ "arm_arch_thumb2" "movt%?\t%0, #:upper16:%c2" [(set_attr "predicable" "yes") @@ -48347,7 +36744,7 @@ (set_attr "length" "4")] ) -@@ -5587,8 +6410,7 @@ +@@ -5587,8 +6402,7 @@ movw%?\\t%0, %1 ldr%?\\t%0, %1 str%?\\t%1, %0" @@ -48357,7 +36754,7 @@ (set_attr "predicable" "yes") (set_attr "pool_range" "*,*,*,*,4096,*") (set_attr "neg_pool_range" "*,*,*,*,4084,*")] -@@ -5890,7 +6712,7 @@ +@@ -5890,7 +6704,7 @@ cmp%?\\t%0, #0 sub%.\\t%0, %1, #0" [(set_attr "conds" "set") @@ -48366,7 +36763,7 @@ ) ;; Subroutine to store a half word from a register into memory. -@@ -6304,14 +7126,13 @@ +@@ -6304,14 +7118,13 @@ str%(h%)\\t%1, %0\\t%@ movhi ldr%(h%)\\t%0, %1\\t%@ movhi" [(set_attr "predicable" "yes") @@ -48384,7 +36781,7 @@ (const_string "store1") (const_string "load1")])] ) -@@ -6325,8 +7146,7 @@ +@@ -6325,8 +7138,7 @@ mov%?\\t%0, %1\\t%@ movhi mvn%?\\t%0, #%B1\\t%@ movhi" [(set_attr "predicable" "yes") @@ -48394,7 +36791,7 @@ ) (define_expand "thumb_movhi_clobber" -@@ -6449,10 +7269,9 @@ +@@ -6449,26 +7261,27 @@ " ) @@ -48407,7 +36804,6 @@ "TARGET_32BIT && ( register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" -@@ -6459,16 +7278,18 @@ "@ mov%?\\t%0, %1 mov%?\\t%0, %1 @@ -48430,7 +36826,7 @@ ) (define_insn "*thumb1_movqi_insn" -@@ -6485,8 +7306,7 @@ +@@ -6485,8 +7298,7 @@ mov\\t%0, %1 mov\\t%0, %1" [(set_attr "length" "2") @@ -48440,7 +36836,7 @@ (set_attr "pool_range" "*,32,*,*,*,*") (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")]) -@@ -6515,7 +7335,7 @@ +@@ -6515,7 +7327,7 @@ (define_insn "*arm32_movhf" [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r") (match_operand:HF 1 "general_operand" " m,r,r,F"))] @@ -48449,7 +36845,7 @@ && ( s_register_operand (operands[0], HFmode) || s_register_operand (operands[1], HFmode))" "* -@@ -6551,8 +7371,7 @@ +@@ -6551,8 +7363,7 @@ } " [(set_attr "conds" "unconditional") @@ -48459,7 +36855,7 @@ (set_attr "length" "4,4,4,8") (set_attr "predicable" "yes")] ) -@@ -6587,8 +7406,7 @@ +@@ -6587,8 +7398,7 @@ } " [(set_attr "length" "2") @@ -48469,7 +36865,7 @@ (set_attr "pool_range" "*,1018,*,*,*") (set_attr "conds" "clob,nocond,nocond,nocond,nocond")]) -@@ -6642,8 +7460,8 @@ +@@ -6642,8 +7452,8 @@ ldr%?\\t%0, %1\\t%@ float str%?\\t%1, %0\\t%@ float" [(set_attr "predicable" "yes") @@ -48480,7 +36876,7 @@ (set_attr "arm_pool_range" "*,4096,*") (set_attr "thumb2_pool_range" "*,4094,*") (set_attr "arm_neg_pool_range" "*,4084,*") -@@ -6666,9 +7484,8 @@ +@@ -6666,9 +7476,8 @@ mov\\t%0, %1 mov\\t%0, %1" [(set_attr "length" "2") @@ -48491,7 +36887,7 @@ (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")] ) -@@ -6738,8 +7555,8 @@ +@@ -6738,8 +7547,8 @@ ) (define_insn "*movdf_soft_insn" @@ -48502,7 +36898,7 @@ "TARGET_32BIT && TARGET_SOFT_FLOAT && ( register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" -@@ -6799,8 +7616,7 @@ +@@ -6799,8 +7608,7 @@ } " [(set_attr "length" "4,2,2,6,4,4") @@ -48512,7 +36908,7 @@ (set_attr "pool_range" "*,*,*,1018,*,*")] ) -@@ -6869,10 +7685,18 @@ +@@ -6869,10 +7677,18 @@ (match_operand:BLK 1 "general_operand" "") (match_operand:SI 2 "const_int_operand" "") (match_operand:SI 3 "const_int_operand" "")] @@ -48532,7 +36928,7 @@ if (arm_gen_movmemqi (operands)) DONE; FAIL; -@@ -7568,7 +8392,7 @@ +@@ -7568,7 +8384,7 @@ (set_attr "arch" "t2,t2,any,any") (set_attr "length" "2,2,4,4") (set_attr "predicable" "yes") @@ -48541,7 +36937,7 @@ ) (define_insn "*cmpsi_shiftsi" -@@ -7582,7 +8406,7 @@ +@@ -7582,7 +8398,7 @@ [(set_attr "conds" "set") (set_attr "shift" "1") (set_attr "arch" "32,a") @@ -48550,7 +36946,7 @@ (define_insn "*cmpsi_shiftsi_swp" [(set (reg:CC_SWP CC_REGNUM) -@@ -7595,7 +8419,7 @@ +@@ -7595,7 +8411,7 @@ [(set_attr "conds" "set") (set_attr "shift" "1") (set_attr "arch" "32,a") @@ -48559,7 +36955,7 @@ (define_insn "*arm_cmpsi_negshiftsi_si" [(set (reg:CC_Z CC_REGNUM) -@@ -7608,8 +8432,8 @@ +@@ -7608,8 +8424,8 @@ "cmn%?\\t%0, %2%S1" [(set_attr "conds" "set") (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") @@ -48570,7 +36966,7 @@ (set_attr "predicable" "yes")] ) -@@ -7617,25 +8441,69 @@ +@@ -7617,25 +8433,69 @@ ;; if-conversion can not reduce to a conditional compare, so we do ;; that directly. @@ -48647,7 +37043,7 @@ ) (define_insn "*arm_cmpdi_zero" -@@ -7758,36 +8626,56 @@ +@@ -7758,36 +8618,56 @@ operands[3] = const0_rtx;" ) @@ -48713,7 +37109,7 @@ (set_attr "length" "8")] ) -@@ -8069,7 +8957,7 @@ +@@ -8069,7 +8949,7 @@ (define_expand "movsfcc" [(set (match_operand:SF 0 "s_register_operand" "") @@ -48722,7 +37118,7 @@ (match_operand:SF 2 "s_register_operand" "") (match_operand:SF 3 "s_register_operand" "")))] "TARGET_32BIT && TARGET_HARD_FLOAT" -@@ -8091,7 +8979,7 @@ +@@ -8091,7 +8971,7 @@ (define_expand "movdfcc" [(set (match_operand:DF 0 "s_register_operand" "") @@ -48731,7 +37127,7 @@ (match_operand:DF 2 "s_register_operand" "") (match_operand:DF 3 "s_register_operand" "")))] "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" -@@ -8110,7 +8998,40 @@ +@@ -8110,7 +8990,40 @@ }" ) @@ -48773,7 +37169,7 @@ [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") (if_then_else:SI (match_operator 3 "arm_comparison_operator" -@@ -8123,26 +9044,60 @@ +@@ -8123,26 +9036,60 @@ mvn%D3\\t%0, #%B2 mov%d3\\t%0, %1 mvn%d3\\t%0, #%B1 @@ -48849,7 +37245,7 @@ ) (define_insn "*movsfcc_soft_insn" -@@ -8156,7 +9111,7 @@ +@@ -8156,7 +9103,7 @@ mov%D3\\t%0, %2 mov%d3\\t%0, %1" [(set_attr "conds" "use") @@ -48858,7 +37254,7 @@ ) -@@ -8255,7 +9210,7 @@ +@@ -8255,7 +9202,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48867,7 +37263,7 @@ "blx%?\\t%0" [(set_attr "type" "call")] ) -@@ -8265,7 +9220,7 @@ +@@ -8265,7 +9212,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48876,7 +37272,7 @@ "* return output_call (operands); " -@@ -8284,7 +9239,7 @@ +@@ -8284,7 +9231,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48885,7 +37281,7 @@ "* return output_call_mem (operands); " -@@ -8297,7 +9252,7 @@ +@@ -8297,7 +9244,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48894,7 +37290,7 @@ "blx\\t%0" [(set_attr "length" "2") (set_attr "type" "call")] -@@ -8308,7 +9263,7 @@ +@@ -8308,7 +9255,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48903,7 +37299,7 @@ "* { if (!TARGET_CALLER_INTERWORKING) -@@ -8367,7 +9322,7 @@ +@@ -8367,7 +9314,7 @@ (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48912,7 +37308,7 @@ "blx%?\\t%1" [(set_attr "type" "call")] ) -@@ -8378,7 +9333,7 @@ +@@ -8378,7 +9325,7 @@ (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48921,7 +37317,7 @@ "* return output_call (&operands[1]); " -@@ -8394,7 +9349,8 @@ +@@ -8394,7 +9341,8 @@ (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] @@ -48931,7 +37327,7 @@ "* return output_call_mem (&operands[1]); " -@@ -8444,6 +9400,7 @@ +@@ -8444,6 +9392,7 @@ (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] "TARGET_32BIT @@ -48939,7 +37335,7 @@ && (GET_CODE (operands[0]) == SYMBOL_REF) && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" "* -@@ -8460,6 +9417,7 @@ +@@ -8460,6 +9409,7 @@ (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] "TARGET_32BIT @@ -48947,7 +37343,7 @@ && (GET_CODE (operands[1]) == SYMBOL_REF) && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" "* -@@ -8505,6 +9463,10 @@ +@@ -8505,6 +9455,10 @@ "TARGET_32BIT" " { @@ -48958,7 +37354,7 @@ if (operands[2] == NULL_RTX) operands[2] = const0_rtx; }" -@@ -8519,6 +9481,10 @@ +@@ -8519,47 +9473,67 @@ "TARGET_32BIT" " { @@ -48969,7 +37365,6 @@ if (operands[3] == NULL_RTX) operands[3] = const0_rtx; }" -@@ -8525,13 +9491,21 @@ ) (define_insn "*sibcall_insn" @@ -48994,7 +37389,6 @@ " [(set_attr "type" "call")] ) -@@ -8538,28 +9512,36 @@ (define_insn "*sibcall_value_insn" [(set (match_operand 0 "" "") @@ -49038,7 +37432,7 @@ DONE; } } -@@ -8584,13 +9566,13 @@ +@@ -8584,13 +9558,13 @@ (set_attr "predicable" "yes")] ) @@ -49055,7 +37449,7 @@ "* { if (arm_ccfsm_state == 2) -@@ -8598,7 +9580,8 @@ +@@ -8598,20 +9572,21 @@ arm_ccfsm_state += 2; return \"\"; } @@ -49065,7 +37459,6 @@ }" [(set_attr "conds" "use") (set_attr "length" "12") -@@ -8605,13 +9588,13 @@ (set_attr "type" "load1")] ) @@ -49082,7 +37475,7 @@ "* { if (arm_ccfsm_state == 2) -@@ -8619,7 +9602,8 @@ +@@ -8619,7 +9594,8 @@ arm_ccfsm_state += 2; return \"\"; } @@ -49092,7 +37485,7 @@ }" [(set_attr "conds" "use") (set_attr "length" "12") -@@ -8991,7 +9975,7 @@ +@@ -8991,7 +9967,7 @@ (if_then_else (match_operand:SI 3 "mult_operator" "") (const_string "no") (const_string "yes"))]) @@ -49101,7 +37494,7 @@ (define_split [(set (match_operand:SI 0 "s_register_operand" "") -@@ -9028,7 +10012,7 @@ +@@ -9028,7 +10004,7 @@ [(set_attr "conds" "set") (set_attr "shift" "4") (set_attr "arch" "32,a") @@ -49110,7 +37503,7 @@ (define_insn "*arith_shiftsi_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) -@@ -9045,7 +10029,7 @@ +@@ -9045,7 +10021,7 @@ [(set_attr "conds" "set") (set_attr "shift" "4") (set_attr "arch" "32,a") @@ -49119,7 +37512,7 @@ (define_insn "*sub_shiftsi" [(set (match_operand:SI 0 "s_register_operand" "=r,r") -@@ -9058,7 +10042,7 @@ +@@ -9058,7 +10034,7 @@ [(set_attr "predicable" "yes") (set_attr "shift" "3") (set_attr "arch" "32,a") @@ -49128,7 +37521,7 @@ (define_insn "*sub_shiftsi_compare0" [(set (reg:CC_NOOV CC_REGNUM) -@@ -9076,7 +10060,7 @@ +@@ -9076,7 +10052,7 @@ [(set_attr "conds" "set") (set_attr "shift" "3") (set_attr "arch" "32,a") @@ -49137,7 +37530,7 @@ (define_insn "*sub_shiftsi_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) -@@ -9092,30 +10076,67 @@ +@@ -9092,30 +10068,67 @@ [(set_attr "conds" "set") (set_attr "shift" "3") (set_attr "arch" "32,a") @@ -49217,7 +37610,7 @@ [(set_attr "conds" "use") (set_attr "length" "4,8")] ) -@@ -9144,6 +10165,16 @@ +@@ -9144,6 +10157,16 @@ (eq:SI (match_operand:SI 1 "s_register_operand" "") (const_int 0))) (clobber (reg:CC CC_REGNUM))] @@ -49234,7 +37627,7 @@ "TARGET_32BIT && reload_completed" [(parallel [(set (reg:CC CC_REGNUM) -@@ -9184,7 +10215,7 @@ +@@ -9184,7 +10207,7 @@ (set (match_dup 0) (const_int 1)))]) (define_insn_and_split "*compare_scc" @@ -49243,7 +37636,7 @@ (match_operator:SI 1 "arm_comparison_operator" [(match_operand:SI 2 "s_register_operand" "r,r") (match_operand:SI 3 "arm_add_operand" "rI,L")])) -@@ -9213,29 +10244,93 @@ +@@ -9213,29 +10236,93 @@ ;; Attempt to improve the sequence generated by the compare_scc splitters ;; not to use conditional execution. @@ -49347,7 +37740,7 @@ (define_insn "*cond_move" [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") -@@ -9262,7 +10357,7 @@ +@@ -9262,7 +10349,7 @@ return \"\"; " [(set_attr "conds" "use") @@ -49356,7 +37749,7 @@ (set_attr "length" "4,4,8")] ) -@@ -9636,7 +10731,7 @@ +@@ -9636,7 +10723,7 @@ ) (define_insn_and_split "*ior_scc_scc" @@ -49365,7 +37758,7 @@ (ior:SI (match_operator:SI 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "arm_add_operand" "rIL")]) -@@ -9674,7 +10769,7 @@ +@@ -9674,7 +10761,7 @@ [(match_operand:SI 4 "s_register_operand" "r") (match_operand:SI 5 "arm_add_operand" "rIL")])) (const_int 0))) @@ -49374,7 +37767,7 @@ (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] "TARGET_32BIT" -@@ -9692,7 +10787,7 @@ +@@ -9692,7 +10779,7 @@ (set_attr "length" "16")]) (define_insn_and_split "*and_scc_scc" @@ -49383,7 +37776,7 @@ (and:SI (match_operator:SI 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "arm_add_operand" "rIL")]) -@@ -9732,7 +10827,7 @@ +@@ -9732,7 +10819,7 @@ [(match_operand:SI 4 "s_register_operand" "r") (match_operand:SI 5 "arm_add_operand" "rIL")])) (const_int 0))) @@ -49392,7 +37785,7 @@ (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] "TARGET_32BIT" -@@ -9754,7 +10849,7 @@ +@@ -9754,7 +10841,7 @@ ;; need only zero the value if false (if true, then the value is already ;; correct). (define_insn_and_split "*and_scc_scc_nodom" @@ -49401,7 +37794,7 @@ (and:SI (match_operator:SI 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r,r,0") (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")]) -@@ -9822,7 +10917,7 @@ +@@ -9822,28 +10909,117 @@ "") ;; ??? The conditional patterns above need checking for Thumb-2 usefulness @@ -49410,7 +37803,6 @@ [(set (match_operand:SI 0 "s_register_operand" "=r") (neg:SI (match_operator 3 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "r") -@@ -9829,21 +10924,110 @@ (match_operand:SI 2 "arm_rhs_operand" "rI")]))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" @@ -49530,7 +37922,7 @@ (define_insn "movcond" [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") (if_then_else:SI -@@ -9944,9 +11128,9 @@ +@@ -9944,9 +11120,9 @@ (set_attr "length" "4,4,8,8") (set_attr_alternative "type" [(if_then_else (match_operand 3 "const_int_operand" "") @@ -49542,7 +37934,7 @@ (const_string "*") (const_string "*")])] ) -@@ -9986,9 +11170,9 @@ +@@ -9986,9 +11162,9 @@ (set_attr "length" "4,4,8,8") (set_attr_alternative "type" [(if_then_else (match_operand 3 "const_int_operand" "") @@ -49554,7 +37946,7 @@ (const_string "*") (const_string "*")])] ) -@@ -10174,7 +11358,7 @@ +@@ -10174,7 +11350,7 @@ mov%d4\\t%0, %1\;mvn%D4\\t%0, %2 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" [(set_attr "conds" "use") @@ -49563,7 +37955,7 @@ (set_attr "length" "4,8,8")] ) -@@ -10207,7 +11391,7 @@ +@@ -10207,7 +11383,7 @@ mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" [(set_attr "conds" "use") @@ -49572,7 +37964,7 @@ (set_attr "length" "4,8,8")] ) -@@ -10245,10 +11429,9 @@ +@@ -10245,10 +11421,9 @@ [(set_attr "conds" "use") (set_attr "shift" "2") (set_attr "length" "4,8,8") @@ -49585,7 +37977,7 @@ ) (define_insn "*ifcompare_move_shift" -@@ -10285,10 +11468,9 @@ +@@ -10285,10 +11460,9 @@ [(set_attr "conds" "use") (set_attr "shift" "2") (set_attr "length" "4,8,8") @@ -49598,7 +37990,7 @@ ) (define_insn "*ifcompare_shift_shift" -@@ -10326,12 +11508,11 @@ +@@ -10326,12 +11500,11 @@ [(set_attr "conds" "use") (set_attr "shift" "1") (set_attr "length" "8") @@ -49613,7 +38005,7 @@ ) (define_insn "*ifcompare_not_arith" -@@ -10363,7 +11544,7 @@ +@@ -10363,7 +11536,7 @@ "TARGET_ARM" "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3" [(set_attr "conds" "use") @@ -49622,7 +38014,7 @@ (set_attr "length" "8")] ) -@@ -10396,7 +11577,7 @@ +@@ -10396,7 +11569,7 @@ "TARGET_ARM" "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" [(set_attr "conds" "use") @@ -49631,7 +38023,7 @@ (set_attr "length" "8")] ) -@@ -10844,7 +12025,7 @@ +@@ -10844,7 +12017,7 @@ mvn%D4\\t%0, %2 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" [(set_attr "conds" "use") @@ -49640,7 +38032,7 @@ (set_attr "length" "4,8")] ) -@@ -11239,7 +12420,7 @@ +@@ -11239,7 +12412,7 @@ "TARGET_32BIT && arm_arch5" "clz%?\\t%0, %1" [(set_attr "predicable" "yes") @@ -49649,7 +38041,7 @@ (define_insn "rbitsi2" [(set (match_operand:SI 0 "s_register_operand" "=r") -@@ -11247,7 +12428,7 @@ +@@ -11247,7 +12420,7 @@ "TARGET_32BIT && arm_arch_thumb2" "rbit%?\\t%0, %1" [(set_attr "predicable" "yes") @@ -49658,7 +38050,7 @@ (define_expand "ctzsi2" [(set (match_operand:SI 0 "s_register_operand" "") -@@ -11282,6 +12463,7 @@ +@@ -11280,6 +12453,7 @@ (const_int 0)])] "TARGET_32BIT" "" @@ -49666,7 +38058,7 @@ ) (define_insn "force_register_use" -@@ -11401,7 +12583,8 @@ +@@ -11399,7 +12573,8 @@ "arm_arch_thumb2" "movt%?\t%0, %L1" [(set_attr "predicable" "yes") @@ -49676,7 +38068,7 @@ ) (define_insn "*arm_rev" -@@ -11552,7 +12735,8 @@ +@@ -11550,7 +12725,8 @@ false, true))" "ldrd%?\t%0, %3, [%1, %2]" [(set_attr "type" "load2") @@ -49686,7 +38078,7 @@ (define_insn "*thumb2_ldrd_base" [(set (match_operand:SI 0 "s_register_operand" "=r") -@@ -11566,7 +12750,8 @@ +@@ -11564,7 +12740,8 @@ operands[1], 0, false, true))" "ldrd%?\t%0, %2, [%1]" [(set_attr "type" "load2") @@ -49696,7 +38088,7 @@ (define_insn "*thumb2_ldrd_base_neg" [(set (match_operand:SI 0 "s_register_operand" "=r") -@@ -11580,7 +12765,8 @@ +@@ -11578,7 +12755,8 @@ operands[1], -4, false, true))" "ldrd%?\t%0, %2, [%1, #-4]" [(set_attr "type" "load2") @@ -49706,7 +38098,7 @@ (define_insn "*thumb2_strd" [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") -@@ -11597,7 +12783,8 @@ +@@ -11595,7 +12773,8 @@ false, false))" "strd%?\t%2, %4, [%0, %1]" [(set_attr "type" "store2") @@ -49716,7 +38108,7 @@ (define_insn "*thumb2_strd_base" [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk")) -@@ -11611,7 +12798,8 @@ +@@ -11609,7 +12788,8 @@ operands[0], 0, false, false))" "strd%?\t%1, %2, [%0]" [(set_attr "type" "store2") @@ -49726,7 +38118,7 @@ (define_insn "*thumb2_strd_base_neg" [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") -@@ -11625,9 +12813,24 @@ +@@ -11623,9 +12803,13 @@ operands[0], -4, false, false))" "strd%?\t%1, %2, [%0, #-4]" [(set_attr "type" "store2") @@ -49734,17 +38126,6 @@ + (set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no")]) -+;; ARMv8 CRC32 instructions. -+(define_insn "" -+ [(set (match_operand:SI 0 "s_register_operand" "=r") -+ (unspec:SI [(match_operand:SI 1 "s_register_operand" "r") -+ (match_operand: 2 "s_register_operand" "r")] -+ CRC))] -+ "TARGET_CRC32" -+ "\\t%0, %1, %2" -+ [(set_attr "type" "crc") -+ (set_attr "conds" "unconditional")] -+) +;; Load the load/store double peephole optimizations. +(include "ldrdstrd.md") @@ -49752,15 +38133,6 @@ ;; Load the load/store multiple patterns (include "ldmstm.md") -@@ -11661,6 +12864,8 @@ - (include "thumb2.md") - ;; Neon patterns - (include "neon.md") -+;; Crypto patterns -+(include "crypto.md") - ;; Synchronization Primitives - (include "sync.md") - ;; Fixed-point patterns --- a/src/gcc/config/arm/fmp626.md +++ b/src/gcc/config/arm/fmp626.md @@ -63,12 +63,15 @@ @@ -49808,95 +38180,6 @@ "fmp626_core*3") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ---- a/src/gcc/config/arm/crypto.md -+++ b/src/gcc/config/arm/crypto.md -@@ -0,0 +1,86 @@ -+;; ARMv8-A crypto patterns. -+;; Copyright (C) 2013-2014 Free Software Foundation, Inc. -+;; Contributed by ARM Ltd. -+ -+;; This file is part of GCC. -+ -+;; GCC is free software; you can redistribute it and/or modify it -+;; under the terms of the GNU General Public License as published -+;; by the Free Software Foundation; either version 3, or (at your -+;; option) any later version. -+ -+;; GCC is distributed in the hope that it will be useful, but WITHOUT -+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -+;; License for more details. -+ -+;; You should have received a copy of the GNU General Public License -+;; along with GCC; see the file COPYING3. If not see -+;; . -+ -+(define_insn "crypto_" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (unspec: [(match_operand: 1 -+ "register_operand" "w")] -+ CRYPTO_UNARY))] -+ "TARGET_CRYPTO" -+ ".\\t%q0, %q1" -+ [(set_attr "neon_type" "")] -+) -+ -+(define_insn "crypto_" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (unspec: [(match_operand: 1 "register_operand" "0") -+ (match_operand: 2 "register_operand" "w")] -+ CRYPTO_BINARY))] -+ "TARGET_CRYPTO" -+ ".\\t%q0, %q2" -+ [(set_attr "neon_type" "")] -+) -+ -+(define_insn "crypto_" -+ [(set (match_operand: 0 "register_operand" "=w") -+ (unspec: [(match_operand: 1 "register_operand" "0") -+ (match_operand: 2 "register_operand" "w") -+ (match_operand: 3 "register_operand" "w")] -+ CRYPTO_TERNARY))] -+ "TARGET_CRYPTO" -+ ".\\t%q0, %q2, %q3" -+ [(set_attr "neon_type" "")] -+) -+ -+(define_insn "crypto_sha1h" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (zero_extend:V4SI -+ (unspec:SI [(vec_select:SI -+ (match_operand:V4SI 1 "register_operand" "w") -+ (parallel [(match_operand:SI 2 "immediate_operand" "i")]))] -+ UNSPEC_SHA1H)))] -+ "TARGET_CRYPTO" -+ "sha1h.32\\t%q0, %q1" -+ [(set_attr "neon_type" "neon_crypto_sha1_fast")] -+) -+ -+(define_insn "crypto_vmullp64" -+ [(set (match_operand:TI 0 "register_operand" "=w") -+ (unspec:TI [(match_operand:DI 1 "register_operand" "w") -+ (match_operand:DI 2 "register_operand" "w")] -+ UNSPEC_VMULLP64))] -+ "TARGET_CRYPTO" -+ "vmull.p64\\t%q0, %P1, %P2" -+ [(set_attr "neon_type" "neon_mul_d_long")] -+) -+ -+(define_insn "crypto_" -+ [(set (match_operand:V4SI 0 "register_operand" "=w") -+ (unspec: -+ [(match_operand: 1 "register_operand" "0") -+ (vec_select:SI -+ (match_operand: 2 "register_operand" "w") -+ (parallel [(match_operand:SI 4 "immediate_operand" "i")])) -+ (match_operand: 3 "register_operand" "w")] -+ CRYPTO_SELECTING))] -+ "TARGET_CRYPTO" -+ ".\\t%q0, %q2, %q3" -+ [(set_attr "neon_type" "")] -+) --- a/src/gcc/config/arm/fa526.md +++ b/src/gcc/config/arm/fa526.md @@ -62,12 +62,15 @@ @@ -49975,102 +38258,6 @@ "core*32") (define_insn_reservation "single_cycle" 1 ---- a/src/gcc/config/arm/neon-docgen.ml -+++ b/src/gcc/config/arm/neon-docgen.ml -@@ -329,6 +329,85 @@ - "@c This file is generated automatically using gcc/config/arm/neon-docgen.ml"; - "@c Please do not edit manually."] - -+let crypto_doc = -+" -+@itemize @bullet -+@item poly128_t vldrq_p128(poly128_t const *) -+@end itemize -+ -+@itemize @bullet -+@item void vstrq_p128(poly128_t *, poly128_t) -+@end itemize -+ -+@itemize @bullet -+@item uint64x1_t vceq_p64 (poly64x1_t, poly64x1_t) -+@end itemize -+ -+@itemize @bullet -+@item uint64x1_t vtst_p64 (poly64x1_t, poly64x1_t) -+@end itemize -+ -+@itemize @bullet -+@item uint32_t vsha1h_u32 (uint32_t) -+@*@emph{Form of expected instruction(s):} @code{sha1h.32 @var{q0}, @var{q1}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1cq_u32 (uint32x4_t, uint32_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1c.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1pq_u32 (uint32x4_t, uint32_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1p.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1mq_u32 (uint32x4_t, uint32_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1m.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1su0q_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1su0.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha1su1q_u32 (uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha1su1.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256hq_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256h.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256h2q_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256h2.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256su0q_u32 (uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256su0.32 @var{q0}, @var{q1}} -+@end itemize -+ -+@itemize @bullet -+@item uint32x4_t vsha256su1q_u32 (uint32x4_t, uint32x4_t, uint32x4_t) -+@*@emph{Form of expected instruction(s):} @code{sha256su1.32 @var{q0}, @var{q1}, @var{q2}} -+@end itemize -+ -+@itemize @bullet -+@item poly128_t vmull_p64 (poly64_t a, poly64_t b) -+@*@emph{Form of expected instruction(s):} @code{vmull.p64 @var{q0}, @var{d1}, @var{d2}} -+@end itemize -+ -+@itemize @bullet -+@item poly128_t vmull_high_p64 (poly64x2_t a, poly64x2_t b) -+@*@emph{Form of expected instruction(s):} @code{vmull.p64 @var{q0}, @var{d1}, @var{d2}} -+@end itemize -+" -+ - (* Program entry point. *) - let _ = - if Array.length Sys.argv <> 2 then -@@ -339,6 +418,7 @@ - let chan = open_out file in - gnu_header chan; - List.iter (document_group chan) intrinsic_groups; -+ Printf.fprintf chan "%s\n" crypto_doc; - close_out chan - with Sys_error sys -> - failwith ("Could not create output file " ^ file ^ ": " ^ sys) --- a/src/gcc/config/arm/iwmmxt2.md +++ b/src/gcc/config/arm/iwmmxt2.md @@ -24,7 +24,7 @@ @@ -50664,7 +38851,7 @@ "cortex_a9_p0_shift | cortex_a9_p1_shift") ;; Loads have a latency of 4 cycles. -@@ -130,7 +129,7 @@ +@@ -130,29 +129,29 @@ ;; We get 16*16 multiply / mac results in 3 cycles. (define_insn_reservation "cortex_a9_mult16" 3 (and (eq_attr "tune" "cortexa9") @@ -50673,7 +38860,6 @@ "cortex_a9_mult16") ;; The 16*16 mac is slightly different that it -@@ -137,22 +136,22 @@ ;; reserves M1 and M2 in the same cycle. (define_insn_reservation "cortex_a9_mac16" 3 (and (eq_attr "tune" "cortexa9") @@ -50749,15 +38935,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --- a/src/gcc/config/arm/neon-gen.ml +++ b/src/gcc/config/arm/neon-gen.ml -@@ -114,6 +114,7 @@ - | T_uint32x4 -> T_int32x4 - | T_uint64x1 -> T_int64x1 - | T_uint64x2 -> T_int64x2 -+ | T_poly64x2 -> T_int64x2 - (* Cast to types defined by mode in arm.c, not random types pulled in from - the header in use. This fixes incompatible pointer errors when - compiling with C++. *) -@@ -121,9 +122,12 @@ +@@ -121,6 +121,7 @@ | T_uint16 | T_int16 -> T_intHI | T_uint32 | T_int32 -> T_intSI | T_uint64 | T_int64 -> T_intDI @@ -50765,12 +38943,7 @@ | T_float32 -> T_floatSF | T_poly8 -> T_intQI | T_poly16 -> T_intHI -+ | T_poly64 -> T_intDI -+ | T_poly128 -> T_intTI - | T_arrayof (n, elt) -> T_arrayof (n, signed_ctype elt) - | T_ptrto elt -> T_ptrto (signed_ctype elt) - | T_const elt -> T_const (signed_ctype elt) -@@ -275,8 +279,8 @@ +@@ -275,8 +276,8 @@ let mode = mode_of_elt elttype shape in string_of_mode mode with MixedMode (dst, src) -> @@ -50781,7 +38954,7 @@ string_of_mode dstmode ^ string_of_mode srcmode let get_shuffle features = -@@ -291,19 +295,24 @@ +@@ -291,19 +292,24 @@ match List.find (fun feature -> match feature with Requires_feature _ -> true | Requires_arch _ -> true @@ -50809,150 +38982,14 @@ | _ -> false) features in if feature then Format.printf "#endif@\n" -@@ -356,79 +365,96 @@ - abase : "ARM" base name for the type (i.e. int in int8x8_t). - esize : element size. - enum : element count. -+ alevel: architecture level at which available. - *) - -+type fpulevel = CRYPTO | ALL -+ - let deftypes () = - let typeinfo = [ - (* Doubleword vector types. *) -- "__builtin_neon_qi", "int", 8, 8; -- "__builtin_neon_hi", "int", 16, 4; -- "__builtin_neon_si", "int", 32, 2; -- "__builtin_neon_di", "int", 64, 1; -- "__builtin_neon_sf", "float", 32, 2; -- "__builtin_neon_poly8", "poly", 8, 8; -- "__builtin_neon_poly16", "poly", 16, 4; -- "__builtin_neon_uqi", "uint", 8, 8; -- "__builtin_neon_uhi", "uint", 16, 4; -- "__builtin_neon_usi", "uint", 32, 2; -- "__builtin_neon_udi", "uint", 64, 1; -+ "__builtin_neon_qi", "int", 8, 8, ALL; -+ "__builtin_neon_hi", "int", 16, 4, ALL; -+ "__builtin_neon_si", "int", 32, 2, ALL; -+ "__builtin_neon_di", "int", 64, 1, ALL; -+ "__builtin_neon_hf", "float", 16, 4, ALL; -+ "__builtin_neon_sf", "float", 32, 2, ALL; -+ "__builtin_neon_poly8", "poly", 8, 8, ALL; -+ "__builtin_neon_poly16", "poly", 16, 4, ALL; -+ "__builtin_neon_poly64", "poly", 64, 1, CRYPTO; -+ "__builtin_neon_uqi", "uint", 8, 8, ALL; -+ "__builtin_neon_uhi", "uint", 16, 4, ALL; -+ "__builtin_neon_usi", "uint", 32, 2, ALL; -+ "__builtin_neon_udi", "uint", 64, 1, ALL; - - (* Quadword vector types. *) -- "__builtin_neon_qi", "int", 8, 16; -- "__builtin_neon_hi", "int", 16, 8; -- "__builtin_neon_si", "int", 32, 4; -- "__builtin_neon_di", "int", 64, 2; -- "__builtin_neon_sf", "float", 32, 4; -- "__builtin_neon_poly8", "poly", 8, 16; -- "__builtin_neon_poly16", "poly", 16, 8; -- "__builtin_neon_uqi", "uint", 8, 16; -- "__builtin_neon_uhi", "uint", 16, 8; -- "__builtin_neon_usi", "uint", 32, 4; -- "__builtin_neon_udi", "uint", 64, 2 -+ "__builtin_neon_qi", "int", 8, 16, ALL; -+ "__builtin_neon_hi", "int", 16, 8, ALL; -+ "__builtin_neon_si", "int", 32, 4, ALL; -+ "__builtin_neon_di", "int", 64, 2, ALL; -+ "__builtin_neon_sf", "float", 32, 4, ALL; -+ "__builtin_neon_poly8", "poly", 8, 16, ALL; -+ "__builtin_neon_poly16", "poly", 16, 8, ALL; -+ "__builtin_neon_poly64", "poly", 64, 2, CRYPTO; -+ "__builtin_neon_uqi", "uint", 8, 16, ALL; -+ "__builtin_neon_uhi", "uint", 16, 8, ALL; -+ "__builtin_neon_usi", "uint", 32, 4, ALL; -+ "__builtin_neon_udi", "uint", 64, 2, ALL - ] in - List.iter -- (fun (cbase, abase, esize, enum) -> -+ (fun (cbase, abase, esize, enum, fpulevel) -> - let attr = - match enum with - 1 -> "" - | _ -> Printf.sprintf "\t__attribute__ ((__vector_size__ (%d)))" - (esize * enum / 8) in -- Format.printf "typedef %s %s%dx%d_t%s;@\n" cbase abase esize enum attr) -+ if fpulevel == CRYPTO then -+ Format.printf "#ifdef __ARM_FEATURE_CRYPTO\n"; -+ Format.printf "typedef %s %s%dx%d_t%s;@\n" cbase abase esize enum attr; -+ if fpulevel == CRYPTO then -+ Format.printf "#endif\n";) - typeinfo; - Format.print_newline (); - (* Extra types not in . *) - Format.printf "typedef float float32_t;\n"; - Format.printf "typedef __builtin_neon_poly8 poly8_t;\n"; -- Format.printf "typedef __builtin_neon_poly16 poly16_t;\n" -+ Format.printf "typedef __builtin_neon_poly16 poly16_t;\n"; -+ Format.printf "#ifdef __ARM_FEATURE_CRYPTO\n"; -+ Format.printf "typedef __builtin_neon_poly64 poly64_t;\n"; -+ Format.printf "typedef __builtin_neon_poly128 poly128_t;\n"; -+ Format.printf "#endif\n" - --(* Output structs containing arrays, for load & store instructions etc. *) -+(* Output structs containing arrays, for load & store instructions etc. -+ poly128_t is deliberately not included here because it has no array types -+ defined for it. *) - - let arrtypes () = - let typeinfo = [ -- "int", 8; "int", 16; -- "int", 32; "int", 64; -- "uint", 8; "uint", 16; -- "uint", 32; "uint", 64; -- "float", 32; "poly", 8; -- "poly", 16 -+ "int", 8, ALL; "int", 16, ALL; -+ "int", 32, ALL; "int", 64, ALL; -+ "uint", 8, ALL; "uint", 16, ALL; -+ "uint", 32, ALL; "uint", 64, ALL; -+ "float", 32, ALL; "poly", 8, ALL; -+ "poly", 16, ALL; "poly", 64, CRYPTO - ] in -- let writestruct elname elsize regsize arrsize = -+ let writestruct elname elsize regsize arrsize fpulevel = - let elnum = regsize / elsize in - let structname = - Printf.sprintf "%s%dx%dx%d_t" elname elsize elnum arrsize in - let sfmt = start_function () in -- Format.printf "typedef struct %s" structname; -+ Format.printf "%stypedef struct %s" -+ (if fpulevel == CRYPTO then "#ifdef __ARM_FEATURE_CRYPTO\n" else "") structname; - open_braceblock sfmt; - Format.printf "%s%dx%d_t val[%d];" elname elsize elnum arrsize; - close_braceblock sfmt; -- Format.printf " %s;" structname; -+ Format.printf " %s;%s" structname (if fpulevel == CRYPTO then "\n#endif\n" else ""); - end_function sfmt; - in - for n = 2 to 4 do - List.iter -- (fun (elname, elsize) -> -- writestruct elname elsize 64 n; -- writestruct elname elsize 128 n) -+ (fun (elname, elsize, alevel) -> -+ writestruct elname elsize 64 n alevel; -+ writestruct elname elsize 128 n alevel) - typeinfo - done - -@@ -484,6 +510,8 @@ - print_ops ops; - Format.print_newline (); - print_ops reinterp; -+ print_ops reinterpq; -+ Format.printf "%s" crypto_intrinsics; - print_lines [ - "#ifdef __cplusplus"; - "}"; +@@ -365,6 +371,7 @@ + "__builtin_neon_hi", "int", 16, 4; + "__builtin_neon_si", "int", 32, 2; + "__builtin_neon_di", "int", 64, 1; ++ "__builtin_neon_hf", "float", 16, 4; + "__builtin_neon_sf", "float", 32, 2; + "__builtin_neon_poly8", "poly", 8, 8; + "__builtin_neon_poly16", "poly", 16, 4; --- a/src/gcc/config/mips/linux-common.h +++ b/src/gcc/config/mips/linux-common.h @@ -44,7 +44,7 @@ @@ -50964,61 +39001,16 @@ #undef STARTFILE_SPEC #define STARTFILE_SPEC \ ---- a/src/gcc/tree-vect-slp.c -+++ b/src/gcc/tree-vect-slp.c -@@ -2192,7 +2192,7 @@ - } - - /* Cost model: check if the vectorization is worthwhile. */ -- if (flag_vect_cost_model -+ if (!unlimited_cost_model () - && !vect_bb_vectorization_profitable_p (bb_vinfo)) - { - if (dump_enabled_p ()) ---- a/src/gcc/params.def -+++ b/src/gcc/params.def -@@ -544,6 +544,11 @@ - "Bound on number of runtime checks inserted by the vectorizer's loop versioning for alias check", - 10, 0, 0) - -+DEFPARAM(PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT, -+ "vect-max-peeling-for-alignment", -+ "Max number of loop peels to enhancement alignment of data references in a loop", -+ -1, -1, 64) -+ - DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIONS, - "max-cselib-memory-locations", - "The maximum memory locations recorded by cselib", --- a/src/libobjc/ChangeLog.linaro +++ b/src/libobjc/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -51026,7 +39018,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -51034,7 +39026,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -51042,37 +39034,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libgfortran/ChangeLog.linaro +++ b/src/libgfortran/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -51080,7 +39052,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -51088,7 +39060,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -51096,37 +39068,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libada/ChangeLog.linaro +++ b/src/libada/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -51134,7 +39086,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -51142,7 +39094,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -51150,37 +39102,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libffi/ChangeLog.linaro +++ b/src/libffi/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -51188,7 +39120,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -51196,7 +39128,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -51204,37 +39136,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libssp/ChangeLog.linaro +++ b/src/libssp/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -51242,7 +39154,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -51250,7 +39162,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -51258,7 +39170,7 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libcpp/configure +++ b/src/libcpp/configure @@ -7152,9 +7152,7 @@ @@ -51287,34 +39199,14 @@ hppa*64*-*-* | \ --- a/src/libcpp/ChangeLog.linaro +++ b/src/libcpp/ChangeLog.linaro -@@ -0,0 +1,59 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,39 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-09-05 Yvan Roux + @@ -51346,37 +39238,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/libcpp/po/ChangeLog.linaro +++ b/src/libcpp/po/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -51384,7 +39256,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -51392,7 +39264,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -51400,37 +39272,17 @@ + +2013-04-09 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. --- a/src/fixincludes/ChangeLog.linaro +++ b/src/fixincludes/ChangeLog.linaro -@@ -0,0 +1,51 @@ -+2014-03-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.03 released. -+ -+2014-02-11 Yvan Roux -+ -+ GCC Linaro 4.8-2014.02 released. -+ -+2014-01-17 Christophe Lyon -+ -+ GCC Linaro 4.8-2014.01 released. -+ -+2013-12-21 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.12 released. -+ -+2013-11-14 Christophe Lyon -+ -+ GCC Linaro 4.8-2013.11 released. -+ +@@ -0,0 +1,31 @@ +2013-10-15 Christophe Lyon + + GCC Linaro 4.8-2013.10 released. + +2013-09-10 Christophe Lyon + -+ GCC Linaro 4.8-2013.09 released. ++ GCC Linaro 4.8-2013.09 released. + +2013-08-14 Christophe Lyon + @@ -51438,7 +39290,7 @@ + +2013-07-19 Matthew Gretton-Dann + -+ GCC Linaro 4.8-2013.07-1 released. ++ GCC Linaro 4.8-2013.07-1 released. + +2013-07-05 Christophe Lyon + @@ -51446,7 +39298,7 @@ + +2013-06-11 Rob Savoye + -+ GCC Linaro gcc-linaro-4.8-2013.06 released. ++ GCC Linaro gcc-linaro-4.8-2013.06 released. + +2013-05-14 Matthew Gretton-Dann + @@ -51457 +39309 @@ -+ GCC Linaro 4.8-2013.04 released. ++ * GCC Linaro 4.8-2013.04 released. diff -u gcc-4.8-4.8.2/debian/patches/gcc-multiarch.diff gcc-4.8-4.8.2/debian/patches/gcc-multiarch.diff --- gcc-4.8-4.8.2/debian/patches/gcc-multiarch.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-multiarch.diff @@ -13,8 +13,6 @@ * config/s390/t-linux64: Set MULTIARCH_DIRNAME. * config/sparc/t-linux64: Set MULTIARCH_DIRNAME. -Index: b/src/libstdc++-v3/python/hook.in -=================================================================== --- a/src/libstdc++-v3/python/hook.in +++ b/src/libstdc++-v3/python/hook.in @@ -47,14 +47,18 @@ @@ -87,9 +85,9 @@ --- a/src/gcc/config/rs6000/t-linux64 +++ b/src/gcc/config/rs6000/t-linux64 @@ -30,3 +30,5 @@ - MULTILIB_EXTRA_OPTS := - MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu) - MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) + MULTILIB_EXTRA_OPTS = fPIC + MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:powerpc64-linux-gnu) + MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) + +MULTIARCH_DIRNAME = $(call if_multiarch,powerpc$(if $(findstring 64,$(target)),64)-linux-gnu) Index: b/src/gcc/config/i386/t-linux64 @@ -129,7 +127,7 @@ =================================================================== --- a/src/gcc/config.gcc +++ b/src/gcc/config.gcc -@@ -1806,8 +1806,11 @@ +@@ -1799,8 +1799,11 @@ mips64*-*-linux* | mipsisa64*-*-linux*) tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/gnu-user64.h mips/linux64.h mips/linux-common.h" tmake_file="${tmake_file} mips/t-linux64" @@ -142,7 +140,7 @@ mips64el-st-linux-gnu) tm_file="${tm_file} mips/st.h" tmake_file="${tmake_file} mips/t-st" -@@ -3746,7 +3749,7 @@ +@@ -3709,7 +3712,7 @@ i[34567]86-*-darwin* | x86_64-*-darwin*) ;; i[34567]86-*-linux* | x86_64-*-linux*) @@ -176,0 +175,13 @@ +Index: b/src/gcc/Makefile.in +=================================================================== +--- a/src/gcc/Makefile.in ++++ b/src/gcc/Makefile.in +@@ -1829,7 +1829,7 @@ + "$(MULTILIB_EXCLUSIONS)" \ + "$(MULTILIB_OSDIRNAMES)" \ + "$(MULTILIB_REQUIRED)" \ +- "$(MULTIARCH_DIRNAME)" \ ++ "$(if $(MULTILIB_OSDIRNAMES),,$(MULTIARCH_DIRNAME))" \ + "$(MULTILIB_REUSE)" \ + "@enable_multilib@" \ + > tmp-mlib.h; \ diff -u gcc-4.8-4.8.2/debian/patches/gcc-multilib-multiarch.diff gcc-4.8-4.8.2/debian/patches/gcc-multilib-multiarch.diff --- gcc-4.8-4.8.2/debian/patches/gcc-multilib-multiarch.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-multilib-multiarch.diff @@ -41,16 +41,16 @@ --- a/src/gcc/config/rs6000/t-linux64 +++ b/src/gcc/config/rs6000/t-linux64 @@ -28,7 +28,12 @@ - MULTILIB_OPTIONS := m64/m32 - MULTILIB_DIRNAMES := 64 32 - MULTILIB_EXTRA_OPTS := + MULTILIB_OPTIONS = m64/m32 + MULTILIB_DIRNAMES = 64 32 + MULTILIB_EXTRA_OPTS = fPIC +ifneq (,$(findstring powerpc64,$(target))) +MULTILIB_OSDIRNAMES = ../lib$(call if_multiarch,:powerpc64-linux-gnu) +MULTILIB_OSDIRNAMES += ../lib32$(call if_multiarch,:powerpc-linux-gnu) +else - MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu) --MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) -+MULTILIB_OSDIRNAMES += m32=../lib$(call if_multiarch,:powerpc-linux-gnu) + MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:powerpc64-linux-gnu) +-MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) ++MULTILIB_OSDIRNAMES += ../lib$(call if_multiarch,:powerpc-linux-gnu) +endif MULTIARCH_DIRNAME = $(call if_multiarch,powerpc$(if $(findstring 64,$(target)),64)-linux-gnu) reverted: --- gcc-4.8-4.8.2/debian/patches/gcc-rs6000-update.diff +++ gcc-4.8-4.8.2.orig/debian/patches/gcc-rs6000-update.diff @@ -1,70 +0,0 @@ -when trying to build Ada for powerpc64le-linux, I ran into an ICE -in fixup_args_size_notes. - -It turns out that the p8 fusion peephole acts on these two insns -from the epilog sequence: - -(insn 1693 1078 1079 91 (set (reg:DI 7 7) - (plus:DI (reg/f:DI 31 31) - (const_int 65536 [0x10000]))) 82 {*adddi3_internal1} - (nil)) -(insn 1079 1693 1511 91 (set (reg/f:DI 1 1) - (mem/c:DI (plus:DI (reg:DI 7 7) - (const_int -16096 [0xffffffffffffc120])) [233 %sfp+49440 S8 A64])) 519 {*movdi_internal64} - (expr_list:REG_DEAD (reg:DI 7 7) - (expr_list:REG_ARGS_SIZE (const_int 0 [0]) - (nil)))) - -and replaces them by: - -(insn 1776 1078 1777 91 (set (reg/f:DI 1 1) - (plus:DI (reg/f:DI 31 31) - (const_int 65536 [0x10000]))) -1 - (nil)) - -(insn 1777 1776 1511 91 (set (reg/f:DI 1 1) - (mem/c:DI (plus:DI (reg/f:DI 1 1) - (const_int -16096 [0xffffffffffffc120])) [233 S8 A8])) -1 - (expr_list:REG_ARGS_SIZE (const_int 0 [0]) - (nil))) - -Then peephole common code thinks it needs to re-create the REG_ARGS_SIZE -note and fails since the code is too complex for it to understand. (Which -is reasonable since it doesn't know what value is being restored from the -stack here.) - -However, the more fundamental problem seems to be that this transformation -should be invalid anyway, since it creates an intermediate state where -the stack pointer points to a location without proper backchain, which -violates the ABI. - -The following patch fixes this by disabling the fusion peephole in those -cases where it would introduce a new use of the stack pointer as temporary -register. - -Tested on powerpc64le-linux. OK for mainline (and 4.8 after the big patch -series is committed)? - -Bye, -Ulrich - -ChangeLog: - - * config/rs6000/rs6000.c (fusion_gpr_load_p): Refuse optimization - if it would clobber the stack pointer, even temporarily. - ---- a/src/gcc/config/rs6000/rs6000.c -+++ b/src/gcc/config/rs6000/rs6000.c -@@ -32519,6 +32519,11 @@ - - if (!peep2_reg_dead_p (2, addis_reg)) - return false; -+ -+ /* If the target register being loaded is the stack pointer, we must -+ avoid loading any other value into it, even temporarily. */ -+ if (REG_P (target) && REGNO (target) == STACK_POINTER_REGNUM) -+ return false; - } - - base_reg = XEXP (addr, 0); - diff -u gcc-4.8-4.8.2/debian/patches/gcc-target-include-asm.diff gcc-4.8-4.8.2/debian/patches/gcc-target-include-asm.diff --- gcc-4.8-4.8.2/debian/patches/gcc-target-include-asm.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-target-include-asm.diff @@ -4,7 +4,7 @@ =================================================================== --- a/src/configure.ac +++ b/src/configure.ac -@@ -2967,7 +2967,7 @@ +@@ -2964,7 +2964,7 @@ # being built; programs in there won't even run. if test "${build}" = "${host}" && test -d ${srcdir}/gcc; then # Search for pre-installed headers if nothing else fits. diff -u gcc-4.8-4.8.2/debian/patches/gcc-textdomain.diff gcc-4.8-4.8.2/debian/patches/gcc-textdomain.diff --- gcc-4.8-4.8.2/debian/patches/gcc-textdomain.diff +++ gcc-4.8-4.8.2/debian/patches/gcc-textdomain.diff @@ -19,7 +19,7 @@ =================================================================== --- a/src/gcc/Makefile.in +++ b/src/gcc/Makefile.in -@@ -5260,8 +5260,8 @@ +@@ -5304,8 +5304,8 @@ dir=$(localedir)/$$lang/LC_MESSAGES; \ echo $(mkinstalldirs) $(DESTDIR)$$dir; \ $(mkinstalldirs) $(DESTDIR)$$dir || exit 1; \ diff -u gcc-4.8-4.8.2/debian/patches/gccgo-version.diff gcc-4.8-4.8.2/debian/patches/gccgo-version.diff --- gcc-4.8-4.8.2/debian/patches/gccgo-version.diff +++ gcc-4.8-4.8.2/debian/patches/gccgo-version.diff @@ -4,7 +4,7 @@ =================================================================== --- a/src/gcc/go/Make-lang.in +++ b/src/gcc/go/Make-lang.in -@@ -243,7 +243,9 @@ +@@ -244,7 +244,9 @@ $(TM_H) $(RTL_H) $(TREE_H) $(TM_P_H) output.h $(TARGET_H) \ $(COMMON_TARGET_H) @@ -19,7 +19,7 @@ =================================================================== --- a/src/libgo/Makefile.in +++ b/src/libgo/Makefile.in -@@ -430,14 +430,14 @@ +@@ -431,14 +431,14 @@ SUFFIXES = .c .go .gox .o .obj .lo .a @LIBGO_IS_RTEMS_TRUE@subdirs = testsuite SUBDIRS = ${subdirs} diff -u gcc-4.8-4.8.2/debian/patches/gdc-4.8.diff gcc-4.8-4.8.2/debian/patches/gdc-4.8.diff --- gcc-4.8-4.8.2/debian/patches/gdc-4.8.diff +++ gcc-4.8-4.8.2/debian/patches/gdc-4.8.diff @@ -1,11 +1,9 @@ # DP: This implements D language support in the GCC back end, and adds # DP: relevant documentation about the GDC front end (code part). -Index: b/src/gcc/config/rs6000/rs6000.c -=================================================================== --- a/src/gcc/config/rs6000/rs6000.c +++ b/src/gcc/config/rs6000/rs6000.c -@@ -21584,7 +21584,8 @@ +@@ -21578,7 +21578,8 @@ rs6000_output_function_epilogue (FILE *f either, so for now use 0. */ if (! strcmp (language_string, "GNU C") || ! strcmp (language_string, "GNU GIMPLE") @@ -15,11 +13,9 @@ i = 0; else if (! strcmp (language_string, "GNU F77") || ! strcmp (language_string, "GNU Fortran")) -Index: b/src/gcc/dwarf2out.c -=================================================================== --- a/src/gcc/dwarf2out.c +++ b/src/gcc/dwarf2out.c -@@ -18909,6 +18909,8 @@ +@@ -18907,6 +18907,8 @@ gen_compile_unit_die (const char *filena language = DW_LANG_C89; if (strcmp (language_string, "GNU C++") == 0) language = DW_LANG_C_plus_plus; @@ -28,11 +24,9 @@ else if (strcmp (language_string, "GNU F77") == 0) language = DW_LANG_Fortran77; else if (strcmp (language_string, "GNU Pascal") == 0) -Index: b/src/gcc/gcc.c -=================================================================== --- a/src/gcc/gcc.c +++ b/src/gcc/gcc.c -@@ -1003,6 +1003,7 @@ +@@ -1002,6 +1002,7 @@ static const struct compiler default_com {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0}, {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0}, {".go", "#Go", 0, 1, 0}, diff -u gcc-4.8-4.8.2/debian/patches/gdc-frontend-posix.diff gcc-4.8-4.8.2/debian/patches/gdc-frontend-posix.diff --- gcc-4.8-4.8.2/debian/patches/gdc-frontend-posix.diff +++ gcc-4.8-4.8.2/debian/patches/gdc-frontend-posix.diff @@ -3,11 +3,11 @@ ---- a/src/gcc/d/dfrontend/object.h -+++ b/src/gcc/d/dfrontend/object.h -@@ -10,7 +10,7 @@ - #ifndef OBJECT_H - #define OBJECT_H +--- a/src/gcc/d/dfrontend/root.c ++++ b/src/gcc/d/dfrontend/root.c +@@ -7,7 +7,7 @@ + // in artistic.txt, or the GNU General Public License in gnu.txt. + // See the included readme.txt for details. -#define POSIX (linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun) +#define POSIX (__linux__ || __GLIBC__ || __gnu_hurd__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun) - #if __DMC__ - #pragma once + #include + #include diff -u gcc-4.8-4.8.2/debian/patches/gdc-libphobos-build.diff gcc-4.8-4.8.2/debian/patches/gdc-libphobos-build.diff --- gcc-4.8-4.8.2/debian/patches/gdc-libphobos-build.diff +++ gcc-4.8-4.8.2/debian/patches/gdc-libphobos-build.diff @@ -1,10 +1,8 @@ # DP: This implements building of libphobos library in GCC. -Index: b/src/configure -=================================================================== --- a/src/configure +++ b/src/configure -@@ -2781,7 +2781,8 @@ +@@ -2781,7 +2781,8 @@ target_libraries="target-libgcc \ ${libgcj} \ target-libobjc \ target-libada \ @@ -14,8 +12,6 @@ # these tools are built using the target libraries, and are intended to # run only in the target environment -Index: b/src/configure.ac -=================================================================== --- a/src/configure.ac +++ b/src/configure.ac @@ -164,6 +164,7 @@ @@ -26,11 +22,9 @@ target-boehm-gc \ ${libgcj} \ target-libobjc \ -Index: b/src/Makefile.def -=================================================================== --- a/src/Makefile.def +++ b/src/Makefile.def -@@ -131,6 +131,7 @@ +@@ -131,6 +131,7 @@ target_modules = { module= libquadmath; target_modules = { module= libgfortran; }; target_modules = { module= libobjc; }; target_modules = { module= libgo; }; @@ -38,7 +32,7 @@ target_modules = { module= libtermcap; no_check=true; missing=mostlyclean; missing=clean; -@@ -505,6 +506,8 @@ +@@ -505,6 +506,8 @@ dependencies = { module=configure-target dependencies = { module=all-target-libgo; on=all-target-libbacktrace; }; dependencies = { module=all-target-libgo; on=all-target-libffi; }; dependencies = { module=all-target-libgo; on=all-target-libatomic; }; @@ -47,7 +41,7 @@ dependencies = { module=configure-target-libjava; on=configure-target-zlib; }; dependencies = { module=configure-target-libjava; on=configure-target-boehm-gc; }; dependencies = { module=configure-target-libjava; on=configure-target-libffi; }; -@@ -560,6 +563,8 @@ +@@ -560,6 +563,8 @@ languages = { language=objc; gcc-check-t languages = { language=obj-c++; gcc-check-target=check-obj-c++; }; languages = { language=go; gcc-check-target=check-go; lib-check-target=check-target-libgo; }; @@ -56,11 +50,9 @@ // Toplevel bootstrap bootstrap_stage = { id=1 ; }; -Index: b/src/Makefile.in -=================================================================== --- a/src/Makefile.in +++ b/src/Makefile.in -@@ -933,6 +933,7 @@ +@@ -933,6 +933,7 @@ configure-target: \ maybe-configure-target-libgfortran \ maybe-configure-target-libobjc \ maybe-configure-target-libgo \ @@ -68,7 +60,7 @@ maybe-configure-target-libtermcap \ maybe-configure-target-winsup \ maybe-configure-target-libgloss \ -@@ -1086,6 +1087,7 @@ +@@ -1086,6 +1087,7 @@ all-target: maybe-all-target-libquadmath all-target: maybe-all-target-libgfortran all-target: maybe-all-target-libobjc all-target: maybe-all-target-libgo @@ -76,7 +68,7 @@ all-target: maybe-all-target-libtermcap all-target: maybe-all-target-winsup all-target: maybe-all-target-libgloss -@@ -1175,6 +1177,7 @@ +@@ -1175,6 +1177,7 @@ info-target: maybe-info-target-libquadma info-target: maybe-info-target-libgfortran info-target: maybe-info-target-libobjc info-target: maybe-info-target-libgo @@ -84,7 +76,7 @@ info-target: maybe-info-target-libtermcap info-target: maybe-info-target-winsup info-target: maybe-info-target-libgloss -@@ -1257,6 +1260,7 @@ +@@ -1257,6 +1260,7 @@ dvi-target: maybe-dvi-target-libquadmath dvi-target: maybe-dvi-target-libgfortran dvi-target: maybe-dvi-target-libobjc dvi-target: maybe-dvi-target-libgo @@ -92,7 +84,7 @@ dvi-target: maybe-dvi-target-libtermcap dvi-target: maybe-dvi-target-winsup dvi-target: maybe-dvi-target-libgloss -@@ -1339,6 +1343,7 @@ +@@ -1339,6 +1343,7 @@ pdf-target: maybe-pdf-target-libquadmath pdf-target: maybe-pdf-target-libgfortran pdf-target: maybe-pdf-target-libobjc pdf-target: maybe-pdf-target-libgo @@ -100,7 +92,7 @@ pdf-target: maybe-pdf-target-libtermcap pdf-target: maybe-pdf-target-winsup pdf-target: maybe-pdf-target-libgloss -@@ -1421,6 +1426,7 @@ +@@ -1421,6 +1426,7 @@ html-target: maybe-html-target-libquadma html-target: maybe-html-target-libgfortran html-target: maybe-html-target-libobjc html-target: maybe-html-target-libgo @@ -108,7 +100,7 @@ html-target: maybe-html-target-libtermcap html-target: maybe-html-target-winsup html-target: maybe-html-target-libgloss -@@ -1503,6 +1509,7 @@ +@@ -1503,6 +1509,7 @@ TAGS-target: maybe-TAGS-target-libquadma TAGS-target: maybe-TAGS-target-libgfortran TAGS-target: maybe-TAGS-target-libobjc TAGS-target: maybe-TAGS-target-libgo @@ -116,7 +108,7 @@ TAGS-target: maybe-TAGS-target-libtermcap TAGS-target: maybe-TAGS-target-winsup TAGS-target: maybe-TAGS-target-libgloss -@@ -1585,6 +1592,7 @@ +@@ -1585,6 +1592,7 @@ install-info-target: maybe-install-info- install-info-target: maybe-install-info-target-libgfortran install-info-target: maybe-install-info-target-libobjc install-info-target: maybe-install-info-target-libgo @@ -124,7 +116,7 @@ install-info-target: maybe-install-info-target-libtermcap install-info-target: maybe-install-info-target-winsup install-info-target: maybe-install-info-target-libgloss -@@ -1667,6 +1675,7 @@ +@@ -1667,6 +1675,7 @@ install-pdf-target: maybe-install-pdf-ta install-pdf-target: maybe-install-pdf-target-libgfortran install-pdf-target: maybe-install-pdf-target-libobjc install-pdf-target: maybe-install-pdf-target-libgo @@ -132,7 +124,7 @@ install-pdf-target: maybe-install-pdf-target-libtermcap install-pdf-target: maybe-install-pdf-target-winsup install-pdf-target: maybe-install-pdf-target-libgloss -@@ -1749,6 +1758,7 @@ +@@ -1749,6 +1758,7 @@ install-html-target: maybe-install-html- install-html-target: maybe-install-html-target-libgfortran install-html-target: maybe-install-html-target-libobjc install-html-target: maybe-install-html-target-libgo @@ -140,7 +132,7 @@ install-html-target: maybe-install-html-target-libtermcap install-html-target: maybe-install-html-target-winsup install-html-target: maybe-install-html-target-libgloss -@@ -1831,6 +1841,7 @@ +@@ -1831,6 +1841,7 @@ installcheck-target: maybe-installcheck- installcheck-target: maybe-installcheck-target-libgfortran installcheck-target: maybe-installcheck-target-libobjc installcheck-target: maybe-installcheck-target-libgo @@ -148,7 +140,7 @@ installcheck-target: maybe-installcheck-target-libtermcap installcheck-target: maybe-installcheck-target-winsup installcheck-target: maybe-installcheck-target-libgloss -@@ -1913,6 +1924,7 @@ +@@ -1913,6 +1924,7 @@ mostlyclean-target: maybe-mostlyclean-ta mostlyclean-target: maybe-mostlyclean-target-libgfortran mostlyclean-target: maybe-mostlyclean-target-libobjc mostlyclean-target: maybe-mostlyclean-target-libgo @@ -156,7 +148,7 @@ mostlyclean-target: maybe-mostlyclean-target-libtermcap mostlyclean-target: maybe-mostlyclean-target-winsup mostlyclean-target: maybe-mostlyclean-target-libgloss -@@ -1995,6 +2007,7 @@ +@@ -1995,6 +2007,7 @@ clean-target: maybe-clean-target-libquad clean-target: maybe-clean-target-libgfortran clean-target: maybe-clean-target-libobjc clean-target: maybe-clean-target-libgo @@ -164,7 +156,7 @@ clean-target: maybe-clean-target-libtermcap clean-target: maybe-clean-target-winsup clean-target: maybe-clean-target-libgloss -@@ -2077,6 +2090,7 @@ +@@ -2077,6 +2090,7 @@ distclean-target: maybe-distclean-target distclean-target: maybe-distclean-target-libgfortran distclean-target: maybe-distclean-target-libobjc distclean-target: maybe-distclean-target-libgo @@ -172,7 +164,7 @@ distclean-target: maybe-distclean-target-libtermcap distclean-target: maybe-distclean-target-winsup distclean-target: maybe-distclean-target-libgloss -@@ -2159,6 +2173,7 @@ +@@ -2159,6 +2173,7 @@ maintainer-clean-target: maybe-maintaine maintainer-clean-target: maybe-maintainer-clean-target-libgfortran maintainer-clean-target: maybe-maintainer-clean-target-libobjc maintainer-clean-target: maybe-maintainer-clean-target-libgo @@ -180,7 +172,7 @@ maintainer-clean-target: maybe-maintainer-clean-target-libtermcap maintainer-clean-target: maybe-maintainer-clean-target-winsup maintainer-clean-target: maybe-maintainer-clean-target-libgloss -@@ -2296,6 +2311,7 @@ +@@ -2296,6 +2311,7 @@ check-target: \ maybe-check-target-libgfortran \ maybe-check-target-libobjc \ maybe-check-target-libgo \ @@ -188,7 +180,7 @@ maybe-check-target-libtermcap \ maybe-check-target-winsup \ maybe-check-target-libgloss \ -@@ -2451,6 +2467,7 @@ +@@ -2451,6 +2467,7 @@ install-target: \ maybe-install-target-libgfortran \ maybe-install-target-libobjc \ maybe-install-target-libgo \ @@ -196,7 +188,7 @@ maybe-install-target-libtermcap \ maybe-install-target-winsup \ maybe-install-target-libgloss \ -@@ -2553,6 +2570,7 @@ +@@ -2553,6 +2570,7 @@ install-strip-target: \ maybe-install-strip-target-libgfortran \ maybe-install-strip-target-libobjc \ maybe-install-strip-target-libgo \ @@ -204,7 +196,7 @@ maybe-install-strip-target-libtermcap \ maybe-install-strip-target-winsup \ maybe-install-strip-target-libgloss \ -@@ -37320,6 +37338,463 @@ +@@ -37320,6 +37338,463 @@ maintainer-clean-target-libgo: @@ -668,7 +660,7 @@ .PHONY: configure-target-libtermcap maybe-configure-target-libtermcap maybe-configure-target-libtermcap: @if gcc-bootstrap -@@ -43344,6 +43819,14 @@ +@@ -43354,6 +43829,14 @@ check-gcc-go: (cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-go); check-go: check-gcc-go check-target-libgo @@ -683,7 +675,7 @@ # The gcc part of install-no-fixedincludes, which relies on an intimate # knowledge of how a number of gcc internal targets (inter)operate. Delegate. -@@ -45397,6 +45880,7 @@ +@@ -45407,6 +45890,7 @@ configure-target-libquadmath: stage_last configure-target-libgfortran: stage_last configure-target-libobjc: stage_last configure-target-libgo: stage_last @@ -691,7 +683,7 @@ configure-target-libtermcap: stage_last configure-target-winsup: stage_last configure-target-libgloss: stage_last -@@ -45428,6 +45912,7 @@ +@@ -45438,6 +45922,7 @@ configure-target-libquadmath: maybe-all- configure-target-libgfortran: maybe-all-gcc configure-target-libobjc: maybe-all-gcc configure-target-libgo: maybe-all-gcc @@ -699,7 +691,7 @@ configure-target-libtermcap: maybe-all-gcc configure-target-winsup: maybe-all-gcc configure-target-libgloss: maybe-all-gcc -@@ -46170,6 +46655,8 @@ +@@ -46180,6 +46665,8 @@ configure-target-libgo: maybe-all-target all-target-libgo: maybe-all-target-libbacktrace all-target-libgo: maybe-all-target-libffi all-target-libgo: maybe-all-target-libatomic @@ -708,7 +700,7 @@ configure-target-libjava: maybe-configure-target-zlib configure-target-libjava: maybe-configure-target-boehm-gc configure-target-libjava: maybe-configure-target-libffi -@@ -46256,6 +46743,7 @@ +@@ -46266,6 +46753,7 @@ configure-target-libquadmath: maybe-all- configure-target-libgfortran: maybe-all-target-libgcc configure-target-libobjc: maybe-all-target-libgcc configure-target-libgo: maybe-all-target-libgcc @@ -716,7 +708,7 @@ configure-target-libtermcap: maybe-all-target-libgcc configure-target-winsup: maybe-all-target-libgcc configure-target-libgloss: maybe-all-target-libgcc -@@ -46291,6 +46779,8 @@ +@@ -46301,6 +46789,8 @@ configure-target-libobjc: maybe-all-targ configure-target-libgo: maybe-all-target-newlib maybe-all-target-libgloss diff -u gcc-4.8-4.8.2/debian/patches/gdc-updates.diff gcc-4.8-4.8.2/debian/patches/gdc-updates.diff --- gcc-4.8-4.8.2/debian/patches/gdc-updates.diff +++ gcc-4.8-4.8.2/debian/patches/gdc-updates.diff @@ -1,1413 +1,8 @@ -# DP: gdc updates up to 20140401. +# DP: gdc updates up to 20130611. ---- a/src/gcc/d/ChangeLog 2013-06-02 11:37:56.000000000 +0100 -+++ b/src/gcc/d/ChangeLog 2014-04-01 16:32:51.000000000 +0100 -@@ -1,694 +1,280 @@ --2013-06-01 Johannes Pfau -+2014-03-31 Iain Buclaw - -- * d-codegen.cc(maybe_set_builtin_frontend): Check parameter and -- return types of intrinsics. -+ * d-codegen.cc(error_mark_p): Removed function, replace uses with -+ error_operand_p. -+ (error_mark): Removed function, replace uses with error_mark_node. -+ * d-ctype.cc(Type::toCtype): Return d_unknown_type_node for frontend -+ error types. -+ * d-objfile.cc(VarDeclaration::toObjFile): Don't build CONST_DECLs for -+ non-scalar manifests. -+ -+2014-03-23 Iain Buclaw -+ -+ * d-decls.cc(Dsymbol::toImport): Prevent GC from collecting -+ IMPORTED_DECL nodes whilst front-end compilation in progress. -+ -+2014-03-19 Iain Buclaw -+ -+ * d-codegen.cc(AggLayout::visit): Rename to layout_aggregate_type. -+ (AggLayout::doFields, AggLayout::doInterfaces): Remove function and -+ move implementation into layout_aggregate_type. -+ (AggLayout::addField): Rename to insert_aggregate_field. -+ (AggLayout::finish): Rename to finish_aggregate_type. -+ * d-codegen.h(AggLayout): Update definition. -+ * d-ctype.cc(TypeStruct::toCtype): Update for glue changes. -+ (TypeFunction::toCtype): Fix ICE on generic function types. -+ (TypeClass::toCtype): Move generation of vptr and monitor fields into -+ layout_aggregate_type. Moved generation of TYPE_METHODS from ... -+ * d-objfile.cc(FuncDeclaration::toObjFile): ... here into -+ TypeClass::toCtype. Don't build up TYPE_METHODS on a per-function -+ basis, generate the entire vtable. -+ -+2014-03-18 Iain Buclaw -+ -+ * d-decls.cc(Dsymbol::toSymbolX): Set the symbol prettyIdent. -+ (Dsymbol::toImport): Emit packages as their fully qualified names. -+ (ClassDeclaration::toSymbol): Distinguish between the classinfo -+ assembler and decl name. -+ (InterfaceDeclaration::toSymbol): Likewise for interface symbol. -+ (Module::toSymbol): Likewise for moduleinfo symbol. -+ (ClassDeclaration::toVtblSymbol): Likewise for class vtable symbol. -+ (AggregateDeclaration::toInitializer) -+ (TypedefDeclaration::toInitializer, EnumDeclaration::toInitializer): -+ Likewise for default initialisers. -+ * d-objfile.cc(Module::genobjfile): Don't set-up moduleinfo symbol -+ storage twice. -+ -+2014-03-17 Iain Buclaw -+ -+ * d-codegen.cc(d_decl_context): Fix null pointer dereference. -+ * d-objfile.cc(FuncDeclaration::toObjFile): Don't override the setting -+ of DECL_CONTEXT on the declaration here. -+ (d_finish_symbol): Likewise. -+ * d-objfile.cc(VarDeclaration::toObjFile): Move the generation of -+ manifest constants to ... -+ * d-decls.cc(VarDeclaration::toSymbol): ... here, and emit them as -+ CONST_DECLs. Set the DECL_CONTEXT for all variable symbols. -+ -+ * d-builtins.cc(d_gcc_magic_builtins_module): Don't store compiler -+ generated builtins in Symbol::isym, use Symbol::csym instead. -+ (d_gcc_magic_libbuiltins_check): Likewise. -+ * d-codegen.cc(d_decl_context): Return the imported symbol tree of -+ modules where the NAMESPACE_DECL is now stored. -+ (d_build_module): Remove function. Move implementation to ... -+ * d-decls.cc(Dsymbol::toImport): ... here. Build an IMPORTED_DECL for -+ all imported declarations. -+ (FuncDeclaration::toSymbol): Remove special handling of Symbol::isym. -+ (Module::toSymbol): Remove call to d_build_module. -+ * d-objfile.cc(Dsymbol::toObjFile): Handle emission of IMPORTED_DECL -+ symbols to debug. -+ -+2014-03-16 Iain Buclaw -+ -+ * d-codegen.cc(build_attributes): Ensure D-specific attributes have -+ their value interpreted through CTFE. -+ -+2014-02-21 Iain Buclaw -+ -+ * d-codegen.cc(d_build_module): Update signature to accept a Loc -+ location to the module declaration. -+ * d-decls.cc(Module::toSymbol): Update call to d_build_module. -+ Set TREE_PUBLIC/DECL_EXTERNAL to distingush which modules are being -+ compiled. -+ * d-objfile.cc(Dsymbol::toObjFile): Handle Import symbols, and emit -+ debug information for imported modules. -+ (ImportStatement::toIR): Likewise. -+ (set_input_location): New function to implement the equivalent of -+ set_decl_location, but instead sets input_location. -+ -+2014-02-19 Johannes Pfau -+ -+ * d-objfile.cc(build_call_function): Call set_input_location -+ to set debug info correctly -+ -+2014-02-18 Iain Buclaw -+ -+ * d-objfile.cc(VarDeclaration::toObjFile): Remove toplevel check. -+ DECL_CONTEXT is never set on manifest constants. -+ (d_finish_compilation): Remove fancy check on force outputting -+ symbols to object file. -+ (build_type_decl): Don't emit the qualified identifier in debug -+ information. The fully qualified name is now determined through the -+ NAMESPACE_DECL context chain. -+ * d-ctype.cc(TypeEnum::toCtype): Likewise for enum members. -+ (VarDeclaration::toSymbol): Likewise for static variables. -+ (FuncDeclaration::toSymbol): Likewise for functions. -+ -+ * d-decls.cc(FuncDeclaration::toSymbol): Don't emit the 'D main' -+ symbol to debug as plain 'main'. -+ * d-objfile.cc(VarDeclaration::toObjFile): Don't emit the qualified -+ identifier of manifest constants in debug information. -+ -+2014-02-17 Iain Buclaw -+ -+ * d-codegen.cc(d_build_module): New function. -+ * d-decls.cc(Module::toSymbol): Use d_build_module to build up the -+ qualified module namespace. -+ -+ * d-codegen.cc(expand_intrinsic_op, expand_intrinsic_op2): New -+ functions to build a call to a builtin code. -+ (expand_intrinsic_bsr, expand_intrinsic_bt): New functions to expand a -+ BUILTIN_FRONTEND call to core.bitop intrinsics. -+ (expand_intrinsic_vaarg, expand_intrinsic_vastart): New functions to -+ expand a BUILTIN_FRONTEND call to core.vararg intrinsics. -+ (maybe_expand_builtin): Update. -+ -+2014-02-16 Iain Buclaw -+ -+ * d-decls.cc(Module::toSymbol): Build a NAMESPACE_DECL to populate the -+ DECL_CONTEXT of toplevel functions. -+ * d-codegen.cc(d_decl_context): Return the enclosing module -+ NAMESPACE_DECL as the decl context only when the symbol is extern(D) -+ and not D main. - --2013-06-01 Iain Buclaw -+2014-02-15 Iain Buclaw - -- * d-codegen.cc(IRState::var): Handle variables used for NRVO. -- * d-ir.cc(ReturnStatement::toIR): Return result decl directly if NRVO. -- * d-objfile.cc(Symbol::SnamedResult): New member to hold the named -- RESULT_DECL of the function. -- (FuncDeclaration::toObjFile): Set-up function for NRVO. -- (build_tlssections): Align _tlsstart and _tlsend symbols to target -- address size. -- * d-ctype(TypeFunction::toSymbol): Mark functions returning non-POD -- structs as TREE_ADDRESSABLE to force return in memory. -- * d-decls.cc(FuncDeclaration::toSymbol): Propagate TREE_ADDRESSABLE -- from the original function type. -- --2013-05-29 Iain Buclaw -- -- * d-target.cc: New source file to handle Target structure. -- -- * d-builtins.c(d_bi_init): Remove function. -- (d_gcc_type_align): Move to Target::alignsize. -- (d_gcc_field_align): Move to Target::fieldalign. -- (d_init_builtins): Build va_list type for D frontend. -- * d-lang.cc(d_init): Use isLP64 to determine LP64 targets. -- (d_add_builtin_version): Set is64bit if target is X86_64. -- * d-codegen.cc(convert_for_assignment): Use memset to implement front -- end code (struct = 0) here, rather than build an empty constructor. -- * d-elem.cc(AssignExp::toElem): Remove handling of (struct = 0) and -- call convert_for_assignment. -- --2013-05-28 Iain Buclaw -- -- * d-gcc-complex_t.h: Rename to complex_t.h. -- * d-gcc-real.cc: Rename to d-longdouble.cc. -- * d-gcc-real.h: Rename to longdouble.h -- * d-port.cc: New source file to handle Port structure. -- * gdc_alloca.h: Remove source. -- -- * d-longdouble.cc(real_t): Rename to longdouble. -- (longdouble::getnan): Move to Port::nan. -- (longdouble::getsnan): Move to Port::snan. -- (longdouble::getinfinity): Move to Port::infinity. -- (longdouble::isInf): Move to Port::isInfinite. -- (longdouble::isNan): Move to Port::isNan. -- (longdouble::isSignallingNan): Move to Port::isSignallingNan. -- * d-builtins.c(gcc_d_backend_init): Rename to d_backend_init. -- (gcc_d_backend_term): Rename to d_backend_term. -- (gcc_type_to_d_type): Don't map 128bit integers to D front end. -- -- * d-elem.cc(AssignExp::toElem): Remove handling of fillHoles, use -- memset to implement (struct = 0). -- (StructLiteralExp::toElem): Handle fillHoles here, creating a -- temporary var that is zero init'd with memset and returned. -- --2013-05-27 Iain Buclaw -- -- * d-codegen.cc(IRState::localVar): Rename to build_local_var. -- (IRState::exprVar): Rename to create_temporary_var. -- (IRState::maybeExprvar): Rename to maybe_temporary_var. -- (IRState::pointerIntSum): Rename to build_array_index. -- * d-lang.cc(d_handle_target_attribute): New function to handle D -- target attributes. -- --2013-05-26 Iain Buclaw -- -- * d-incpath.cc(prefixed_path): Add cpp_GCC_INCLUDE_DIR back in as -- second method for relocation. -- * d-elem.cc(IndexExp::toElem): Fix call to _aaGetX as from -- IRState::toElemLvalue. -- * d-codegen.cc(IRState::toElemLvalue): Remove function. -- (IRState::convertForAssignment): Rename to convert_for_assignment. -- (IRState::convertForCondition): Rename to convert_for_condition. -- (IRState::checkedIndex): Rename to d_checked_index. -- (IRState::boundsCond): Rename to d_bounds_condition. -- (IRState::arrayBoundsCheck): Rename to array_bounds_check. -- (IRState::assertCall): Rename to d_assert_call. -- (IRState::doLineNote): Move to irstate.h. -- * d-irstate.cc(IRBase::getLocalContext): Remove function. -- * d-decls.cc(VarDeclaration::toSymbol): Build decl lang specific for -- decl to point back to D front end type. -- (FuncDeclaration::toSymbol): Likewise. -- --2013-05-23 Iain Buclaw -- -- * d-codegen.cc(AggLayout::finish): Unset TYPE_SIZE before -- re-calculating. -- * d-ctype.cc(TypeStruct::toCtype): Don't call decl_attribute on the -- type twice. -- --2013-05-21 Iain Buclaw -- -- * d-lang.cc(d_gcc_dump_source): Remove function. -- (d_post_options): Set flag_excess_precision_cmd as standard. -- * d-gcc-real.cc(real_t::convert): Remove function. -- (real_t::floatCompare): Remove function. -- (real_t::operator): Always perform floating point compilation at the -- precision of the target real mode. -- * d-todt.cc(dt_last): Remove function. -- (dtlist_to_tree): Rename to dtvector_to_tree. -- (dt_cons): Replace TREE_CHAIN implementation for use of CONSTRUCTOR. -- (dt_chainon): Likewise. -- (dt_container): Likewise. -- (dt_container2): Likewise. -- (StructInitializer::toDt): Likewise. -- (StructLiteralExp::toDt): Likewise. -- --2013-05-17 Iain Buclaw -- -- * d-codegen.cc(IRState::convertTo): Replace with d_convert and -- convert_expr. -- (IRState::declContext): Replace with d_decl_context. -- (IRState::functionNeedsChain): Replace with needs_static_chain. -- (IRState::label): Replace with d_build_label. -- (IRState::emitTemplates): Move to ObjectFile. -- (functionDegenerateClosure): Replace with is_degenerate_closure. -- (get_object_method): Assert that function is a method. -- (IRState::startCond): Move to IRBase. -- (IRState::startElse): Likewise. -- (IRState::endCond): Likewise. -- (IRState::startLoop): Likewise. -- (IRState::continueHere): Likewise. -- (IRState::setContinueLabel): Likewise. -- (IRState::exitIfFalse): Likewise. -- (IRState::endLoop): Likewise. -- (IRState::startCase): Likewise. -- (IRState::doCase): Likewise. -- (IRState::endCase): Likewise. -- (IRState::continueLoop): Likewise. -- (IRState::exitLoop): Likewise. -- (IRState::startTry): Likewise. -- (IRState::startCatches): Likewise. -- (IRState::startCatch): Likewise. -- (IRState::endCatch): Likewise. -- (IRState::endCatches): Likewise. -- (IRState::startFinally): Likewise. -- (IRState::endFinally): Likewise. -- (IRState::doReturn): Likewise. -- (IRState::doJump): Likewise. -- (IRState::pushLabel): Likewise. -- (IRState::checkSwitchCase): Likewise. -- (IRState::checkGoto): Likewise. -- (IRState::checkPreviousGoto): Likewise. -- -- * d-elem.cc(CatAssignExp::toElem): Call postblit on appending array of -- structs if required. -- --2013-05-16 Johannes Pfau -+ * d-decls.cc(VarDeclaration::toSymbol): Don't call -+ setup_symbol_storage until after SET_DECL_ASSEMBLER_NAME has been set. - -- * d-incpath.cc(prefixed_path): use cpp_PREFIX instead of -- cpp_GCC_INCLUDE_DIR for relocation. -- --2013-05-16 Iain Buclaw -- -- * d-codegen.cc(IRState::convertForAssignment): Remove use of -- CtorEltMaker wrapper for vec. -- (d_array_value): Likewise. -- (build_delegate_cst): Likewise. -- (extract_from_method_call): Likewise. -- * d-elem.cc(NewExp::toElem): Likewise. -- (ArrayLiteralExp::toElem): Likewise. -- (AssocArrayLiteralExp::toElem): Likewise. -- (StructLiteralExp::toElem): Likewise. -- (NullExp::toElem): Likewise. -- (VectorExp::toElem): Likewise. -- * d-objfile.cc(build_moduleinfo): Likewise. -- * d-todt.cc(dt_container): Likewise. -- (dt_container2): Likewise. -- -- * d-asmstmt.cc(ExtAsmStatement::toIR): Remove use of ListMaker -- wrapper for tree chaining. -- * d-builtins.c(d_bi_builtin_func): Likewise. -- (d_bi_builtin_type): Likewise. -- (d_gcc_magic_builtins_module): Likewise. -- (d_gcc_magic_libbuiltins_module): Likewise. -- * d-codegen.cc(build_attributes): Likewise. -- (IRState::call): Likewise. -- (IRState::buildFrameForFunction): Likewise. -- (AggLayout::doFields): Likewise. -- (AggLayout::addField): Likewise. -- * d-ctype.cc(TypeEnum::toCtype): Likewise. -- (TypeFunction::toCtype): Likewise. -- * d-todt.cc(dt_container2): Likewise. -- -- * d-codegen.cc(IRState::getFrameInfo): Replace with get_frameinfo. -- (IRState::buildFrameForFunction): Replace with build_frame_type. -- (IRState::isClassNestedInFunction): Replace with d_nested_class. -- (IRState::isStructNestedInFunction): Replace with d_nested_struct. -- (IRState::getFrameForFunction): Fold into IRState::getFrameForSymbol. -- (IRState::getFrameForNestedClass): Likewise. -- (IRState::getFrameForNestedStruct): Likewise. -- --2013-05-15 Iain Buclaw -- -- * d-codegen.cc(IRState::buildFrameForFunction): Also copy the -- parameters of functions with 'in' contracts to a local frame decl. -- * d-lang.cc(d_handle_flatten_attribute): New function to handle D -- flatten attributes. -- --2013-05-14 Iain Buclaw -- -- * d-codegen.cc(IRState::chainLink): Remove function. -- (IRState::chainFunc): Remove function. -- (IRState::sthis): New member which holds the chain of function. -- (IRState::buildChain): Update to use new static chain decl. -- (IRState::getFrameInfo): Likewise. -- * d-objfile.cc(FuncDeclaration::buildClosure): Likewise. -- (FuncDeclaration::toObjFile): Default the function static chain decl -- to null unless vthis is given for the function. -- --2013-05-13 Iain Buclaw -- -- * d-lang.cc(d_handle_noinline_attribute): New function to handle D -- noinline attributes. -- (d_handle_forceinline_attribute): New function to handle D forceinline -- attributes. -- * d-elem.cc(StructLiteralExp::toElem): Return the struct initialiser -- symbol directly if the tree has already been built. -- * d-decls.cc(Dsymbol::toSymbolX): Constify the mangling name to use. -- --2013-05-10 Iain Buclaw -- -- * d-typinf.cc: New file containing type info routines originally in -- the D Front End. -- -- * d-todt.cc(dt_last): New helper function to retrieve last node in a -- dt_t tree list. -- (dt_cons): New helper function to append nodes to the end of a list. -- (dt_chainon): New helper function to concatenate two lists together. -- (dt_container): New helper function to build a ctor from a list. -- (build_vptr_monitor): New helper function to generate the class -- vtable, and put out __vptr and __monitor. -- symbol default values in a class declaration. -- (dtlist_to_tree): New helper function to convert a dt_t list into a -- constructor tree. -- (Type::toDt): Implement routines for new dt_t format. -- (TypeInfoDeclaration::toDt): Likewise. -- (Initializer::toDt): Likewise. -- (Expression::toDt): Likewise. -- (Declaration::toDt): Likewise. -- -- * d-objfile.cc(Dsymbol::toObjFile): Update for new dt_t format. -- (Module::genmoduleinfo): Likewise. -- (Symbol::Symbol): Moved from symbol.cc -- (Obj::objmod): Remove abstraction layer. -- (Obj::moduleinfo): Renamed to build_moduleinfo. -- (obj_tlssections): Renamed to build_tlssections. -- (outdata): Renamed to d_finish_symbol. -- (check_static_sym): Moved into d_finish_symbol. -- -- * d-codegen.cc(d_gcc_emit_local_variable): Remove. -- -- * d-decls.cc(Dsymbol::toSymbolX): Update to not call symbol_calloc. -- (FuncDeclaration::toThunkSymbol): Likewise. -- (ClassDeclaration::toSymbol): Build type as d_unknown_type_node. -- (InterfaceDeclaration::toSymbol): Likewise. -- (Module::toSymbol): Likewise. -- (ClassDeclaration::toVtblSymbol): Update call to toSymbolX. -- (AggregateDeclaration::toInitializer): Likewise. -- (TypedefDeclaration::toInitializer): Likewise. -- (EnumDeclaration::toInitializer): Likewise. -- -- * d-ir.cc(CaseStatement::toIR): Don't call static_sym. -- -- * d-lang.cc(rtlsym): Remove symbol. -- (D_DECL_READONLY_STATIC): Remove macro. -- (d_unknown_type_node): New LANG_TYPE node for marking TypeInfo_Class, -- Interface, and ModuleInfo types that are of a variable size determined -- at compile time. -- -- * d-elem.cc(StringExp::toElem): Clean up for new dt_t format. -- -- * symbol.cc: Remove file. -- --2013-05-08 Iain Buclaw -- -- * d-codegen.cc(IRState::getFrameInfo): Don't create a frame/closure -- for member functions, only required for nested. -- * d-elem.cc(Expression::toElemDtor): Call dtors in the correct order. -- (DeclarationExp::toElem): Don't call dtor on static, manifest, or -- extern symbols upon declaration. -- (AssignExp::toElem): Only call postblit on lvalues in assignment. -- (ArrayLiteralExp::toElem): Always generate literals on heap. -- --2013-05-06 Iain Buclaw -- -- * d-elem.cc(StructLiteralExp::toElem): Return the default initialiser -- symbol if one exists. -- * d-builtins.c(d_gcc_magic_libbuiltins_check): Override the function -- type with the correct built-in function type as defined in backend. -- --2013-04-15 Iain Buclaw -- -- * d-elem.cc(IdentityExp::toElem): Remove special handling of class, -- reference and array types. -- --2013-04-12 Iain Buclaw -- -- * d-codegen.cc(maybe_make_temp): Save call expressions so aren't -- evaluated more than once. -- (d_has_side_effects): Remove check for exceptional class types. -- --2013-04-10 Iain Buclaw -- -- * d-decls.cc(FuncDeclaration::toSymbol): Harden logic for marking -- functions pure as in 'has no side effects'. -- --2013-04-07 Iain Buclaw -- -- * d-decls.cc(FuncDeclaration::toSymbol): Push deferred functions to -- FuncDeclaration::deferred. -- * d-elem.cc(DelegateExp::toElem): Likewise. -- (FuncExp::toElem): Likewise. -- * d-objfile.cc(ObjectFile::shouldEmit): Likewise. -- (FuncDeclaration::toObjFile): Process all deferred functions in -- FuncDeclaration::deferred. -- * symbol.cc(Symbol::deferredNestedFuncs): Remove. -- --2013-04-05 Iain Buclaw -- -- * d-elem.cc(FuncExp::toElem): Defer function literals and lambdas -- until parent function has finished processing. -- --2013-04-04 Iain Buclaw -- -- * d-codegen.cc(IRState::buildChain): Use __frame decl directly when -- setting up the function frame. -- (maybe_set_builtin_frontend): Exit early if symbol has no parent. -- * d-decls.cc(FuncDeclaration::toSymbol): Defer all nested functions, -- not just templated instances. -- * d-objfile.cc(FuncDeclaration::toObjFile): Delay processed deferred -- nested functions until function has finished being generated. -- (ObjectFile::shouldEmit): Don't emit nested functions if the parent -- function hasn't finished processing. -- --2013-04-03 Iain Buclaw -- -- * d-codegen.cc(maybe_set_builtin_frontend): Merged from -- maybe_set_builtin and maybe_set_libcall. -- * d-decls.cc(FuncDeclaration::toSymbol): Use -- maybe_set_builtin_frontend. -- --2013-03-31 Iain Buclaw -- -- * d-lang.cc(d_init_options): Default module info emission to on. -- (d_handle_option): New femit-moduleinfo switch. -- * d-objfile.cc(Module::genobjfile): Don't emit module if disabled -- explicitly. -- * d-builtins(is_intrinsic_module_p): New function to test whether -- module is core.bitops. -- (is_math_module_p): New function to test whether module is std.math or -- core.stdc.math. -- (is_builtin_va_arg_p): New function to test whether symbol is -- specially handled va_arg template. -- (is_builtin_va_start_p): New function to test whether symbol is -- specially handled va_start template. -- * d-codegen.cc(IRState::binding): Replace with bind_expr. -- (IRState::mathModule): Replace with std_math_module. -- (IRState::mathCoreModule): Replace with core_math_module. -- (IRState::intrinsicModule): Replace with std_intrinsic_module. -- (IRState::cstdargTemplateDecl): Replace with va_arg_template. -- (IRState::stdargTemplateDecl): Replace with va_arg2_template. -- (IRState::cstdargStartTemplateDecl): Replace with va_start_template. -- (IRState::getLibCallDecl): Replace with get_libcall. -- (IRState::maybeSetLibCallDecl): Replace with maybe_set_libcall. -- (IRState::libCall): Replace with build_libcall. -- (IRState::maybeSetUpBuiltin): Replace with maybe_set_builtin. -- (IRState::Intrinsic): Move enum out of IRState. -- --2013-03-30 Iain Buclaw -- -- * d-codegen.cc(IRState::darrayPtrRef): Replace with d_array_ptr. -- (IRState::darrayLenRef): Replace with d_array_length. -- (IRState::darrayVal): Replace with d_array_value. -- (IRState::darrayString): Replace with d_array_string. -- (IRState::arrayLength): Replace with get_array_length. -- (get_object_method): Remove dependancy on irs parameter. -- * d-lang.cc(d_init): Use static bool std_inc to determine whether to -- include standard module paths. -- (d_post_options): Canonicalize the input filename. -- (d_parse_file): Correctly catch cases where input file is stdin. -- --2013-03-27 Iain Buclaw -- -- * d-codegen.cc(IRState::getFrameInfo) Create a custom static chain for -- all nested functions. -- * d-gcc-includes.h: Rename to d-system.h -- --2013-03-23 Iain Buclaw -- -- * d-builtins.c(d_bi_init): Set REALPAD to be TYPE_PRECISION of -- long_double_type_node. -- * d-codegen.cc(IRState::twoFieldType): Replace with -- build_two_field_type. -- (IRState::arrayOpNotImplemented): Replace with unhandled_arrayop_p. -- (IRState::delegateMethodRef): Replace with delegate_method. -- (IRState::delegateObjectRef): Replace with delegate_object. -- (IRState::delegateVal): Replace with build_delegate_cst. -- (IRState::methodCallExpr): Replace with build_method_call. -- (IRState::extractMethodCallExpr): Replace with -- extract_from_method_call. -- (IRState::objectInstanceMethod): Replace with get_object_method. -- (IRState::twoFieldCtor): Remove. -- (IRState::call): Assert that if calling a normal FUNCTION_TYPE, -- 'object' is not set. -- * d-ctype.cc(TypeDelegate::toCtype): Build a METHOD_TYPE for the .func -- field type in delegates. -- * d-lang.h(D_IS_METHOD_CALL_EXPR): Rename to D_METHOD_CALL_EXPR. -- * d-objfile.cc(FuncDeclaration::toObjFile): Remove assert for chain -- function. -- --2013-03-20 Johannes Pfau -- -- * d-codegen.cc(IRState::objectInstanceMethod): Recursively check -- for TOKsuper / TOKdottype. Do not ignore CastExp. -- * d-elem.cc(IdentityExp::toElem): Ignore padding in bitwise floating -- point comparisons. -- * testsuite: Cleanup. Remove invalid tests, adjust tests, etc. -- --2013-03-20 Iain Buclaw -- -- * d-codegen.cc(IRState::objectInstanceMethod): Get function pointer -- off function TREE_TYPE. -- (build_deref): Handle cases where expression to dereference is an -- address expression. -- (modify_expr): New function overload to set return type directly. -- * d-elem.cc(CatAssignExp::toElem): Use new modify_expr. -- (AssignExp::toElem): Likewise. -- * d-decls.cc(FuncDeclaration::toSymbol): Don't build a method type for -- nested functions / delegates. Just add on the hidden 'this' pointer -- containing the custom static chain/closure object. -- -- * d-codegen.cc(GlobalValues): Replace with current_module, -- current_irs, object_file. -- (IRState::getFuncType): Replace with get_function_type. -- (IRState::isCallByAlias): Replace with call_by_alias_p. -- (IRState::isFuncType): Replace with function_type_p. -- (IRState::doExp): Remove. -- -- * d-asmstmt.cc(ExtAsmStatement::syntaxCopy): Use arraySyntaxCopy to -- copy front end expressions. -- -- * d-codegen.cc(AssignExp::toElem): Call _d_arrayassign / _d_arrayctor -- when assigning arrays of structs. -- --2013-03-18 Iain Buclaw -- -- * d-codegen.cc(IRState::realPart): Replace with real_part. -- (IRState::imagPart): Replace with imaginary_part. -- (IRState::integerConstant): Replace with build_integer_cst. -- (IRState::floatConstant): Replace with build_float_cst. -- (IRState::hwi2toli): Replace with cst_to_hwi. -- (IRState::addressOf): Replace with build_address. -- (IRState::markAddressable): Replace with d_mark_addressable. -- (IRState::markUsed): Replace with d_mark_used. -- (IRState::markRead): Replace with d_mark_read. -- (IRState::indirect): Replace with indirect_ref. -- (IRState::pvoidOkay): Replace with void_okay_p. -- (IRState::maybeCompound): Replace with maybe_compound_expr. -- (IRState::maybeVoidCompound): Replace with maybe_vcompound_expr. -- (IRState::isErrorMark): Replace with error_mark_p. -- (IRState::getTargetSizeConst): Replace with tree_to_hwi. -- (IRState::modify): Replace with modify_expr. -- (IRState::vmodify): Replace with vmodify_expr. -- (IRState::vinit): Replace with build_vinit. -- (IRState::nop): Replace with build_nop. -- (IRState::vconvert): Replace with build_vconvert. -- (IRState::boolOp): Replace with build_boolop. -- (IRState::compound): Replace with compound_expr. -- (IRState::voidCompound): Replace with vcompound_expr. -- (IRState::component): Replace with component_ref. -- (IRState::errorMark): Replace with error_mark. -- (IRState::typesSame): Replace with d_types_same. -- (IRState::typesCompatible): Replace with d_types_compatible. -- (IRState::getDType): Replace with build_dtype. -- (IRState::getObjectType): Replace with build_object_type. -- (IRState::isDeclarationReferenceType): Replace with decl_reference_p. -- (IRState::trueDeclarationType): Replace with declaration_type. -- (IRState::isArgumentReferenceType): Replace with arg_reference_p. -- (IRState::trueArgumentType): Replace with type_passed_as. -- (IRState::arrayType): Replace with d_array_type. -- (IRState::addTypeAttribute): Replace with insert_type_attributes. -- (IRState::addDeclAttribute): Replace with insert_decl_attributes. -- (IRState::attributes): Replace with build_attributes. -- (IRState::addTypeModifiers): Replace with insert_type_modifiers. -- (IRState::maybeMakeTemp): Replace with maybe_make_temp. -- (IRState::isFreeOfSideEffects): Replace with d_has_side_effects. -- (IRState::pointerOffsetOp): Replace with build_offset_op. -- (IRState::pointerOffset): Replace with build_offset. -- (IRState::buildCall): Replace with d_build_call. -- (IRState::exceptionObject): Replace with build_exception_object. -- --2013-03-17 Iain Buclaw -- -- * d-asmstmt.cc(d_build_asm_stmt): Remove. -- (ExtAsmStatement::ExtAsmStatement): Update to match renamed members. -- (ExtAsmStatement::syntaxCopy): Likewise. -- (ExtAsmStatement::semantic): Likewise. -- (ExtAsmStatement::toCBuffer): Likewise. -- (ExtAsmStatement::comeFrom): New. -- (ExtAsmStatement::blockExit): Don't error if must not throw. -- (naturalString): Remove. -- (ExtAsmStatement::toIR): Inline IRState::doAsm implementation. -- * d-codegen.cc(IRState::doAsm): Remove. -- * d-decls.cc(FuncDeclaration::toSymbol): Don't generate 'naked' -- attribute. -- (binfo_for): Move into d-decls.cc. -- (intfc_binfo_for): Likewise. -- (ClassDeclaration::toDebug): Likewise. -- (EnumDeclaration::toDebug): Likewise. -- (TypedefDeclaration::toDebug): Likewise. -- (StructDeclaration::toDebug): Likewise. -- * d-objfile.cc(FuncDeclaration::toObjFile): Move into d-objfile.cc. -- (FuncDeclaration::buildClosure): Likewise. -- (Module::genobjfile): Likewise. -- * d-glue.cc: Remove file. -- --2013-03-16 Iain Buclaw -- -- * d-ir.cc(SynchronizedStatement::toIR): Remove implementation as is -- now handled by the frontend. -- --2013-03-15 Iain Buclaw -- -- * d-codegen.cc(IRState::maybeExpandSpecialCall): Handle ref argptr -- arguments. -- --2013-03-13 Iain Buclaw -- -- * d-builtins.c(handle_alias_attribute): New function to handle -- internal 'alias' attribute. -- (handle_weakref_attribute): New function to handle internal 'weakref' -- attribute. -- * d-objfile.cc(ObjectFile::outputThunk): Define thunks to external -- symbols as weakref, alias -- --2013-03-12 Johannes Pfau -- -- * patch-versym-os-4.8.x(mingw32.h): Fix typo -- * patch-versym-cpu-4.8.x(mips.h): Fix typo -- Update version symbols to latest dlang specification. -- --2013-03-10 Iain Buclaw -- -- * d-decls.cc(FuncDeclaration::toSymbol): Delay setting TREE_TYPE as -- function type could be hidden in a nested function not yet built. -- * d-codegen.cc(IRState::findThis): Don't get 'this' from outer -- function if it's a closure type. This has already been handled by -- IRState::getFrameForSymbol. -- (IRState::buildChain): Give frame decl debug name '__frame'. -- Always set '__chain' link field. -- (IRState::getFrameInfo): Don't build a frame for all nested functions. -- Search through nested aggregates for static chain in outer functions. -- * d-codegen.h(IRState::useParentChain): Remove. -- * d-glue.cc(FuncDeclaration::toObjFile): Don't call useParentChain. -- Don't create a local var for the chain link for a function. -- (FuncDeclaration::buildClosure): Always set '__chain' link field. -- --2013-03-08 Iain Buclaw -- -- * d-codegen.cc(d_gcc_force_templates): Only check for emitting -- templates as private. -- * d-lang.cc(d_handle_option): Remove -femit-templates= option. -- * d-objfile.cc(ObjectFile::makeDeclOneOnly): Fix code logic so -- fallback method could be reached. -- * d-objfile.h(TEall, TEauto): Remove. -- --2013-03-07 Iain Buclaw -- -- * d-ir.cc(ReturnStatement::toIR): Don't call postblit on return. -- * d-codegen.cc(IRState::trueDeclarationType): Don't set -- D_TYPE_ADDRESSABLE. -- (IRState::makeTemp): Remove. -- (IRState::maybeMakeTemp): Copy makeTemp into function. -- * d-glue.cc(d_genericize): Remove D_TYPE_ADDRESSABLE handling. -- * d-lang.h(D_TYPE_ADDRESSABLE): Remove macro. -- --2013-03-04 Johannes Pfau -- -- * d-ctype.cc(Type::toCtype): Always call gen.addTypeModifiers to -- make sure TYPE_MAIN_VARIANT is set. Reuse tree from unqualified -- variant for that. Also cache the resulting qualified tree. -- (TypeTypedef::toCtype): Likewise. -- (TypeEnum::toCtype): Likewise. -- (TypeStruct::toCtype): Likewise. -- (TypeFunction::toCtype): Likewise. -- (TypeVector::toCtype): Likewise. -- (TypeSArray::toCtype): Likewise. -- (TypeDArray::toCtype): Likewise. -- (TypeAArray::toCtype): Likewise. -- (TypeDelegate::toCtype): Likewise. -- (TypeClass::toCtype): Likewise. -- * d-objfile.cc(ObjectFile::giveDeclUniqueName): Make sure DECL_NAME is set -- --2013-03-01 Iain Buclaw -- -- * d-decls.cc(VarDeclaration::toSymbol): Remove use of c_ident. -+ * d-decls.cc(VarDeclaration::toSymbol): Give prettyIdent precedence -+ for the DECL_NAME over the simple identifier. - (FuncDeclaration::toSymbol): Likewise. -- * d-builtins.c(handle_noreturn_attribute): Assert that this is only -- used for internal purposes. -- (handle_const_attribute): Likewise. -- (handle_malloc_attribute): Likewise. -- (handle_pure_attribute): Likewise. -- (handle_nonnull_attribute): Likewise. -- (handle_nothrow_attribute): Likewise. -- (handle_sentinel_attribute): Likewise. -- (handle_transaction_pure_attribute): Likewise. -- (handle_returns_twice_attribute): Likewise. -- * d-glue.cc(FuncDeclaration::toObjFile): Result variables have no -- default initialiser. -- * d-codegen.cc(IRState::emitLocalVar): Add in assert that the local -- variable has no initialiser if called with no_init = true. -- (IRState::getLibCallDecl): Mark exceptional library functions as -- noreturn. -- (IRState::attributes): Gracefully handle @attribute, and -- @attribute(null). -- --2013-02-28 Jernej Krempus -- -- * d-builtins.c(d_attribute_table): Renamed it to -- d_builtins_attribute_table. -- * d-lang.cc(d_attribute_table): Added an empty table -- * d-lang.cc(LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Defined it as -- d_builtins_attribute_table. -- * d-lang.h(d_builtins_attribute_table): Added a declaration. -- * d-codegen.cc(IRState::attributes): Changed it so it goes through -- in_attrs and looks for any @gcc.attribute.attribute("attr_name"). -- * d-objfile.cc(ObjectFile::setupSymbolStorage): Pass userAttributes -- instead of attributes in all calls to IRState::attributes. -- * d-ctype.cc(TypeTypedef::toCtype): Likewise. -- (TypeEnum::toCtype): Likewise. -- (TypeStruct::toCtype): Likewise. -- (TypeClass::toCtype): Likewise. -- * libphobos/libdruntime/gcc/attribute.d: New file. -- --2013-02-28 Iain Buclaw -+ * d-objfile.cc(d_finish_symbol): Remove setting DECL_NAME as -+ prettyIdent, this has already been done in Declaration::toSymbol. -+ (d_finish_function): Likewise. - -- * d-lang.cc(d_handle_option): Remove OPT_fdeprecated and -- OPT_Wsign_compare, add handling for OPT_Wdeprecated. -- (d_post_options): Handle Wdeprecated and Werror switch combination. -- --2013-02-27 Iain Buclaw -- -- * d-codegen.cc(ArrayScope::ArrayScope): Don't setup length var if its -- value is known at compile time. -- (ArrayScope::setArrayExp): Likewise. -- * d-decls.cc(uniqueName): Remove function. -- (VarDeclaration::toSymbol): Set decl assembler name directly. -+ * d-decls.cc(VarDeclaration::toSymbol): Call set_user_assembler_name -+ if pragma(mangle) was seen. - (FuncDeclaration::toSymbol): Likewise. - --2013-02-15 Iain Buclaw -+2014-02-12 Johannes Pfau - -- * Make-lang.in(GDC_EXTENDED_ASM_SYNTAX): Remove macro. -+ * d-decls.cc(FuncDeclaration::toSymbol): Do not set TREE_NOTHROW on -+ nothrow functions. -+ * d-decls.cc(TypeInfoDeclaration::toSymbol): Call relayout_decl after -+ changing the type. - --2013-02-14 Iain Buclaw -+2014-02-03 Iain Buclaw - -- * d-lang.h(D_DECL_IS_CONTRACT): Remove macro. -- * d-decls.cc(FuncDeclaration::toSymbol): Likewise. - --2013-02-13 Iain Buclaw -+ * d-codegen.cc(d_build_call): Remove special handling of -+ flag_split_darrays switch. -+ (maybe_expand_builtin): Likewise. -+ * d-elem.cc(CatExp::toElem): Likewise. -+ * lang.opt(fsplit-dynamic-arrays): Remove. - -- * d-lang.cc(d_gcc_is_target_win32): Remove. -- (d_add_builtin_version): New function to handle define_builtin -- callback from backend. -- * d-codegen.cc(IRState::maybeExpandSpecialCall): Remove intrinsic bt. -+2014-02-02 Iain Buclaw - -- * d-builtins.c: Merge with d-builtins2.cc. -- * d-builtins2.cc: Remove. -+ * d-glue.cc(readFile, writeFile, ensurePathToNameExists): Define. -+ * d-incpath.cc(add_import_path): Update for frontend changes. -+ (add_fileimp_path): Likewise. -+ * d-lang.cc(deps_write): Likewise. -+ (d_parse_file): Likewise. -+ * d-todt.cc(Dts): Update define for frontend changes. -+ * d-decls.cc(ClassDeclaration::toVtblSymbol): Don't mark __vtbl -+ symbols as virtual. They are global static symbols. - --2013-02-07 Johannes Pfau -+2014-01-12 Iain Buclaw - -- * d-lang.cc(d_init): Use gcc's config system for predefined OS versions. -- * setup-gcc.sh: Likewise. -- * target-ver-syms.sh: Likewise. -+ * d-decls.cc(EnumDeclaration::toDebug): Build TYPE_DECL only for -+ enumeral types. - --2013-02-05 Iain Buclaw -+2014-01-06 Iain Buclaw - -- * d-builtins2.cc(gcc_type_to_d_type): Remove STRUCTTHISREF condition. -- * d-decls.cc(FuncDeclaration::toSymbol): Likewise. -- * d-elem.cc(ThisExp::toElem): Likewise. -- * d-ctype.cc(TypeSArray::toCtype): Remove SARRAYVALUE condition. -- * d-codegen.cc(IRState::isDeclarationReferenceType): Likewise. -- (IRState::isArgumentReferenceType): Likewise. -+ * d-ctype.cc(TypeClass::toCtype): Don't add __monitor field for -+ extern(C++) classes. - --2013-02-01 Johannes Pfau -+ * d-builtins.c(d_gcc_magic_module): Remove tdata. -+ * d-codegen.cc(build_interface_binfo): Likewise. -+ * d-ctype.cc(TypeEnum::toCtype): Likewise. -+ (TypeClass::toCtype): Likewise. -+ * d-lang.cc(deps_write): Likewise. -+ -+2014-01-05 Iain Buclaw - -- * d-lang.cc(d_init): Use gcc's config system for predefined CPU versions. -- (d_init): Fix definition of D_LP64 version. -- * setup-gcc.sh: Likewise. -- * target-ver-syms.sh: Likewise. -+ * d-ctype.cc(TypeEnum::toCtype): Don't push CONST_DECLs into current -+ function. -+ * d-decls.cc(FuncDeclaration::toThunkSymbol): Don't mark symbol as -+ TREE_PRIVATE, just TREE_PUBLIC as false. -+ (StructLiteralExp::toSymbol): Likewise. -+ (ClassReferenceExp::toSymbol): Likewise. -+ * d-objfile.cc(d_comdat_linkage): Likewise. -+ (d_finish_symbol): Likewise. -+ (build_moduleinfo): Likewise. -+ -+ * config-lang.in: Add d-lang.cc to gtfiles. -+ * d-irstate.h(IRState::varsInScope): Change from Array to vec<> type. -+ (IRState::statementList_): Likewise. -+ (IRState::scopes_): Likewise. -+ (IRState::loops_): Likewise. -+ (IRState::labels_): Likewise. -+ * d-lang.h(d_bi_builtin_func): Remove declaration. -+ (d_bi_builtin_type): Likewise. -+ (d_keep_list): Likewise. -+ * d-objfile.h(Symbol::thunks): Change from Array to vec<> type. -+ (ModuleInfo::classes): Likewise. -+ (ModuleInfo::ctors): Likewise. -+ (ModuleInfo::dtors): Likewise. -+ (ModuleInfo::ctorgates): Likewise. -+ (ModuleInfo::sharedctors): Likewise. -+ (ModuleInfo::shareddtors): Likewise. -+ (ModuleInfo::sharedctorgates): Likewise. -+ (ModuleInfo::unitTests): Likewise. -+ (build_simple_function): Remove declaration. -+ (build_call_function): Likewise. -+ (build_ctor_function): Likewise. -+ (build_dtor_function): Likewise. -+ (build_unittest_function): Likewise. -+ * d-builtins.c(bi_fn_list): Rename to gcc_builtins_functions. -+ (bi_lib_list): Rename to gcc_builtins_libfuncs. -+ (bi_type_list): Rename to gcc_builtins_types. -+ (builtin_converted_types): Remove. -+ (builtin_converted_decls): Change from Array to vec<> type. -+ (gcc_type_to_d_type): Update. -+ (d_bi_builtin_func): Remove and move to d_builtin_function. -+ (d_bi_builtin_type): Remove and move to d_register_builtin_type. -+ (d_gcc_magic_builtins_module): Update. -+ * d-ctype.cc(TypeClass::toCtype): Remove unused var. -+ * d-decls.cc(FuncDeclaration::toThunkSymbol): Update for change to -+ vec<> type. -+ * d-elem.cc(CatExp::toElem): Change stashed vars from Array to vec<>. -+ (Expression::toElemDtor): Update for change to vec<> type. -+ * d-irstate.cc(IRState::startFunction): Likewise. -+ (IRState::endFunction): Likewise. -+ (IRState::addExp): Likewise. -+ (IRState::pushStatementList): Likewise. -+ (IRState::popStatementList): Likewise. -+ (IRState::getLabelBlock): Likewise. -+ (IRState::getLoopForLabel): Likewise. -+ (IRState::beginFlow): Likewise. -+ (IRState::endFlow): Likewise. -+ (IRState::startScope): Likewise. -+ (IRState::pushLabel): Likewise. -+ (IRState::checkGoto): Likewise. -+ (IRState::checkPreviousGoto): Change from Array to Blocks type. -+ * d-lang.cc(global_declarations): Change from Array to vec<> type. -+ (d_add_global_declaration): Update for change to vec<> type. -+ (d_write_global_declarations): Likewise. -+ (d_keep_list): Make static to source file. -+ * d-objfile.cc(static_ctor_list): Change from Array to vec<> type. -+ (static_dtor_list): Likewise. -+ (Module::genobjfile): Update for change to vec<> type. -+ (d_finish_module): Likewise. -+ (d_finish_function): Likewise. -+ (deferred_thunks): Change from ArrayBase<> to vec<> type. -+ (write_deferred_thunks): Update for change to vec<> type. -+ (use_thunk): Likewise. -+ (build_simple_function): Make static to source file. -+ (build_call_function): Likewise. -+ (build_ctor_function): Likewise. -+ (build_dtor_function): Likewise. -+ (build_unittest_function): Likewise. -+ -+2014-01-02 Iain Buclaw -+ -+ * d-objfile.cc(setup_symbol_storage): Use output_module_p on template -+ instantiating module to determine if symbol is externally compiled. -+ (d_finish_function): Set function local if function body was compiled. -+ * d-decls.cc(Dsymbol::toSymbolX): Use unsigned integer format for the -+ prefix string length. - ---- a/src/gcc/d/ChangeLog-2013 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/ChangeLog-2013 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,1215 @@ -+2013-12-27 Iain Buclaw -+ -+ * d-codegen.cc(build_two_field_type): Declare builtin types as -+ toplevel declarations. -+ * d-ctype(EnumDeclaration::toDebug): Build type decl in debug code. -+ * d-lang.cc(nametype): Rename to d_nametype. -+ -+2013-12-23 Iain Buclaw -+ -+ * d-decls.cc(EnumDeclaration::toDebug): Don't send array types to -+ rest_of_type_compilation. -+ -+2013-12-16 Iain Buclaw -+ -+ * d-spec.cc(lang_specific_driver): Require linking in library for all -+ files except D interface files. -+ * d-lang.cc(d_write_global_declarations): Call d_finish_compilation. -+ * d-objfile.cc(mark_needed): Mark static. -+ (d_finish_symbol): Don't call mark_needed. -+ (d_finish_function): Likewise. -+ (d_finish_compilation): New function to wrapup all global -+ declarations, mark templates/comdats as needed if required, and start -+ the final compilation. -+ -+2013-12-10 Iain Buclaw -+ -+ * d-ctype.cc(TypeVector::toCtype): Treat void vectors as ubyte. -+ * d-objfile.cc(VarDeclaration::toObjFile): Gag all errors compiling -+ manifest constants. -+ * d-todt.cc(TypeVector::toDt): New function to generate correct static -+ data for vector initialisers. -+ -+2013-12-05 Iain Buclaw -+ -+ * d-lang.cc(d_init_options_struct): Don't define strict aliasing. -+ (d_get_alias_set): New function to return language-specific alias set. -+ * d-convert.cc(d_convert_basic): Always zero extend pointer to integer -+ conversions. -+ -+2013-12-04 Iain Buclaw -+ -+ * d-codegen.cc(maybe_set_builtin_frontend): Assert that all runtime -+ library functions have been set-up correctly. -+ (libcall_ids): Remove unhandled library functions. -+ (get_libcall): Likewise. -+ * d-codegen.h(LibCall): Likewise. -+ * d-objfile.cc(output_symbol_p): Remove. -+ -+2013-12-03 Iain Buclaw -+ -+ * d-lang.cc(d_init_options): Update for frontend changes. -+ (d_handle_option): Set frontend allInst option if -femit-templates. -+ * d-objfile.cc(output_template_p): Want to emit all instantiated -+ templates if -femit-templates or -fdebug was passed to the compiler. -+ * d-objfile.h(TemplateEmission): Define TEallinst. -+ * d-todt.cc(StructDeclaration::toDt): Update for frontend changes. -+ * d-spec.cc(THREAD_LIBRARY): Define default thread library to link if -+ one is not already specified in the configuration process. -+ (TIME_LIBRARY): Define default real time library to link if one is not -+ already specified in the configuration process. -+ (LIBSTDCXX): Define C++ library to link if compiling C++ and D sources. -+ (lang_specific_driver): Update implementation to use new macros. -+ -+2013-12-02 Iain Buclaw -+ -+ * d-elem.cc(CatAssignExp::toElem): Don't call postblit after element -+ append to array. -+ (NewExp::toElem): Handle calling 'new' on opaque types. -+ (ArrayLiteralExp::toElem): Ensure array literal elements have no side -+ effects by making temporaries as necessary. -+ * d-todt.cc(StructLiteralExp::toDt): Update for frontend changes. -+ * d-codegen.cc(build_frame_type): Check for scoped variables if -+ building a closure. -+ * d-objfile.cc(d_finish_symbol): Relax toDt checking rule. -+ -+2013-12-01 Iain Buclaw -+ -+ * d-asmstmt.cc(ExtAsmStatement::ExtAsmStatement): Remove labels -+ member from class. -+ * d-codegen.cc(d_gcc_force_templates): Remove. -+ (convert_expr): Update for frontend changes. -+ (convert_for_assignment): Likewise. -+ (maybe_set_builtin_frontend): Update for changes to libdruntime -+ core.bitops signatures. -+ * d-ctype.cc(TypeFunction::toCtype): Update for frontend changes. -+ * d-decls.cc(Dsymbol::toSymbolX): Likewise. -+ (VarDeclaration::toSymbol): Likewise. -+ (FuncDeclaration::toSymbol): Don't defer nested functions here. -+ * d-elem.cc(PowAssignExp::toElem): Update for frontend changes. -+ (DeleteExp::toElem): Likewise. -+ (AssertExp::toElem): Don't call invariant on an extern C++ class. -+ * d-glue.cc(Global::init): Initialise new stdmsg member. -+ * d-lang.cc(d_handle_option): Handle -fdeps switch. Remove TEprivate -+ for -femit-templates switch. -+ (genCmain): Update for frontend changes. -+ (d_parse_file): Likewise. -+ * d-longdouble.cc(longdouble::dump): Likewise. -+ * d-objfile.cc(ClassDeclaration::toObjFile): Update for frontend -+ changes. -+ (InterfaceDeclaration::toObjFile): Likewise. -+ (EnumDeclaration::toObjFile): Likewise. -+ (Symbol::Symbol): Remove outputSymbol member. -+ (output_symbol_p): Mark static. -+ (output_declaration_p): Determine symbol codegen status from -+ semanticRun. -+ (output_template_p): New function to determine whether an instantiated -+ template is to be written to object file. -+ (FuncDeclaration::toObjFile): Use semanticRun to update codegen status -+ of function. -+ (FuncDeclaration::buildClosure): Error if putting a scoped variable in -+ a closure. -+ (Module::genobjfile): Update for frontend changes. -+ (d_comdat_linkage): Don't determine linkage from TE setting. Mark all -+ comdat symbols as DECL_COMDAT. -+ (setup_symbol_storage): Use output_template_p to determine whether the -+ symbol is being written to object file. -+ (mark_needed): New function to mark decls that must be emitted. -+ (d_finish_symbol): Mark finished symbols as needed. -+ (d_finish_function): Mark finished functions as needed. -+ (build_simple_function): Set semanticRun for glue changes. -+ * d-objfile.h(OutputStage): Remove enum. -+ * d-todt.cc(build_vptr_monitor): Update for frontend changes. -+ (StructInitializer::toDt): Likewise. -+ (StructDeclaration::toDt): Likewise. -+ (TypeInfoEnumDeclaration::toDt): Likewise. -+ (TypeInfoStructDeclaration::toDt): Likewise. -+ (Type::getTypeInfo): Likewise. -+ -+2013-11-30 Iain Buclaw -+ -+ * d-lang.cc(genCmain): Implement code generation of __entrypoint -+ module to provide the target C main function. -+ (deps_write): Ignore the module __entrypoint when writing make deps. -+ (d_parse_file): Handle writing __entrypoint module to object file. -+ * d-objfile.cc(d_finish_symbol): Remove special handling of _tlsstart -+ symbol, but ensure _tlsend gets written to the thread common section. -+ (d_finish_function): Remove call to build_tlssections. -+ (build_tlssections): Remove. -+ -+2013-11-29 Iain Buclaw -+ -+ * d-decls.cc(ClassDeclaration::toVtblSymbol): Use TypeSArray::makeType -+ to generate frontend static array type. -+ * d-glue.cc(Dsymbol::ungagSpeculative): Define. -+ * d-lang.cc(genCmain): Define as empty. -+ (d_parse_file): Update for frontend changes. -+ * d-objfile.cc(StructDeclaration::toObjFile): Likewise. -+ * d-typinf.cc(TypeBasic::builtinTypeInfo): Likewise. -+ * d-longdouble.cc(longdouble::isIdenticalTo): Remove. -+ * d-port.cc(Port::fequal): Define. -+ -+2013-11-28 Iain Buclaw -+ -+ * d-builtins.cc(gcc_type_to_d_type): Use TypeSArray::makeType to -+ generate frontend static array types. -+ * d-codegen.cc(build_attributes): Use optimize as don't want the -+ ctfeInterpret of TypeExp expressions. -+ (get_object_method): Update for frontend changes. -+ (get_libcall): Update to use Type::dtypeinfo. -+ * d-elem.cc(IndexExp::toElem): Don't generate bounds checking codegen -+ if frontend explictly requests it. -+ (ArrayLiteralExp::toElem): Use TypeSArray::makeType to generate -+ frontend static array type. -+ (StructLiteralExp::toElem): Update for frontend changes. -+ * d-glue.cc(Global::increaseErrorCount): Define. -+ * d-objfile.cc(Module::genmoduleinfo): Remove moduleinfo 'New' -+ implementation for libdruntime changes. -+ * d-todt.cc(StructLiteralExp::toDt): Literal initialisers override -+ default initialisers. -+ (TypeInfoDeclaration::toDt): Update to use Type::dtypeinfo. -+ (TypeInfoStructDeclaration::toDt): Update for frontend changes. -+ * d-typinf.c(Type::getInternalTypeInfo): Update to use -+ Type::dtypeinfo. -+ -+2013-11-25 Iain Buclaw -+ -+ * d-asmstmt.cc(ExtAsmStatement::comeFromImpl): Define for frontend -+ implementation changes. -+ * d-codegen.cc(get_libcall): Update to use Type::typeinfoclass. -+ * d-codegen.cc(WrappedExp): Define as class. -+ * d-convert.cc(d_convert_basic): Fix format warnings. -+ * d-decls.cc(ModuleInfoDeclaration::toSymbol): Remove. -+ (FuncDeclaration::toSymbol): Use mangleExact to get decl mangle. -+ * d-elem.cc(ClassReferenceExp::toElem): Return reference to class. -+ * d-glue.cc(verror): Fix format warnings. -+ (verrorSupplemental): Likewise. -+ (vwarning): Likewise. -+ (vdeprecation): Likewise. -+ (escapePath): Define for frontend implementation changes. -+ * d-irstate.cc(IRState::getLoopForLabel): Implement breaking on named -+ scope labels in for/while loops. -+ * d-lang.cc(d_handle_option): Add handler for new -fdeps and -+ -fmake-deps options. -+ (d_parse_file): Handle new -fdeps and fmake-deps options. -+ * d-objfile.cc(Dsymbol::toObjFile): Update to use RootObject. -+ (Type::typeinfoclass): Update to use Type::typeinfoclass. -+ (InterfaceDeclaration::toObjFile): Likewise. -+ * d-objfile.h(Symbol): Remove inheritance from Object. -+ * d-todt.cc(TypeInfoStructDeclaration::toDt): Update to use -+ Type::immutableOf. -+ -+2013-11-24 Iain Buclaw -+ -+ * d-builtins.c(gcc_type_to_d_type): Use TREE_INT_CST_LOW macro instead -+ of tree_low_cst. -+ (eval_builtin): Likewise. -+ (gcc_cst_to_d_expr): Use tree_cst_hwi. -+ * d-codegen.cc(tree_to_hwi): Remove call to deleted host_integerp. -+ (maybe_expand_builtin): Use TREE_INT_CST_LOW macro. -+ * d-lang.cc(d_parse_file): Update debug_hooks call for middle-end -+ changes. -+ * d-system.h: Update includes for middle-end changes. -+ -+2013-11-17 Iain Buclaw -+ -+ * d-objfile.cc(finish_thunk): Update for conversion of symtab types to -+ a true class hierarchy. -+ -+ * d-ctype.cc(TypeClass::toCtype): Fix ABI to emit correct vtable and -+ monitor field names. -+ -+ * d-ctype.cc(TypeClass:toCtype): Set TYPE_LANG_SPECIFIC on record as -+ well as reference type. -+ * d-lang.cc(d_classify_record): New langhook to return appropriate -+ class/interface/struct type to the debugger. -+ -+2013-10-27 Iain Buclaw -+ -+ * d-elem.cc(ArrayLiteralExp::toElem): Build empty constructor for zero -+ sized arrays. -+ -+2013-10-23 Iain Buclaw -+ -+ * d-elem.cc(AssignExp::toElem): Optimise assigning array literal to a -+ static array. -+ (ArrayLiteralExp::toElem): Do not allocate static or const array -+ literals on the heap using the GC. -+ -+2013-10-16 Iain Buclaw -+ -+ * d-builtins.c(DEF_FUNCTION_TYPE_8): Define. -+ -+2013-10-10 Iain Buclaw -+ -+ * d-builtins.c(gcc_cst_to_d_expr): Add support for VECTOR_CST to -+ Expression conversion. -+ (d_gcc_paint_type): Add support for painting to/from array literals. -+ -+2013-10-01 Iain Buclaw -+ -+ * d-objfile.cc(cvtLocToloc_t): Rename to get_linemap. -+ * d-glue.cc: New source to provide interface for defined globals and -+ error handling called from the front-end. -+ -+2013-09-16 Iain Buclaw -+ -+ * d-codegen.cc(IRState::call): Rename to d_build_call. -+ (IRState::emitLocalVar): Rename to build_local_var. -+ (IRState::buildAssignOp): Move to BinExp::toElemBin. -+ (IRState::IRState): Remove IRState class. -+ * d-irstate.cc(IRBase::IRBase): Rename to IRState, remove inheritance -+ from Object class. -+ * d-decls.cc(VarDeclaration::toSymbol): Remove redundant CONST_DECL -+ code as VarDeclaration::toObjFile does not emit manifest constants. -+ * d-ctype.cc(TypeEnum::toCtype): Generate CONST_DECLs for enumeration -+ members for correct debugging. -+ * d-objfile.cc(build_type_decl): Use fully qualified type name in -+ debugging code. -+ (VarDeclaration::toObjFile): Emit manifest constant values in debug -+ code generation. -+ -+2013-09-10 Iain Buclaw -+ -+ * d-elem.cc(SliceExp::toElem): Don't build D array for slices that -+ return a static array. -+ -+2013-09-03 Iain Buclaw -+ -+ * d-codegen.cc(IRState::buildOp): Rename to build_binary_op. -+ -+2013-09-01 Iain Buclaw -+ -+ * d-decls.cc(binfo_for): Rename to build_class_binfo. -+ (intfc_binfo_for): Rename to build_interface_binfo. -+ (ClassDeclaration::toDebug): Move binfo generation into toCtype. -+ * d-lang.cc(pushlevel): Rename to push_binding_level. -+ (poplevel): Rename to pop_binding_level. -+ (global_bindings_p): Rename to d_global_bindings_p, add langhook. -+ (pushdecl): Rename to d_pushdecl, add langhook. -+ (getdecls): Rename to d_getdecls, add langhook. -+ (set_block): Remove function. -+ (insert_block): Remove function. -+ * d-irstate.cc(IRBase::startBindings): Inline set_block here. -+ (IRBase::endBindings): Inline insert_block here. -+ -+2013-08-29 Iain Buclaw -+ -+ * d-spec.c (lang_specific_spec_functions): Remove. -+ -+2013-08-28 Iain Buclaw -+ -+ * d-codegen.cc(IRState::doArraySet): Rename to IRBase::doArraySet. -+ (IRState::arraySetExpr): Remove function. -+ (IRState::expandDecl): Rename to expand_decl. -+ (IRState::typeinfoReference): Rename to build_typeinfo. -+ (IRState::buildChain): Merge into FuncDeclaration::buildClosure. -+ (IRState::getVThis): Rename to build_vthis. -+ (IRState::maybeExpandSpecialCall): Rename to maybe_expand_builtin. -+ (IRState::toDArray): Rename to d_array_convert. -+ -+2013-08-26 Iain Buclaw -+ -+ * d-codegen.cc(convert_expr): Check that the class type the codegen is -+ casting from is a base class of the class type the codegen is casting -+ to, not the other way round. -+ -+2013-08-14 Iain Buclaw -+ -+ * d-elem.cc(ArrayLiteralExp::toElem): Return null for zero length -+ array literals. -+ -+2013-08-07 Iain Buclaw -+ -+ * d-objfile.cc(finish_thunk): Don't emit thunks to external symbols as -+ weakref declarations. -+ * d-codegen.cc(IRState::maybeExpandSpecialCall): Remove intrinsic yl2x -+ and yl2xp1 builtins. -+ (maybe_set_builtin_frontend): Likewise. -+ -+2013-07-09 Iain Buclaw -+ -+ * d-builtins.c(d_gcc_magic_builtins_module): Set builtins solely -+ provided by the compiler as @safe, pure and nothrow. -+ * d-codegen.cc(IRState::getVThis): Don't set outer 'this' of structs -+ to be parent function chain if no frame has been created. -+ -+2013-07-08 Iain Buclaw -+ -+ * d-elem.cc(Expression::toElemDtor): Wrap temp variables destructor -+ calls in a try/finally expression. -+ -+2013-07-05 Johannes Pfau -+ -+ * patch-versym-os-4.8.x: Set versions on powerpc and alpha. -+ Remove SysV4 support and therefore fix macro redefinition warnings. -+ * patch-versym-os-4.9.x: Likewise. -+ -+2013-07-03 Iain Buclaw -+ -+ * d-longdouble.cc(longdouble::set): Intepret set values at higher -+ precision for min/max properties. -+ * d-codegen.cc(maybe_set_builtin_frontend): Add yl2x and yl2xp1 -+ math intrinsics. -+ (IRState::maybeExpandSpecialCall): Likewise. -+ -+2013-07-02 Iain Buclaw -+ -+ * d-objfile.cc(Module::genobjfile): Don't free current_module_info. -+ * d-codegen.cc(IRState::buildAssignOp): Don't create a SAVE_EXPR -+ around comma expressions used as lvalues. -+ * d-todt.cc(TypeSArray::toDtElem): Get underlying vector basetype when -+ layouting out data in a static array. -+ -+2013-06-29 Iain Buclaw -+ -+ * complex_t.h: Move into dfrontend. -+ * d-builtins.c(gcc_cst_to_d_expr): Explicitly create longdouble. -+ * d-longdouble.cc(longdouble::parse): Remove function. -+ (longdouble::longdouble): Remove constructors from longdouble. -+ Replaced with operator= template and longdouble::set. -+ (longdouble::rv): Update for new class layout. -+ (longdouble::from_shwi): New function to create a longdouble value -+ from a HOST_WIDE_INT. -+ (longdouble::from_uhwi): Likewise, but from an unsigned HOST_WIDE_INT. -+ (longdouble::to_shwi): New function to return a HOST_WIDE_INT value -+ from a longdouble. -+ (longdouble::to_uhwi): Likewise, but from an unsigedn HOST_WIDE_INT. -+ (longdouble::set): New function to explicitly set longdouble value. -+ (longdouble::toInt): Remove function. -+ (longdouble::isZero): Remove function. -+ (longdouble::isNegative): Remove function. -+ * d-port.cc(Port::nan): Rename to Port::ldbl_nan. -+ (Port::infinity): Rename to Port::ldbl_infinity. -+ (Port::ldbl_max): New static field. -+ (Port::init): Set ldbl_max to be maximimum value for long double type. -+ (Port::strtof): New function to convert string to longdouble. -+ (Port::strtod): Likewise. -+ (Port::strtold): Likewise. -+ -+2013-06-24 Iain Buclaw -+ -+ * d-objfile.cc(make_alias_for_thunk): Do not set -+ TREE_SYMBOL_REFERENCED. -+ -+2013-06-17 Iain Buclaw -+ -+ * d-codegen.cc(build_struct_memcmp): New function. -+ * d-elem.cc(IdentityExp::toElem): Use build_struct_memcmp for field -+ comparisons of small structs. -+ -+2013-06-13 Iain Buclaw -+ -+ * d-codegen.cc(make_temp): New function. -+ * d-decls.cc(StructLiteralExp::toSymbol): Implement correctly to -+ generate an anonymous symbol to reference to in the codegen. -+ (ClassReferenceExp::toSymbol): Likewise, but also use an anonymous -+ type as size is not determined until the data has been layed out. -+ * d-elem.cc(EqualExp::toElem): Optimise comparisons of arrays of basic -+ types, also ensure left-to-right evaluation. -+ (SliceExp::toElem): Handle returing slice as a static array type. -+ (AddrExp::toElem): Handle taking the address of StructLiteralExp and -+ ClassReferenceExp symbols. -+ (FuncExp::toElem): Relax type checking to allow returning function -+ addresses as generic pointer types. -+ (ArrayLiteralExp::toElem): Implicitly convert static arrays of void to -+ static arrays of ubyte. -+ (StructLiteralExp::toElem): Remove code generation of postblit calls, -+ now taken care of in the front end. -+ * d-objfile.cc(Module::genmoduleinfo): Emit module name as a null -+ terminated static array. -+ * d-ctype.cc(TypeAArray::toCtype): Pass AA types around like pointers. -+ -+2013-06-11 Iain Buclaw -+ -+ * dfrontend: Update to D front-end version 2.063. -+ -+ * d-builtins.c(gcc_type_to_d_type): Use Loc for unknown locations. -+ (d_gcc_magic_builtins_module): Likewise. -+ (gcc_cst_to_d_expr): Likewise. -+ * d-codegen.cc(get_libcall): Use FuncDeclaration::genCfunc to build -+ D runtime library functions. -+ * d-decl.cc(SymbolDeclaration::SymbolDeclaration): Remove function. -+ (StructLiteralExp::toSymbol): New function. -+ (ClassReferenceExp::toSymbol): New function. -+ * d-elem.cc(AssertExp::toElem): Call struct/class invariants only if -+ compiler is generating invariant code. -+ (TupleExp::toElem): Update for new front-end. -+ (ClassReferenceExp::toElem): New function. -+ * d-lang.cc(d_init_options): Set compiler.vendor front-end parameter. -+ (d_init): Call Expression::init. -+ * d-objfile.cc(InterfaceDeclaration::toObjFile): Correctly set the -+ xgetRTInfo field in the record layout. -+ * d-todt.cc(CastExp::toDt): New function. -+ (AddrExp::toDt): New function. -+ (ClassReferenceExp::toDt): New function. -+ (ClassReferenceExp::toDtI): New function. -+ (ClassReferenceExp::toInstanceDt): New function. -+ (ClassReferenceExp::toDt2): New function. -+ +--- a/src/gcc/d/ChangeLog ++++ b/src/gcc/d/ChangeLog +@@ -1,3 +1,75 @@ +2013-06-10 Iain Buclaw + + * d-objfile.cc(FuncDeclaration::toObjFile): Set 'this' parameter as @@ -1483,225915 +78,5244 @@ -+2013-06-01 Johannes Pfau -+ -+ * d-codegen.cc(maybe_set_builtin_frontend): Check parameter and -+ return types of intrinsics. -+ -+2013-06-01 Iain Buclaw -+ -+ * d-codegen.cc(IRState::var): Handle variables used for NRVO. -+ * d-ir.cc(ReturnStatement::toIR): Return result decl directly if NRVO. -+ * d-objfile.cc(Symbol::SnamedResult): New member to hold the named -+ RESULT_DECL of the function. -+ (FuncDeclaration::toObjFile): Set-up function for NRVO. -+ (build_tlssections): Align _tlsstart and _tlsend symbols to target -+ address size. -+ * d-ctype(TypeFunction::toSymbol): Mark functions returning non-POD -+ structs as TREE_ADDRESSABLE to force return in memory. -+ * d-decls.cc(FuncDeclaration::toSymbol): Propagate TREE_ADDRESSABLE -+ from the original function type. -+ -+2013-05-29 Iain Buclaw -+ -+ * d-target.cc: New source file to handle Target structure. -+ -+ * d-builtins.c(d_bi_init): Remove function. -+ (d_gcc_type_align): Move to Target::alignsize. -+ (d_gcc_field_align): Move to Target::fieldalign. -+ (d_init_builtins): Build va_list type for D frontend. -+ * d-lang.cc(d_init): Use isLP64 to determine LP64 targets. -+ (d_add_builtin_version): Set is64bit if target is X86_64. -+ * d-codegen.cc(convert_for_assignment): Use memset to implement front -+ end code (struct = 0) here, rather than build an empty constructor. -+ * d-elem.cc(AssignExp::toElem): Remove handling of (struct = 0) and -+ call convert_for_assignment. -+ -+2013-05-28 Iain Buclaw -+ -+ * d-gcc-complex_t.h: Rename to complex_t.h. -+ * d-gcc-real.cc: Rename to d-longdouble.cc. -+ * d-gcc-real.h: Rename to longdouble.h -+ * d-port.cc: New source file to handle Port structure. -+ * gdc_alloca.h: Remove source. -+ -+ * d-longdouble.cc(real_t): Rename to longdouble. -+ (longdouble::getnan): Move to Port::nan. -+ (longdouble::getsnan): Move to Port::snan. -+ (longdouble::getinfinity): Move to Port::infinity. -+ (longdouble::isInf): Move to Port::isInfinite. -+ (longdouble::isNan): Move to Port::isNan. -+ (longdouble::isSignallingNan): Move to Port::isSignallingNan. -+ * d-builtins.c(gcc_d_backend_init): Rename to d_backend_init. -+ (gcc_d_backend_term): Rename to d_backend_term. -+ (gcc_type_to_d_type): Don't map 128bit integers to D front end. -+ -+ * d-elem.cc(AssignExp::toElem): Remove handling of fillHoles, use -+ memset to implement (struct = 0). -+ (StructLiteralExp::toElem): Handle fillHoles here, creating a -+ temporary var that is zero init'd with memset and returned. -+ -+2013-05-27 Iain Buclaw -+ -+ * d-codegen.cc(IRState::localVar): Rename to build_local_var. -+ (IRState::exprVar): Rename to create_temporary_var. -+ (IRState::maybeExprvar): Rename to maybe_temporary_var. -+ (IRState::pointerIntSum): Rename to build_array_index. -+ * d-lang.cc(d_handle_target_attribute): New function to handle D -+ target attributes. -+ -+2013-05-26 Iain Buclaw -+ -+ * d-incpath.cc(prefixed_path): Add cpp_GCC_INCLUDE_DIR back in as -+ second method for relocation. -+ * d-elem.cc(IndexExp::toElem): Fix call to _aaGetX as from -+ IRState::toElemLvalue. -+ * d-codegen.cc(IRState::toElemLvalue): Remove function. -+ (IRState::convertForAssignment): Rename to convert_for_assignment. -+ (IRState::convertForCondition): Rename to convert_for_condition. -+ (IRState::checkedIndex): Rename to d_checked_index. -+ (IRState::boundsCond): Rename to d_bounds_condition. -+ (IRState::arrayBoundsCheck): Rename to array_bounds_check. -+ (IRState::assertCall): Rename to d_assert_call. -+ (IRState::doLineNote): Move to irstate.h. -+ * d-irstate.cc(IRBase::getLocalContext): Remove function. -+ * d-decls.cc(VarDeclaration::toSymbol): Build decl lang specific for -+ decl to point back to D front end type. -+ (FuncDeclaration::toSymbol): Likewise. -+ -+2013-05-23 Iain Buclaw -+ -+ * d-codegen.cc(AggLayout::finish): Unset TYPE_SIZE before -+ re-calculating. -+ * d-ctype.cc(TypeStruct::toCtype): Don't call decl_attribute on the -+ type twice. -+ -+2013-05-21 Iain Buclaw -+ -+ * d-lang.cc(d_gcc_dump_source): Remove function. -+ (d_post_options): Set flag_excess_precision_cmd as standard. -+ * d-gcc-real.cc(real_t::convert): Remove function. -+ (real_t::floatCompare): Remove function. -+ (real_t::operator): Always perform floating point compilation at the -+ precision of the target real mode. -+ * d-todt.cc(dt_last): Remove function. -+ (dtlist_to_tree): Rename to dtvector_to_tree. -+ (dt_cons): Replace TREE_CHAIN implementation for use of CONSTRUCTOR. -+ (dt_chainon): Likewise. -+ (dt_container): Likewise. -+ (dt_container2): Likewise. -+ (StructInitializer::toDt): Likewise. -+ (StructLiteralExp::toDt): Likewise. -+ -+2013-05-17 Iain Buclaw -+ -+ * d-codegen.cc(IRState::convertTo): Replace with d_convert and -+ convert_expr. -+ (IRState::declContext): Replace with d_decl_context. -+ (IRState::functionNeedsChain): Replace with needs_static_chain. -+ (IRState::label): Replace with d_build_label. -+ (IRState::emitTemplates): Move to ObjectFile. -+ (functionDegenerateClosure): Replace with is_degenerate_closure. -+ (get_object_method): Assert that function is a method. -+ (IRState::startCond): Move to IRBase. -+ (IRState::startElse): Likewise. -+ (IRState::endCond): Likewise. -+ (IRState::startLoop): Likewise. -+ (IRState::continueHere): Likewise. -+ (IRState::setContinueLabel): Likewise. -+ (IRState::exitIfFalse): Likewise. -+ (IRState::endLoop): Likewise. -+ (IRState::startCase): Likewise. -+ (IRState::doCase): Likewise. -+ (IRState::endCase): Likewise. -+ (IRState::continueLoop): Likewise. -+ (IRState::exitLoop): Likewise. -+ (IRState::startTry): Likewise. -+ (IRState::startCatches): Likewise. -+ (IRState::startCatch): Likewise. -+ (IRState::endCatch): Likewise. -+ (IRState::endCatches): Likewise. -+ (IRState::startFinally): Likewise. -+ (IRState::endFinally): Likewise. -+ (IRState::doReturn): Likewise. -+ (IRState::doJump): Likewise. -+ (IRState::pushLabel): Likewise. -+ (IRState::checkSwitchCase): Likewise. -+ (IRState::checkGoto): Likewise. -+ (IRState::checkPreviousGoto): Likewise. -+ -+ * d-elem.cc(CatAssignExp::toElem): Call postblit on appending array of -+ structs if required. -+ -+2013-05-16 Johannes Pfau -+ -+ * d-incpath.cc(prefixed_path): use cpp_PREFIX instead of -+ cpp_GCC_INCLUDE_DIR for relocation. -+ -+2013-05-16 Iain Buclaw -+ -+ * d-codegen.cc(IRState::convertForAssignment): Remove use of -+ CtorEltMaker wrapper for vec. -+ (d_array_value): Likewise. -+ (build_delegate_cst): Likewise. -+ (extract_from_method_call): Likewise. -+ * d-elem.cc(NewExp::toElem): Likewise. -+ (ArrayLiteralExp::toElem): Likewise. -+ (AssocArrayLiteralExp::toElem): Likewise. -+ (StructLiteralExp::toElem): Likewise. -+ (NullExp::toElem): Likewise. -+ (VectorExp::toElem): Likewise. -+ * d-objfile.cc(build_moduleinfo): Likewise. -+ * d-todt.cc(dt_container): Likewise. -+ (dt_container2): Likewise. -+ -+ * d-asmstmt.cc(ExtAsmStatement::toIR): Remove use of ListMaker -+ wrapper for tree chaining. -+ * d-builtins.c(d_bi_builtin_func): Likewise. -+ (d_bi_builtin_type): Likewise. -+ (d_gcc_magic_builtins_module): Likewise. -+ (d_gcc_magic_libbuiltins_module): Likewise. -+ * d-codegen.cc(build_attributes): Likewise. -+ (IRState::call): Likewise. -+ (IRState::buildFrameForFunction): Likewise. -+ (AggLayout::doFields): Likewise. -+ (AggLayout::addField): Likewise. -+ * d-ctype.cc(TypeEnum::toCtype): Likewise. -+ (TypeFunction::toCtype): Likewise. -+ * d-todt.cc(dt_container2): Likewise. -+ -+ * d-codegen.cc(IRState::getFrameInfo): Replace with get_frameinfo. -+ (IRState::buildFrameForFunction): Replace with build_frame_type. -+ (IRState::isClassNestedInFunction): Replace with d_nested_class. -+ (IRState::isStructNestedInFunction): Replace with d_nested_struct. -+ (IRState::getFrameForFunction): Fold into IRState::getFrameForSymbol. -+ (IRState::getFrameForNestedClass): Likewise. -+ (IRState::getFrameForNestedStruct): Likewise. -+ -+2013-05-15 Iain Buclaw -+ -+ * d-codegen.cc(IRState::buildFrameForFunction): Also copy the -+ parameters of functions with 'in' contracts to a local frame decl. -+ * d-lang.cc(d_handle_flatten_attribute): New function to handle D -+ flatten attributes. -+ -+2013-05-14 Iain Buclaw -+ -+ * d-codegen.cc(IRState::chainLink): Remove function. -+ (IRState::chainFunc): Remove function. -+ (IRState::sthis): New member which holds the chain of function. -+ (IRState::buildChain): Update to use new static chain decl. -+ (IRState::getFrameInfo): Likewise. -+ * d-objfile.cc(FuncDeclaration::buildClosure): Likewise. -+ (FuncDeclaration::toObjFile): Default the function static chain decl -+ to null unless vthis is given for the function. -+ -+2013-05-13 Iain Buclaw -+ -+ * d-lang.cc(d_handle_noinline_attribute): New function to handle D -+ noinline attributes. -+ (d_handle_forceinline_attribute): New function to handle D forceinline -+ attributes. -+ * d-elem.cc(StructLiteralExp::toElem): Return the struct initialiser -+ symbol directly if the tree has already been built. -+ * d-decls.cc(Dsymbol::toSymbolX): Constify the mangling name to use. -+ -+2013-05-10 Iain Buclaw -+ -+ * d-typinf.cc: New file containing type info routines originally in -+ the D Front End. -+ -+ * d-todt.cc(dt_last): New helper function to retrieve last node in a -+ dt_t tree list. -+ (dt_cons): New helper function to append nodes to the end of a list. -+ (dt_chainon): New helper function to concatenate two lists together. -+ (dt_container): New helper function to build a ctor from a list. -+ (build_vptr_monitor): New helper function to generate the class -+ vtable, and put out __vptr and __monitor. -+ symbol default values in a class declaration. -+ (dtlist_to_tree): New helper function to convert a dt_t list into a -+ constructor tree. -+ (Type::toDt): Implement routines for new dt_t format. -+ (TypeInfoDeclaration::toDt): Likewise. -+ (Initializer::toDt): Likewise. -+ (Expression::toDt): Likewise. -+ (Declaration::toDt): Likewise. -+ -+ * d-objfile.cc(Dsymbol::toObjFile): Update for new dt_t format. -+ (Module::genmoduleinfo): Likewise. -+ (Symbol::Symbol): Moved from symbol.cc -+ (Obj::objmod): Remove abstraction layer. -+ (Obj::moduleinfo): Renamed to build_moduleinfo. -+ (obj_tlssections): Renamed to build_tlssections. -+ (outdata): Renamed to d_finish_symbol. -+ (check_static_sym): Moved into d_finish_symbol. -+ -+ * d-codegen.cc(d_gcc_emit_local_variable): Remove. -+ -+ * d-decls.cc(Dsymbol::toSymbolX): Update to not call symbol_calloc. -+ (FuncDeclaration::toThunkSymbol): Likewise. -+ (ClassDeclaration::toSymbol): Build type as d_unknown_type_node. -+ (InterfaceDeclaration::toSymbol): Likewise. -+ (Module::toSymbol): Likewise. -+ (ClassDeclaration::toVtblSymbol): Update call to toSymbolX. -+ (AggregateDeclaration::toInitializer): Likewise. -+ (TypedefDeclaration::toInitializer): Likewise. -+ (EnumDeclaration::toInitializer): Likewise. -+ -+ * d-ir.cc(CaseStatement::toIR): Don't call static_sym. -+ -+ * d-lang.cc(rtlsym): Remove symbol. -+ (D_DECL_READONLY_STATIC): Remove macro. -+ (d_unknown_type_node): New LANG_TYPE node for marking TypeInfo_Class, -+ Interface, and ModuleInfo types that are of a variable size determined -+ at compile time. -+ -+ * d-elem.cc(StringExp::toElem): Clean up for new dt_t format. -+ -+ * symbol.cc: Remove file. -+ -+2013-05-08 Iain Buclaw -+ -+ * d-codegen.cc(IRState::getFrameInfo): Don't create a frame/closure -+ for member functions, only required for nested. -+ * d-elem.cc(Expression::toElemDtor): Call dtors in the correct order. -+ (DeclarationExp::toElem): Don't call dtor on static, manifest, or -+ extern symbols upon declaration. -+ (AssignExp::toElem): Only call postblit on lvalues in assignment. -+ (ArrayLiteralExp::toElem): Always generate literals on heap. -+ -+2013-05-06 Iain Buclaw -+ -+ * d-elem.cc(StructLiteralExp::toElem): Return the default initialiser -+ symbol if one exists. -+ * d-builtins.c(d_gcc_magic_libbuiltins_check): Override the function -+ type with the correct built-in function type as defined in backend. -+ -+2013-04-15 Iain Buclaw -+ -+ * d-elem.cc(IdentityExp::toElem): Remove special handling of class, -+ reference and array types. -+ -+2013-04-12 Iain Buclaw -+ -+ * d-codegen.cc(maybe_make_temp): Save call expressions so aren't -+ evaluated more than once. -+ (d_has_side_effects): Remove check for exceptional class types. -+ -+2013-04-10 Iain Buclaw -+ -+ * d-decls.cc(FuncDeclaration::toSymbol): Harden logic for marking -+ functions pure as in 'has no side effects'. -+ -+2013-04-07 Iain Buclaw -+ -+ * d-decls.cc(FuncDeclaration::toSymbol): Push deferred functions to -+ FuncDeclaration::deferred. -+ * d-elem.cc(DelegateExp::toElem): Likewise. -+ (FuncExp::toElem): Likewise. -+ * d-objfile.cc(ObjectFile::shouldEmit): Likewise. -+ (FuncDeclaration::toObjFile): Process all deferred functions in -+ FuncDeclaration::deferred. -+ * symbol.cc(Symbol::deferredNestedFuncs): Remove. -+ -+2013-04-05 Iain Buclaw -+ -+ * d-elem.cc(FuncExp::toElem): Defer function literals and lambdas -+ until parent function has finished processing. -+ -+2013-04-04 Iain Buclaw -+ -+ * d-codegen.cc(IRState::buildChain): Use __frame decl directly when -+ setting up the function frame. -+ (maybe_set_builtin_frontend): Exit early if symbol has no parent. -+ * d-decls.cc(FuncDeclaration::toSymbol): Defer all nested functions, -+ not just templated instances. -+ * d-objfile.cc(FuncDeclaration::toObjFile): Delay processed deferred -+ nested functions until function has finished being generated. -+ (ObjectFile::shouldEmit): Don't emit nested functions if the parent -+ function hasn't finished processing. -+ -+2013-04-03 Iain Buclaw -+ -+ * d-codegen.cc(maybe_set_builtin_frontend): Merged from -+ maybe_set_builtin and maybe_set_libcall. -+ * d-decls.cc(FuncDeclaration::toSymbol): Use -+ maybe_set_builtin_frontend. -+ -+2013-03-31 Iain Buclaw -+ -+ * d-lang.cc(d_init_options): Default module info emission to on. -+ (d_handle_option): New femit-moduleinfo switch. -+ * d-objfile.cc(Module::genobjfile): Don't emit module if disabled -+ explicitly. -+ * d-builtins(is_intrinsic_module_p): New function to test whether -+ module is core.bitops. -+ (is_math_module_p): New function to test whether module is std.math or -+ core.stdc.math. -+ (is_builtin_va_arg_p): New function to test whether symbol is -+ specially handled va_arg template. -+ (is_builtin_va_start_p): New function to test whether symbol is -+ specially handled va_start template. -+ * d-codegen.cc(IRState::binding): Replace with bind_expr. -+ (IRState::mathModule): Replace with std_math_module. -+ (IRState::mathCoreModule): Replace with core_math_module. -+ (IRState::intrinsicModule): Replace with std_intrinsic_module. -+ (IRState::cstdargTemplateDecl): Replace with va_arg_template. -+ (IRState::stdargTemplateDecl): Replace with va_arg2_template. -+ (IRState::cstdargStartTemplateDecl): Replace with va_start_template. -+ (IRState::getLibCallDecl): Replace with get_libcall. -+ (IRState::maybeSetLibCallDecl): Replace with maybe_set_libcall. -+ (IRState::libCall): Replace with build_libcall. -+ (IRState::maybeSetUpBuiltin): Replace with maybe_set_builtin. -+ (IRState::Intrinsic): Move enum out of IRState. -+ -+2013-03-30 Iain Buclaw -+ -+ * d-codegen.cc(IRState::darrayPtrRef): Replace with d_array_ptr. -+ (IRState::darrayLenRef): Replace with d_array_length. -+ (IRState::darrayVal): Replace with d_array_value. -+ (IRState::darrayString): Replace with d_array_string. -+ (IRState::arrayLength): Replace with get_array_length. -+ (get_object_method): Remove dependancy on irs parameter. -+ * d-lang.cc(d_init): Use static bool std_inc to determine whether to -+ include standard module paths. -+ (d_post_options): Canonicalize the input filename. -+ (d_parse_file): Correctly catch cases where input file is stdin. -+ -+2013-03-27 Iain Buclaw -+ -+ * d-codegen.cc(IRState::getFrameInfo) Create a custom static chain for -+ all nested functions. -+ * d-gcc-includes.h: Rename to d-system.h -+ -+2013-03-23 Iain Buclaw -+ -+ * d-builtins.c(d_bi_init): Set REALPAD to be TYPE_PRECISION of -+ long_double_type_node. -+ * d-codegen.cc(IRState::twoFieldType): Replace with -+ build_two_field_type. -+ (IRState::arrayOpNotImplemented): Replace with unhandled_arrayop_p. -+ (IRState::delegateMethodRef): Replace with delegate_method. -+ (IRState::delegateObjectRef): Replace with delegate_object. -+ (IRState::delegateVal): Replace with build_delegate_cst. -+ (IRState::methodCallExpr): Replace with build_method_call. -+ (IRState::extractMethodCallExpr): Replace with -+ extract_from_method_call. -+ (IRState::objectInstanceMethod): Replace with get_object_method. -+ (IRState::twoFieldCtor): Remove. -+ (IRState::call): Assert that if calling a normal FUNCTION_TYPE, -+ 'object' is not set. -+ * d-ctype.cc(TypeDelegate::toCtype): Build a METHOD_TYPE for the .func -+ field type in delegates. -+ * d-lang.h(D_IS_METHOD_CALL_EXPR): Rename to D_METHOD_CALL_EXPR. -+ * d-objfile.cc(FuncDeclaration::toObjFile): Remove assert for chain -+ function. -+ -+2013-03-20 Johannes Pfau -+ -+ * d-codegen.cc(IRState::objectInstanceMethod): Recursively check -+ for TOKsuper / TOKdottype. Do not ignore CastExp. -+ * d-elem.cc(IdentityExp::toElem): Ignore padding in bitwise floating -+ point comparisons. -+ * testsuite: Cleanup. Remove invalid tests, adjust tests, etc. -+ -+2013-03-20 Iain Buclaw -+ -+ * d-codegen.cc(IRState::objectInstanceMethod): Get function pointer -+ off function TREE_TYPE. -+ (build_deref): Handle cases where expression to dereference is an -+ address expression. -+ (modify_expr): New function overload to set return type directly. -+ * d-elem.cc(CatAssignExp::toElem): Use new modify_expr. -+ (AssignExp::toElem): Likewise. -+ * d-decls.cc(FuncDeclaration::toSymbol): Don't build a method type for -+ nested functions / delegates. Just add on the hidden 'this' pointer -+ containing the custom static chain/closure object. -+ -+ * d-codegen.cc(GlobalValues): Replace with current_module, -+ current_irs, object_file. -+ (IRState::getFuncType): Replace with get_function_type. -+ (IRState::isCallByAlias): Replace with call_by_alias_p. -+ (IRState::isFuncType): Replace with function_type_p. -+ (IRState::doExp): Remove. -+ -+ * d-asmstmt.cc(ExtAsmStatement::syntaxCopy): Use arraySyntaxCopy to -+ copy front end expressions. -+ -+ * d-codegen.cc(AssignExp::toElem): Call _d_arrayassign / _d_arrayctor -+ when assigning arrays of structs. -+ -+2013-03-18 Iain Buclaw -+ -+ * d-codegen.cc(IRState::realPart): Replace with real_part. -+ (IRState::imagPart): Replace with imaginary_part. -+ (IRState::integerConstant): Replace with build_integer_cst. -+ (IRState::floatConstant): Replace with build_float_cst. -+ (IRState::hwi2toli): Replace with cst_to_hwi. -+ (IRState::addressOf): Replace with build_address. -+ (IRState::markAddressable): Replace with d_mark_addressable. -+ (IRState::markUsed): Replace with d_mark_used. -+ (IRState::markRead): Replace with d_mark_read. -+ (IRState::indirect): Replace with indirect_ref. -+ (IRState::pvoidOkay): Replace with void_okay_p. -+ (IRState::maybeCompound): Replace with maybe_compound_expr. -+ (IRState::maybeVoidCompound): Replace with maybe_vcompound_expr. -+ (IRState::isErrorMark): Replace with error_mark_p. -+ (IRState::getTargetSizeConst): Replace with tree_to_hwi. -+ (IRState::modify): Replace with modify_expr. -+ (IRState::vmodify): Replace with vmodify_expr. -+ (IRState::vinit): Replace with build_vinit. -+ (IRState::nop): Replace with build_nop. -+ (IRState::vconvert): Replace with build_vconvert. -+ (IRState::boolOp): Replace with build_boolop. -+ (IRState::compound): Replace with compound_expr. -+ (IRState::voidCompound): Replace with vcompound_expr. -+ (IRState::component): Replace with component_ref. -+ (IRState::errorMark): Replace with error_mark. -+ (IRState::typesSame): Replace with d_types_same. -+ (IRState::typesCompatible): Replace with d_types_compatible. -+ (IRState::getDType): Replace with build_dtype. -+ (IRState::getObjectType): Replace with build_object_type. -+ (IRState::isDeclarationReferenceType): Replace with decl_reference_p. -+ (IRState::trueDeclarationType): Replace with declaration_type. -+ (IRState::isArgumentReferenceType): Replace with arg_reference_p. -+ (IRState::trueArgumentType): Replace with type_passed_as. -+ (IRState::arrayType): Replace with d_array_type. -+ (IRState::addTypeAttribute): Replace with insert_type_attributes. -+ (IRState::addDeclAttribute): Replace with insert_decl_attributes. -+ (IRState::attributes): Replace with build_attributes. -+ (IRState::addTypeModifiers): Replace with insert_type_modifiers. -+ (IRState::maybeMakeTemp): Replace with maybe_make_temp. -+ (IRState::isFreeOfSideEffects): Replace with d_has_side_effects. -+ (IRState::pointerOffsetOp): Replace with build_offset_op. -+ (IRState::pointerOffset): Replace with build_offset. -+ (IRState::buildCall): Replace with d_build_call. -+ (IRState::exceptionObject): Replace with build_exception_object. -+ -+2013-03-17 Iain Buclaw -+ -+ * d-asmstmt.cc(d_build_asm_stmt): Remove. -+ (ExtAsmStatement::ExtAsmStatement): Update to match renamed members. -+ (ExtAsmStatement::syntaxCopy): Likewise. -+ (ExtAsmStatement::semantic): Likewise. -+ (ExtAsmStatement::toCBuffer): Likewise. -+ (ExtAsmStatement::comeFrom): New. -+ (ExtAsmStatement::blockExit): Don't error if must not throw. -+ (naturalString): Remove. -+ (ExtAsmStatement::toIR): Inline IRState::doAsm implementation. -+ * d-codegen.cc(IRState::doAsm): Remove. -+ * d-decls.cc(FuncDeclaration::toSymbol): Don't generate 'naked' -+ attribute. -+ (binfo_for): Move into d-decls.cc. -+ (intfc_binfo_for): Likewise. -+ (ClassDeclaration::toDebug): Likewise. -+ (EnumDeclaration::toDebug): Likewise. -+ (TypedefDeclaration::toDebug): Likewise. -+ (StructDeclaration::toDebug): Likewise. -+ * d-objfile.cc(FuncDeclaration::toObjFile): Move into d-objfile.cc. -+ (FuncDeclaration::buildClosure): Likewise. -+ (Module::genobjfile): Likewise. -+ * d-glue.cc: Remove file. -+ -+2013-03-16 Iain Buclaw -+ -+ * d-ir.cc(SynchronizedStatement::toIR): Remove implementation as is -+ now handled by the frontend. -+ -+2013-03-15 Iain Buclaw -+ -+ * d-codegen.cc(IRState::maybeExpandSpecialCall): Handle ref argptr -+ arguments. -+ -+2013-03-13 Iain Buclaw -+ -+ * d-builtins.c(handle_alias_attribute): New function to handle -+ internal 'alias' attribute. -+ (handle_weakref_attribute): New function to handle internal 'weakref' -+ attribute. -+ * d-objfile.cc(ObjectFile::outputThunk): Define thunks to external -+ symbols as weakref, alias -+ -+2013-03-12 Johannes Pfau -+ -+ * patch-versym-os-4.8.x(mingw32.h): Fix typo -+ * patch-versym-cpu-4.8.x(mips.h): Fix typo -+ Update version symbols to latest dlang specification. -+ -+2013-03-10 Iain Buclaw -+ -+ * d-decls.cc(FuncDeclaration::toSymbol): Delay setting TREE_TYPE as -+ function type could be hidden in a nested function not yet built. -+ * d-codegen.cc(IRState::findThis): Don't get 'this' from outer -+ function if it's a closure type. This has already been handled by -+ IRState::getFrameForSymbol. -+ (IRState::buildChain): Give frame decl debug name '__frame'. -+ Always set '__chain' link field. -+ (IRState::getFrameInfo): Don't build a frame for all nested functions. -+ Search through nested aggregates for static chain in outer functions. -+ * d-codegen.h(IRState::useParentChain): Remove. -+ * d-glue.cc(FuncDeclaration::toObjFile): Don't call useParentChain. -+ Don't create a local var for the chain link for a function. -+ (FuncDeclaration::buildClosure): Always set '__chain' link field. -+ -+2013-03-08 Iain Buclaw -+ -+ * d-codegen.cc(d_gcc_force_templates): Only check for emitting -+ templates as private. -+ * d-lang.cc(d_handle_option): Remove -femit-templates= option. -+ * d-objfile.cc(ObjectFile::makeDeclOneOnly): Fix code logic so -+ fallback method could be reached. -+ * d-objfile.h(TEall, TEauto): Remove. -+ -+2013-03-07 Iain Buclaw -+ -+ * d-ir.cc(ReturnStatement::toIR): Don't call postblit on return. -+ * d-codegen.cc(IRState::trueDeclarationType): Don't set -+ D_TYPE_ADDRESSABLE. -+ (IRState::makeTemp): Remove. -+ (IRState::maybeMakeTemp): Copy makeTemp into function. -+ * d-glue.cc(d_genericize): Remove D_TYPE_ADDRESSABLE handling. -+ * d-lang.h(D_TYPE_ADDRESSABLE): Remove macro. -+ -+2013-03-04 Johannes Pfau -+ -+ * d-ctype.cc(Type::toCtype): Always call gen.addTypeModifiers to -+ make sure TYPE_MAIN_VARIANT is set. Reuse tree from unqualified -+ variant for that. Also cache the resulting qualified tree. -+ (TypeTypedef::toCtype): Likewise. -+ (TypeEnum::toCtype): Likewise. -+ (TypeStruct::toCtype): Likewise. -+ (TypeFunction::toCtype): Likewise. -+ (TypeVector::toCtype): Likewise. -+ (TypeSArray::toCtype): Likewise. -+ (TypeDArray::toCtype): Likewise. -+ (TypeAArray::toCtype): Likewise. -+ (TypeDelegate::toCtype): Likewise. -+ (TypeClass::toCtype): Likewise. -+ * d-objfile.cc(ObjectFile::giveDeclUniqueName): Make sure DECL_NAME is set -+ -+2013-03-01 Iain Buclaw -+ -+ * d-decls.cc(VarDeclaration::toSymbol): Remove use of c_ident. -+ (FuncDeclaration::toSymbol): Likewise. -+ * d-builtins.c(handle_noreturn_attribute): Assert that this is only -+ used for internal purposes. -+ (handle_const_attribute): Likewise. -+ (handle_malloc_attribute): Likewise. -+ (handle_pure_attribute): Likewise. -+ (handle_nonnull_attribute): Likewise. -+ (handle_nothrow_attribute): Likewise. -+ (handle_sentinel_attribute): Likewise. -+ (handle_transaction_pure_attribute): Likewise. -+ (handle_returns_twice_attribute): Likewise. -+ * d-glue.cc(FuncDeclaration::toObjFile): Result variables have no -+ default initialiser. -+ * d-codegen.cc(IRState::emitLocalVar): Add in assert that the local -+ variable has no initialiser if called with no_init = true. -+ (IRState::getLibCallDecl): Mark exceptional library functions as -+ noreturn. -+ (IRState::attributes): Gracefully handle @attribute, and -+ @attribute(null). -+ -+2013-02-28 Jernej Krempus -+ -+ * d-builtins.c(d_attribute_table): Renamed it to -+ d_builtins_attribute_table. -+ * d-lang.cc(d_attribute_table): Added an empty table -+ * d-lang.cc(LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Defined it as -+ d_builtins_attribute_table. -+ * d-lang.h(d_builtins_attribute_table): Added a declaration. -+ * d-codegen.cc(IRState::attributes): Changed it so it goes through -+ in_attrs and looks for any @gcc.attribute.attribute("attr_name"). -+ * d-objfile.cc(ObjectFile::setupSymbolStorage): Pass userAttributes -+ instead of attributes in all calls to IRState::attributes. -+ * d-ctype.cc(TypeTypedef::toCtype): Likewise. -+ (TypeEnum::toCtype): Likewise. -+ (TypeStruct::toCtype): Likewise. -+ (TypeClass::toCtype): Likewise. -+ * libphobos/libdruntime/gcc/attribute.d: New file. -+ -+2013-02-28 Iain Buclaw -+ -+ * d-lang.cc(d_handle_option): Remove OPT_fdeprecated and -+ OPT_Wsign_compare, add handling for OPT_Wdeprecated. -+ (d_post_options): Handle Wdeprecated and Werror switch combination. -+ -+2013-02-27 Iain Buclaw -+ -+ * d-codegen.cc(ArrayScope::ArrayScope): Don't setup length var if its -+ value is known at compile time. -+ (ArrayScope::setArrayExp): Likewise. -+ * d-decls.cc(uniqueName): Remove function. -+ (VarDeclaration::toSymbol): Set decl assembler name directly. -+ (FuncDeclaration::toSymbol): Likewise. -+ -+2013-02-15 Iain Buclaw -+ -+ * Make-lang.in(GDC_EXTENDED_ASM_SYNTAX): Remove macro. -+ -+2013-02-14 Iain Buclaw -+ -+ * d-lang.h(D_DECL_IS_CONTRACT): Remove macro. -+ * d-decls.cc(FuncDeclaration::toSymbol): Likewise. -+ -+2013-02-13 Iain Buclaw -+ -+ * d-lang.cc(d_gcc_is_target_win32): Remove. -+ (d_add_builtin_version): New function to handle define_builtin -+ callback from backend. -+ * d-codegen.cc(IRState::maybeExpandSpecialCall): Remove intrinsic bt. -+ -+ * d-builtins.c: Merge with d-builtins2.cc. -+ * d-builtins2.cc: Remove. -+ -+2013-02-07 Johannes Pfau -+ -+ * d-lang.cc(d_init): Use gcc's config system for predefined OS versions. -+ * setup-gcc.sh: Likewise. -+ * target-ver-syms.sh: Likewise. -+ -+2013-02-05 Iain Buclaw -+ -+ * d-builtins2.cc(gcc_type_to_d_type): Remove STRUCTTHISREF condition. -+ * d-decls.cc(FuncDeclaration::toSymbol): Likewise. -+ * d-elem.cc(ThisExp::toElem): Likewise. -+ * d-ctype.cc(TypeSArray::toCtype): Remove SARRAYVALUE condition. -+ * d-codegen.cc(IRState::isDeclarationReferenceType): Likewise. -+ (IRState::isArgumentReferenceType): Likewise. -+ -+2013-02-01 Johannes Pfau -+ -+ * d-lang.cc(d_init): Use gcc's config system for predefined CPU versions. -+ (d_init): Fix definition of D_LP64 version. -+ * setup-gcc.sh: Likewise. -+ * target-ver-syms.sh: Likewise. -+ ---- a/src/gcc/d/complex_t.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/complex_t.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,132 +0,0 @@ --// complex_t.h -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -- --// GCC is free software; you can redistribute it and/or modify it under --// the terms of the GNU General Public License as published by the Free --// Software Foundation; either version 3, or (at your option) any later --// version. -- --// GCC is distributed in the hope that it will be useful, but WITHOUT ANY --// WARRANTY; without even the implied warranty of MERCHANTABILITY or --// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --// for more details. -- --// You should have received a copy of the GNU General Public License --// along with GCC; see the file COPYING3. If not see --// . -- --#ifndef GCC_DCMPLR_COMPLEX_T_H --#define GCC_DCMPLR_COMPLEX_T_H -- --/* Roll our own complex type for compilers that don't support complex -- */ -- -- --struct complex_t --{ -- longdouble re; -- longdouble im; -- -- complex_t (void) -- { -- this->re = 0; -- this->im = 0; -- } -- -- complex_t (longdouble re) -- { -- this->re = re; -- this->im = 0; -- } -- -- complex_t (longdouble re, longdouble im) -- { -- this->re = re; -- this->im = im; -- } -- -- complex_t operator+ (complex_t y) -- { -- complex_t r; -- r.re = this->re + y.re; -- r.im = this->im + y.im; -- return r; -- } -- -- complex_t operator- (complex_t y) -- { -- complex_t r; -- r.re = this->re - y.re; -- r.im = this->im - y.im; -- return r; -- } -- -- complex_t operator- (void) -- { -- complex_t r; -- r.re = -this->re; -- r.im = -this->im; -- return r; -- } -- -- complex_t operator* (complex_t y) -- { return complex_t (this->re * y.re - this->im * y.im, this->im * y.re + this->re * y.im); } -- -- complex_t operator/ (complex_t y) -- { -- longdouble abs_y_re = y.re.isNegative() ? -y.re : y.re; -- longdouble abs_y_im = y.im.isNegative() ? -y.im : y.im; -- longdouble r, den; -- -- if (abs_y_re < abs_y_im) -- { -- r = y.re / y.im; -- den = y.im + r * y.re; -- return complex_t ((this->re * r + this->im) / den, -- (this->im * r - this->re) / den); -- } -- else -- { -- r = y.im / y.re; -- den = y.re + r * y.im; -- return complex_t ((this->re + r * this->im) / den, -- (this->im - r * this->re) / den); -- } -- } -- -- operator bool (void) -- { return !re.isZero() || !im.isZero(); } -- -- int operator== (complex_t y) -- { return this->re == y.re && this->im == y.im; } -- -- int operator!= (complex_t y) -- { return this->re != y.re || this->im != y.im; } --}; -- --inline complex_t operator* (longdouble x, complex_t y) --{ -- return complex_t (x) * y; --} -- --inline complex_t operator* (complex_t x, longdouble y) --{ -- return x * complex_t (y); --} -- --inline complex_t operator/ (complex_t x, longdouble y) --{ -- return x / complex_t (y); --} -- --inline longdouble creall (complex_t x) --{ -- return x.re; --} -- --inline longdouble cimagl (complex_t x) --{ -- return x.im; --} -- --#endif ---- a/src/gcc/d/config-lang.in 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/config-lang.in 2014-04-01 16:32:51.000000000 +0100 -@@ -1,7 +1,7 @@ - # config-lang.in for D front-end - - # GDC -- D front-end for GCC --# Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+# Copyright (C) 2011-2013 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 -@@ -14,20 +14,25 @@ - # GNU General Public License for more details. - # - # You should have received a copy of the GNU General Public License --# along with GCC; see the file COPYING3. If not see --# . -+# along with this program. If not, see . -+ -+# 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) - - language="d" - - compilers="cc1d\$(exeext)" + 2013-06-01 Johannes Pfau --stagestuff="gdc\$(exeext) gdc-cross\$(exeext) cc1d\$(exeext)" -- --gtfiles="\$(srcdir)/d/d-lang.h \$(srcdir)/d/d-builtins.c" -+target_libs="target-libphobos target-zlib target-libbacktrace" - --target_libs="target-libphobos target-zlib" -- --lang_requires=c++ -+# The D frontend is written in C++, so we need to build the C++ -+# compiler during stage 1. - lang_requires_boot_languages=c++ - -+gtfiles="\$(srcdir)/d/d-builtins.c \$(srcdir)/d/d-lang.h" -+ -+# Do not build by default. - build_by_default="no" ---- a/src/gcc/d/d-asmstmt.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-asmstmt.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-asmstmt.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -49,7 +49,7 @@ AsmStatement::toIR (IRState *) - ExtAsmStatement::ExtAsmStatement (Loc loc, Expression *insn, - Expressions *args, Identifiers *names, - Expressions *constraints, int outputargs, -- Expressions *clobbers, Dsymbols * labels) -+ Expressions *clobbers) - : Statement (loc) - { - this->insn = insn; -@@ -58,7 +58,6 @@ ExtAsmStatement::ExtAsmStatement (Loc lo - this->constraints = constraints; - this->outputargs = outputargs; - this->clobbers = clobbers; -- this->labels = labels; - } - - // Create a copy of ExtAsmStatement. -@@ -70,15 +69,13 @@ ExtAsmStatement::syntaxCopy (void) - Expressions *args = NULL; - Expressions *constraints = NULL; - Expressions *clobbers = NULL; -- Dsymbols *labels = NULL; - - args = Expression::arraySyntaxCopy (this->args); - constraints = Expression::arraySyntaxCopy (this->constraints); - clobbers = Expression::arraySyntaxCopy (this->clobbers); -- labels = Dsymbol::arraySyntaxCopy (this->labels); - - return new ExtAsmStatement (this->loc, insn, args, this->names, constraints, -- this->outputargs, clobbers, labels); -+ this->outputargs, clobbers); - } - - // Semantically analyze ExtAsmStatement where SC is the scope of the statment. -@@ -200,9 +197,10 @@ ExtAsmStatement::toCBuffer (OutBuffer *b - - // TRUE if statement 'comes from' somewhere else, like a goto. - --int ExtAsmStatement::comeFrom() -+bool -+ExtAsmStatement::comeFromImpl() - { -- return 1; -+ return true; - } + * d-codegen.cc(maybe_set_builtin_frontend): Check parameter and +--- a/src/gcc/d/d-builtins.c ++++ b/src/gcc/d/d-builtins.c +@@ -732,10 +732,10 @@ + Expression *arg0 = (*arguments)[0]; + Type *t0 = arg0->type; - // Return how an ExtAsmStatement exits. ---- a/src/gcc/d/d-builtins.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-builtins.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - /* d-builtins.c -- D frontend for GCC. -- Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. -+ Copyright (C) 2011-2013 Free Software Foundation, Inc. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free -@@ -24,13 +24,23 @@ - #include "template.h" - #include "d-codegen.h" - --static tree bi_fn_list; --static tree bi_lib_list; --static tree bi_type_list; -+static GTY(()) vec *gcc_builtins_functions = NULL; -+static GTY(()) vec *gcc_builtins_libfuncs = NULL; -+static GTY(()) vec *gcc_builtins_types = NULL; - - // Necessary for built-in struct types --static Array builtin_converted_types; --static Dsymbols builtin_converted_decls; -+struct builtin_sym -+{ -+ builtin_sym (Dsymbol *d, Type *t, tree c) -+ : decl(d), dtype(t), ctype(c) -+ { } -+ -+ Dsymbol *decl; -+ Type *dtype; -+ tree ctype; -+}; +- static IRState irs; + tree callee = NULL_TREE; + tree result; +- irs.doLineNote (loc); + -+static vec *builtin_converted_decls = NULL; ++ set_input_location (loc); - // Built-in symbols that require special handling. - static Module *std_intrinsic_module; -@@ -71,7 +81,6 @@ tree d_global_trees[DTI_MAX]; - static Type * - gcc_type_to_d_type (tree t) - { -- Expression *e; - Type *d; - unsigned type_size; - bool is_unsigned; -@@ -121,7 +130,7 @@ gcc_type_to_d_type (tree t) - return Type::tbool; - - case INTEGER_TYPE: -- type_size = tree_low_cst (TYPE_SIZE_UNIT (t), 1); -+ type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (t)); - is_unsigned = TYPE_UNSIGNED (t); + switch (builtin) + { +@@ -805,6 +805,7 @@ + gcc_unreachable(); + } - // This search assumes that integer types come before char and bit... -@@ -136,7 +145,7 @@ gcc_type_to_d_type (tree t) - break; ++ static IRState irs; + TypeFunction *tf = (TypeFunction *) gcc_type_to_d_type (TREE_TYPE (callee)); + result = irs.call (tf, callee, NULL, arguments); + result = fold (result); +@@ -846,8 +847,8 @@ + tree callee = NULL_TREE; - case REAL_TYPE: -- type_size = tree_low_cst (TYPE_SIZE_UNIT (t), 1); -+ type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (t)); - for (size_t i = 0; i < TMAX; i++) - { - d = Type::basic[i]; -@@ -146,7 +155,7 @@ gcc_type_to_d_type (tree t) - break; + // cirstate is not available. +- IRState irs; +- irs.doLineNote (loc); ++ static IRState irs; ++ set_input_location (loc); + tree result = irs.call (tf, callee, NULL, arguments); + result = fold (result); - case COMPLEX_TYPE: -- type_size = tree_low_cst (TYPE_SIZE_UNIT (t), 1); -+ type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (t)); - for (size_t i = 0; i < TMAX; i++) - { - d = Type::basic[i]; -@@ -170,10 +179,7 @@ gcc_type_to_d_type (tree t) - length = size_binop (PLUS_EXPR, size_one_node, - convert (sizetype, length)); - -- e = new IntegerExp (0, tree_to_hwi (length), -- Type::tindex); -- d = new TypeSArray (d, e); -- d = d->semantic (0, NULL); -+ d = TypeSArray::makeType (Loc(), d, tree_to_hwi (length)); - d->ctype = t; - return d; - } -@@ -183,8 +189,7 @@ gcc_type_to_d_type (tree t) - d = gcc_type_to_d_type (TREE_TYPE (t)); - if (d) - { -- e = new IntegerExp (0, TYPE_VECTOR_SUBPARTS (t), Type::tindex); -- d = new TypeSArray (d, e); -+ d = TypeSArray::makeType (Loc(), d, TYPE_VECTOR_SUBPARTS (t)); - - if (d->nextOf()->isTypeBasic() == NULL) - break; -@@ -194,18 +199,17 @@ gcc_type_to_d_type (tree t) - if (type_size != 8 && type_size != 16 && type_size != 32) - break; - -- d = new TypeVector (0, d); -- d = d->semantic (0, NULL); -+ d = new TypeVector (Loc(), d); - return d; - } - break; +@@ -1177,7 +1178,7 @@ + D_TYPE_IMAGINARY_FLOAT (d_ireal_type_node) = 1; - case RECORD_TYPE: -- for (size_t i = 0; i < builtin_converted_types.dim; i += 2) -+ for (size_t i = 0; i < vec_safe_length (builtin_converted_decls); ++i) - { -- tree ti = (tree) builtin_converted_types.data[i]; -+ tree ti = (*builtin_converted_decls)[i]->ctype; - if (TYPE_MAIN_VARIANT (ti) == TYPE_MAIN_VARIANT (t)) -- return (Type *) builtin_converted_types.data[i + 1]; -+ return (*builtin_converted_decls)[i]->dtype; - } + /* Used for ModuleInfo, ClassInfo, and Interface decls. */ +- d_unknown_type_node = make_node (LANG_TYPE); ++ d_unknown_type_node = make_node (RECORD_TYPE); - if (TYPE_NAME (t)) -@@ -217,7 +221,7 @@ gcc_type_to_d_type (tree t) - structname = structname_buf; - } + { + /* Make sure we get a unique function type, so we can give +--- a/src/gcc/d/d-codegen.cc ++++ b/src/gcc/d/d-codegen.cc +@@ -25,9 +25,8 @@ + #include "dfrontend/target.h" -- sdecl = new StructDeclaration (0, Lexer::idPool (structname)); -+ sdecl = new StructDeclaration (Loc(), Lexer::idPool (structname)); - // The gcc.builtins module may not exist yet, so cannot set - // sdecl->parent here. If it is va_list, the parent needs to - // be set to the object module which will not exist when -@@ -225,22 +229,18 @@ gcc_type_to_d_type (tree t) - sdecl->structsize = int_size_in_bytes (t); - sdecl->alignsize = TYPE_ALIGN_UNIT (t); - sdecl->sizeok = SIZEOKdone; -- -- d = new TypeStruct (sdecl); -- d->ctype = t; -- -- sdecl->type = d; -- sdecl->handle = d; -+ sdecl->type = new TypeStruct (sdecl); -+ sdecl->type->ctype = t; -+ sdecl->handle = sdecl->type; -+ sdecl->type->merge(); - - // Does not seem necessary to convert fields, but the - // members field must be non-null for the above size - // setting to stick. - sdecl->members = new Dsymbols; -- -- builtin_converted_types.push (t); -- builtin_converted_types.push (d); -- builtin_converted_decls.push (sdecl); -- return d; -+ d = sdecl->type; -+ vec_safe_push (builtin_converted_decls, new builtin_sym (sdecl, d, t)); -+ return sdecl->type; - - case FUNCTION_TYPE: - typefunc_ret= gcc_type_to_d_type (TREE_TYPE (t)); -@@ -290,30 +290,6 @@ gcc_type_to_d_type (tree t) - } +-Module *cmodule; ++Module *current_module_decl; + IRState *cirstate; +-ObjectFile *object_file; --// Hook from d_builtin_function. --// Add DECL to builtin functions list for maybe processing later --// if gcc.builtins was imported into the current module. -- --void --d_bi_builtin_func (tree decl) --{ -- if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl)) -- bi_lib_list = chainon (bi_lib_list, build_tree_list (0, decl)); -- -- bi_fn_list = chainon (bi_fn_list, build_tree_list (0, decl)); --} -- --// Hook from d_register_builtin_type. --// Add DECL to builtin types list for maybe processing later --// if gcc.builtins was imported into the current module. -- --void --d_bi_builtin_type (tree decl) --{ -- bi_type_list = chainon (bi_type_list, build_tree_list (0, decl)); --} -- -- - // Returns TRUE if M is a module that contains specially handled intrinsics. - // If module was never imported into current compilation, return false. -@@ -445,10 +421,10 @@ static void - d_gcc_magic_builtins_module (Module *m) + // Public routine called from D frontend to hide from glue interface. +@@ -37,7 +36,7 @@ + bool + d_gcc_force_templates (void) { - Dsymbols *funcs = new Dsymbols; -+ tree decl; +- return ObjectFile::emitTemplates == TEprivate; ++ return flag_emit_templates == TEprivate; + } -- for (tree n = bi_fn_list; n != NULL_TREE; n = TREE_CHAIN (n)) -+ for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i) + // Return the DECL_CONTEXT for symbol DSYM. +@@ -105,7 +104,7 @@ + if (sym->SframeField) { -- tree decl = TREE_VALUE (n); - const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); - TypeFunction *dtf = (TypeFunction *) gcc_type_to_d_type (TREE_TYPE (decl)); - -@@ -460,33 +436,34 @@ d_gcc_magic_builtins_module (Module *m) - if (dtf->parameters && dtf->parameters->dim == 0 && dtf->varargs) - continue; - -- // %% D2 - builtins are trusted and optionally nothrow. -- // The purity of a builtins can vary depending on compiler -- // flags set at init, or by the -foptions passed, such as -+ // D2 @safe/pure/nothrow functions. -+ // It is assumed that builtins solely provided by the compiler are -+ // considered @safe, pure and nothrow. Builtins that correspond to -+ // functions in the standard library that don't throw are considered -+ // @trusted. The purity of a builtin can vary depending on compiler -+ // flags set upon initialisation, or by the -foptions passed, such as - // flag_unsafe_math_optimizations. -- -- // Similiarly, if a builtin does not correspond to a function -- // in the standard library (is provided by the compiler), then -- // will also mark the function as weakly pure in the D frontend. -- dtf->trust = TREE_NOTHROW (decl) ? TRUSTtrusted : TRUSTsystem; -- dtf->isnothrow = TREE_NOTHROW (decl); -+ dtf->isnothrow = TREE_NOTHROW (decl) || !DECL_ASSEMBLER_NAME_SET_P (decl); - dtf->purity = DECL_PURE_P (decl) ? PUREstrong : - TREE_READONLY (decl) ? PUREconst : - DECL_IS_NOVOPS (decl) ? PUREweak : - !DECL_ASSEMBLER_NAME_SET_P (decl) ? PUREweak : - PUREimpure; -+ dtf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUSTsafe : -+ TREE_NOTHROW (decl) ? TRUSTtrusted : -+ TRUSTsystem; - -- FuncDeclaration *func = new FuncDeclaration (0, 0, Lexer::idPool (name), -+ FuncDeclaration *func = new FuncDeclaration (Loc(), Loc(), Lexer::idPool (name), - STCextern, dtf); -- func->isym = new Symbol; -- func->isym->Stree = decl; -+ func->csym = new Symbol; -+ func->csym->Sident = name; -+ func->csym->Stree = decl; - - funcs->push (func); + // Fixes debugging local variables. +- SET_DECL_VALUE_EXPR (var_decl, var (vd)); ++ SET_DECL_VALUE_EXPR (var_decl, get_decl_tree (vd, this->func)); + DECL_HAS_VALUE_EXPR_P (var_decl) = 1; } + var_exp = var_decl; +@@ -130,7 +129,7 @@ -- for (tree n = bi_type_list; n != NULL_TREE; n = TREE_CHAIN (n)) -+ for (size_t i = 0; vec_safe_iterate (gcc_builtins_types, i, &decl); ++i) + if (!no_init) { -- tree decl = TREE_VALUE (n); - tree type = TREE_TYPE (decl); - const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); - Type *dt = gcc_type_to_d_type (type); -@@ -494,7 +471,7 @@ d_gcc_magic_builtins_module (Module *m) - if (!dt) - continue; - -- funcs->push (new AliasDeclaration (0, Lexer::idPool (name), dt)); -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool (name), dt)); - } - - // Iterate through the target-specific builtin types for va_list. -@@ -510,13 +487,13 @@ d_gcc_magic_builtins_module (Module *m) - if (!dt) - continue; +- object_file->doLineNote (vd->loc); ++ set_input_location (vd->loc); -- funcs->push (new AliasDeclaration (0, Lexer::idPool (name), dt)); -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool (name), dt)); - } + if (!init_val) + { +@@ -216,11 +215,11 @@ } + } -- for (size_t i = 0; i < builtin_converted_decls.dim ; ++i) -+ for (size_t i = 0; i < vec_safe_length (builtin_converted_decls); ++i) - { -- Dsymbol *sym = builtin_converted_decls[i]; -+ Dsymbol *sym = (*builtin_converted_decls)[i]->decl; - // va_list is a pain. It can be referenced without importing - // gcc.builtins so it really needs to go in the object module. - if (!sym->parent) -@@ -524,48 +501,48 @@ d_gcc_magic_builtins_module (Module *m) - Declaration *decl = sym->isDeclaration(); - if (!decl || decl->type != Type::tvalist) - { -- sym->parent = m; - // Currently, there is no need to run semantic, but we do - // want to output inits, etc. -+ sym->parent = m; - funcs->push (sym); - } - } - } +-// Return the correct decl to be used for variable VD. +-// Could be a VAR_DECL, or a FIELD_DECL from a closure. ++// Return the correct decl to be used for variable DECL accessed from ++// function FUNC. Could be a VAR_DECL, or a FIELD_DECL from a closure. - // va_list should already be built, so no need to convert to D type again. -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_va_list"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_va_list"), - Type::tvalist)); - - // Provide access to target-specific integer types. -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_clong"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_clong"), - gcc_type_to_d_type (long_integer_type_node))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_culong"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_culong"), - gcc_type_to_d_type (long_unsigned_type_node))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_machine_byte"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_machine_byte"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (byte_mode, 0)))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_machine_ubyte"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_machine_ubyte"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (byte_mode, 1)))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_machine_int"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_machine_int"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (word_mode, 0)))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_machine_uint"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_machine_uint"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (word_mode, 1)))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_pointer_int"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_pointer_int"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (ptr_mode, 0)))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_pointer_uint"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_pointer_uint"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (ptr_mode, 1)))); - - // _Unwind_Word has it's own target specific mode. -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_unwind_int"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_unwind_int"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (targetm.unwind_word_mode(), 0)))); - -- funcs->push (new AliasDeclaration (0, Lexer::idPool ("__builtin_unwind_uint"), -+ funcs->push (new AliasDeclaration (Loc(), Lexer::idPool ("__builtin_unwind_uint"), - gcc_type_to_d_type (lang_hooks.types.type_for_mode (targetm.unwind_word_mode(), 1)))); + tree +-IRState::var (Declaration *decl) ++get_decl_tree (Declaration *decl, FuncDeclaration *func) + { + VarDeclaration *vd = decl->isVarDeclaration(); - m->members->push (new LinkDeclaration (LINKc, funcs)); -@@ -595,9 +572,10 @@ d_gcc_magic_libbuiltins_check (Dsymbol * - } - else if (fd && !fd->fbody) - { -- for (tree n = bi_lib_list; n != NULL_TREE; n = TREE_CHAIN (n)) -+ tree decl; -+ -+ for (size_t i = 0; vec_safe_iterate (gcc_builtins_libfuncs, i, &decl); ++i) +@@ -236,12 +235,10 @@ + else if (vsym->SframeField != NULL_TREE) { -- tree decl = TREE_VALUE (n); - gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl)); + // Get the closure holding the var decl. +- FuncDeclaration *fd = vd->toParent2()->isFuncDeclaration(); +- tree frame_ref = get_framedecl (this->func, fd); +- tree field = vsym->SframeField; ++ FuncDeclaration *parent = vd->toParent2()->isFuncDeclaration(); ++ tree frame_ref = get_framedecl (func, parent); - const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); -@@ -614,8 +592,9 @@ d_gcc_magic_libbuiltins_check (Dsymbol * - (*tf->parameters)[i]->storageClass |= STCref; - } - } -- fd->isym = new Symbol; -- fd->isym->Stree = decl; -+ fd->csym = new Symbol; -+ fd->csym->Sident = name; -+ fd->csym->Stree = decl; - return; - } - } -@@ -649,19 +628,19 @@ d_gcc_magic_module (Module *m) +- gcc_assert (field != NULL_TREE); +- return component_ref (build_deref (frame_ref), field); ++ return component_ref (build_deref (frame_ref), vsym->SframeField); + } + } - if (md->packages->dim == 1) - { -- if (!strcmp ((md->packages->tdata()[0])->string, "gcc")) -+ if (!strcmp ((*md->packages)[0]->string, "gcc")) - { - if (!strcmp (md->id->string, "builtins")) - d_gcc_magic_builtins_module (m); +@@ -301,7 +298,7 @@ } -- else if (!strcmp ((md->packages->tdata()[0])->string, "core")) -+ else if (!strcmp ((*md->packages)[0]->string, "core")) + else { - if (!strcmp (md->id->string, "bitop")) - std_intrinsic_module = m; - else if (!strcmp (md->id->string, "math")) - core_math_module = m; +- ::error ("can't convert a delegate expression to %s", target_type->toChars()); ++ error ("can't convert a delegate expression to %s", target_type->toChars()); + return error_mark (target_type); } -- else if (!strcmp ((md->packages->tdata()[0])->string, "std")) -+ else if (!strcmp ((*md->packages)[0]->string, "std")) - { - if (!strcmp (md->id->string, "math")) - std_math_module = m; -@@ -669,8 +648,8 @@ d_gcc_magic_module (Module *m) - } - else if (md->packages->dim == 2) - { -- if (!strcmp ((md->packages->tdata()[0])->string, "core") -- && !strcmp ((md->packages->tdata()[1])->string, "stdc")) -+ if (!strcmp ((*md->packages)[0]->string, "core") -+ && !strcmp ((*md->packages)[1]->string, "stdc")) - { - if (!strcmp (md->id->string, "stdarg")) - d_gcc_magic_stdarg_module (m); -@@ -699,31 +678,51 @@ gcc_cst_to_d_expr (tree cst) - complex_t value; - value.re = TREE_REAL_CST (TREE_REALPART (cst)); - value.im = TREE_REAL_CST (TREE_IMAGPART (cst)); -- return new ComplexExp (0, value, type); -+ return new ComplexExp (Loc(), value, type); + break; +@@ -321,7 +318,7 @@ + } + else + { +- ::error ("can't convert struct %s to %s", exp_type->toChars(), target_type->toChars()); ++ error ("can't convert struct %s to %s", exp_type->toChars(), target_type->toChars()); + return error_mark (target_type); + } + } +@@ -406,8 +403,8 @@ + + if ((dim * esize) % tsize != 0) + { +- ::error ("cannot cast %s to %s since sizes don't line up", +- exp_type->toChars(), target_type->toChars()); ++ error ("cannot cast %s to %s since sizes don't line up", ++ exp_type->toChars(), target_type->toChars()); + return error_mark (target_type); + } + dim = (dim * esize) / tsize; +@@ -430,8 +427,8 @@ } - else if (code == INTEGER_CST) + else { -- dinteger_t value = cst_to_hwi (TREE_INT_CST (cst)); -- return new IntegerExp (0, value, type); -+ dinteger_t value = tree_to_hwi (cst); -+ return new IntegerExp (Loc(), value, type); +- ::error ("cannot cast expression of type %s to type %s", +- exp_type->toChars(), target_type->toChars()); ++ error ("cannot cast expression of type %s to type %s", ++ exp_type->toChars(), target_type->toChars()); + return error_mark (target_type); } - else if (code == REAL_CST) - { -- real_t value = TREE_REAL_CST (cst); -- return new RealExp (0, value, type); -+ real_value value = TREE_REAL_CST (cst); -+ return new RealExp (Loc(), ldouble(value), type); + break; +@@ -474,8 +471,8 @@ } - else if (code == STRING_CST) + else { - const void *string = TREE_STRING_POINTER (cst); - size_t len = TREE_STRING_LENGTH (cst); -- return new StringExp (0, CONST_CAST (void *, string), len); -+ return new StringExp (Loc(), CONST_CAST (void *, string), len); -+ } -+ else if (code == VECTOR_CST) -+ { -+ dinteger_t nunits = VECTOR_CST_NELTS (cst); -+ Expressions *elements = new Expressions; -+ elements->setDim (nunits); -+ -+ for (size_t i = 0; i < nunits; i++) -+ { -+ Expression *elem = gcc_cst_to_d_expr (VECTOR_CST_ELT (cst, i)); -+ if (elem == NULL) -+ return NULL; -+ -+ (*elements)[i] = elem; -+ } -+ -+ Expression *e = new ArrayLiteralExp (Loc(), elements); -+ e->type = ((TypeVector *) type)->basetype; -+ -+ return new VectorExp (Loc(), e, type); +- ::error ("cannot cast expression of type %s to %s", +- exp_type->toChars(), target_type->toChars()); ++ error ("cannot cast expression of type %s to %s", ++ exp_type->toChars(), target_type->toChars()); + return error_mark (target_type); } - } -+ - return NULL; - } - --// Helper for d_gcc_eval_builtin. Evaluate builtin D --// function BUILTIN whose argument list is ARGUMENTS. --// Return result; NULL if cannot evaluate it. -+// Helper for d_gcc_eval_builtin. Evaluate builtin D function BUILTIN whose -+// argument list is ARGUMENTS. Return result; NULL if cannot evaluate it. - - Expression * - eval_builtin (Loc loc, BUILTIN builtin, Expressions *arguments) -@@ -732,10 +731,10 @@ eval_builtin (Loc loc, BUILTIN builtin, - Expression *arg0 = (*arguments)[0]; - Type *t0 = arg0->type; + break; +@@ -562,8 +559,15 @@ + tree index = build2 (RANGE_EXPR, Type::tsize_t->toCtype(), + integer_zero_node, build_integer_cst (count - 1)); + tree value = convert_for_assignment (expr, exp_type, sa_type->next); ++ ++ // Can't use VAR_DECLs in CONSTRUCTORS. ++ if (TREE_CODE (value) == VAR_DECL) ++ { ++ value = DECL_INITIAL (value); ++ gcc_assert (value); ++ } -- static IRState irs; - tree callee = NULL_TREE; - tree result; -- irs.doLineNote (loc); -+ -+ set_input_location (loc); +- CONSTRUCTOR_APPEND_ELT (ce, index, object_file->stripVarDecl (value)); ++ CONSTRUCTOR_APPEND_ELT (ce, index, value); + CONSTRUCTOR_ELTS (ctor) = ce; + } + TREE_READONLY (ctor) = 1; +@@ -597,23 +601,19 @@ + // Return a TREE representation of EXPR converted to represent parameter type ARG. - switch (builtin) + tree +-IRState::convertForArgument (Expression *expr, Parameter *arg) ++convert_for_argument (tree exp_tree, Expression *expr, Parameter *arg) + { + if (arg_reference_p (arg)) { -@@ -806,14 +805,14 @@ eval_builtin (Loc loc, BUILTIN builtin, - } - - TypeFunction *tf = (TypeFunction *) gcc_type_to_d_type (TREE_TYPE (callee)); -- result = irs.call (tf, callee, NULL, arguments); -+ result = d_build_call (tf, callee, NULL, arguments); - result = fold (result); +- tree exp_tree = expr->toElem (this); +- // front-end already sometimes automatically takes the address +- // TODO: Make this safer? Can this be confused by a non-zero SymOff? ++ // Front-end already sometimes automatically takes the address + if (expr->op != TOKaddress && expr->op != TOKsymoff && expr->op != TOKadd) + exp_tree = build_address (exp_tree); - // Special case bsr. - if (builtin == BUILTINbsr) - { - tree type = t0->toCtype(); -- tree lhs = size_int (tree_low_cst (TYPE_SIZE (type), 1) - 1); -+ tree lhs = size_int (TREE_INT_CST_LOW (TYPE_SIZE (type)) - 1); - result = fold_build2(MINUS_EXPR, type, - fold_convert (type, lhs), result); - } -@@ -826,7 +825,6 @@ eval_builtin (Loc loc, BUILTIN builtin, + return convert (type_passed_as (arg), exp_tree); } - - return e; -- +- else +- { +- // Lazy arguments: expr should already be a delegate +- return expr->toElem (this); +- } ++ ++ // Lazy arguments: expr should already be a delegate ++ return exp_tree; } - // Evaluate builtin D function FD whose argument list is ARGUMENTS. -@@ -845,10 +843,8 @@ d_gcc_eval_builtin (Loc loc, FuncDeclara - TypeFunction *tf = (TypeFunction *) fd->type; - tree callee = NULL_TREE; - -- // cirstate is not available. -- IRState irs; -- irs.doLineNote (loc); -- tree result = irs.call (tf, callee, NULL, arguments); -+ set_input_location (loc); -+ tree result = d_build_call (tf, callee, NULL, arguments); - result = fold (result); - - // Builtin should be successfully evaluated. -@@ -860,27 +856,85 @@ d_gcc_eval_builtin (Loc loc, FuncDeclara + // Perform default promotions for data used in expressions. +@@ -736,6 +736,8 @@ + TypeDelegate *t = new TypeDelegate (tf); + decl_type = t->merge()->toCtype(); } - } - -+// Perform a reinterpret cast of EXPR to type TYPE for use in CTFE. -+// The front end should have already ensured that EXPR is a constant, -+// so we just lower the value to GCC and return the converted CST. -+ - Expression * - d_gcc_paint_type (Expression *expr, Type *type) - { - /* We support up to 512-bit values. */ - unsigned char buffer[64]; -- int len; -- Expression *e; - tree cst; - -- if (type->isintegral()) -+ Type *tb = type->toBasetype(); -+ -+ if (expr->type->isintegral()) -+ cst = build_integer_cst (expr->toInteger(), expr->type->toCtype()); -+ else if (expr->type->isfloating()) - cst = build_float_cst (expr->toReal(), expr->type); -+ else if (expr->op == TOKarrayliteral) -+ { -+ // Build array as VECTOR_CST, assumes EXPR is constant. -+ Expressions *elements = ((ArrayLiteralExp *) expr)->elements; -+ vec *elms = NULL; -+ -+ vec_safe_reserve (elms, elements->dim); -+ for (size_t i = 0; i < elements->dim; i++) -+ { -+ Expression *e = (*elements)[i]; -+ if (e->type->isintegral()) -+ { -+ tree value = build_integer_cst (e->toInteger(), e->type->toCtype()); -+ CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value); -+ } -+ else if (e->type->isfloating()) -+ { -+ tree value = build_float_cst (e->toReal(), e->type); -+ CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value); -+ } -+ else -+ gcc_unreachable(); -+ } -+ -+ // Build vector type. -+ int nunits = ((TypeSArray *) expr->type)->dim->toUInteger(); -+ Type *telem = expr->type->nextOf(); -+ tree vectype = build_vector_type (telem->toCtype(), nunits); -+ -+ cst = build_vector_from_ctor (vectype, elms); -+ } - else -- cst = build_integer_cst (expr->toInteger(), expr->type->toCtype()); -+ gcc_unreachable(); - -- len = native_encode_expr (cst, buffer, sizeof (buffer)); -- cst = native_interpret_expr (type->toCtype(), buffer, len); -+ // Encode CST to buffer. -+ int len = native_encode_expr (cst, buffer, sizeof (buffer)); - -- e = gcc_cst_to_d_expr (cst); -- gcc_assert (e != NULL); -+ if (tb->ty == Tsarray) -+ { -+ // Interpret value as a vector of the same size, -+ // then return the array literal. -+ int nunits = ((TypeSArray *) type)->dim->toUInteger(); -+ Type *elem = type->nextOf(); -+ tree vectype = build_vector_type (elem->toCtype(), nunits); ++ else if (decl->isThisDeclaration()) ++ decl_type = insert_type_modifiers (decl_type, MODconst); -- return e; -+ cst = native_interpret_expr (vectype, buffer, len); -+ -+ Expression *e = gcc_cst_to_d_expr (cst); -+ gcc_assert (e != NULL && e->op == TOKvector); -+ -+ return ((VectorExp *) e)->e1; -+ } -+ else -+ { -+ // Normal interpret cast. -+ cst = native_interpret_expr (type->toCtype(), buffer, len); -+ -+ Expression *e = gcc_cst_to_d_expr (cst); -+ gcc_assert (e != NULL); -+ -+ return e; -+ } + return decl_type; } +@@ -1117,7 +1119,7 @@ + return d_array_length (exp); - /* Used to help initialize the builtin-types.def table. When a type of -@@ -979,9 +1033,9 @@ lookup_ctype_name (const char *p) + default: +- ::error ("can't determine the length of a %s", type->toChars()); ++ error ("can't determine the length of a %s", type->toChars()); + return error_mark (type); + } } +@@ -1300,7 +1302,7 @@ + split dynamic array varargs. */ + TYPE_LANG_SPECIFIC (rec_type) = build_d_type_lang_specific (type); - static void --do_build_builtin_fn (enum built_in_function fncode, -+do_build_builtin_fn (built_in_function fncode, - const char *name, -- enum built_in_class fnclass, -+ built_in_class fnclass, - tree fntype, bool both_p, bool fallback_p, - tree fnattrs, bool implicit_p) - { -@@ -1014,6 +1068,7 @@ enum d_builtin_type - #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME, - #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME, - #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) NAME, -+#define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) NAME, - #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME, - #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME, - #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME, -@@ -1031,6 +1086,7 @@ enum d_builtin_type - #undef DEF_FUNCTION_TYPE_5 - #undef DEF_FUNCTION_TYPE_6 - #undef DEF_FUNCTION_TYPE_7 -+#undef DEF_FUNCTION_TYPE_8 - #undef DEF_FUNCTION_TYPE_VAR_0 - #undef DEF_FUNCTION_TYPE_VAR_1 - #undef DEF_FUNCTION_TYPE_VAR_2 -@@ -1177,7 +1233,7 @@ d_init_builtins (void) - D_TYPE_IMAGINARY_FLOAT (d_ireal_type_node) = 1; - - /* Used for ModuleInfo, ClassInfo, and Interface decls. */ -- d_unknown_type_node = make_node (LANG_TYPE); -+ d_unknown_type_node = make_node (RECORD_TYPE); - - { - /* Make sure we get a unique function type, so we can give -@@ -1217,6 +1273,10 @@ d_init_builtins (void) - #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7) \ - def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); -+#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ -+ ARG6, ARG7, ARG8) \ -+ def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ -+ ARG7, ARG8); - #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \ - def_fn_type (ENUM, RETURN, 1, 0); - #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \ -@@ -1241,6 +1301,8 @@ d_init_builtins (void) - #undef DEF_FUNCTION_TYPE_4 - #undef DEF_FUNCTION_TYPE_5 - #undef DEF_FUNCTION_TYPE_6 -+#undef DEF_FUNCTION_TYPE_7 -+#undef DEF_FUNCTION_TYPE_8 - #undef DEF_FUNCTION_TYPE_VAR_0 - #undef DEF_FUNCTION_TYPE_VAR_1 - #undef DEF_FUNCTION_TYPE_VAR_2 -@@ -1267,7 +1329,10 @@ d_init_builtins (void) - build_common_builtin_nodes (); - } +- /* ObjectFile::declareType will try to declare it as top-level type ++ /* build_type_decl will try to declare it as top-level type + which can break debugging info for element types. */ + tree stub_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL, + get_identifier (type->toChars()), rec_type); +@@ -1667,7 +1669,7 @@ --/* Registration of machine- or os-specific builtin types. */ -+/* Registration of machine- or os-specific builtin types. -+ Add to builtin types list for maybe processing later -+ if gcc.builtins was imported into the current module. */ -+ - void - d_register_builtin_type (tree type, const char *name) - { -@@ -1278,28 +1343,25 @@ d_register_builtin_type (tree type, cons - if (!TYPE_NAME (type)) - TYPE_NAME (type) = decl; + // Deal with float mod expressions immediately. + if (code == FLOAT_MOD_EXPR) +- return floatMod (TREE_TYPE (arg0), arg0, arg1); ++ return build_float_modulus (TREE_TYPE (arg0), arg0, arg1); -- d_bi_builtin_type (decl); -+ vec_safe_push (gcc_builtins_types, decl); + if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1)) + return build_nop (type, build_offset_op (code, arg0, arg1)); +@@ -1793,83 +1795,6 @@ + return false; } --/* Return a definition for a builtin function named NAME and whose data type -- is TYPE. TYPE should be a function type with argument types. -- FUNCTION_CODE tells later passes how to compile calls to this function. -- See tree.h for its possible values. +-// Builds an array index expression from AE. ASC may build a +-// BIND_EXPR if temporaries were created for bounds checking. - -- If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, -- the name to be called if we can't opencode the function. If -- ATTRS is nonzero, use that for the function's attribute list. */ -+/* Add DECL to builtin functions list for maybe processing later -+ if gcc.builtins was imported into the current module. */ - - tree - d_builtin_function (tree decl) - { -- d_bi_builtin_func (decl); -+ if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl)) -+ vec_safe_push (gcc_builtins_libfuncs, decl); -+ -+ vec_safe_push (gcc_builtins_functions, decl); - return decl; - } - - - /* Table of machine-independent attributes supported in GIMPLE. */ --const struct attribute_spec d_builtins_attribute_table[] = -+const attribute_spec d_builtins_attribute_table[] = - { - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, - affects_type_identity } */ -@@ -1345,7 +1407,7 @@ const struct attribute_spec d_builtins_a - /* Give the specifications for the format attributes, used by C and all - descendants. */ - --const struct attribute_spec d_format_attribute_table[] = -+const attribute_spec d_format_attribute_table[] = - { - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, - affects_type_identity } */ -@@ -1687,30 +1749,29 @@ ignore_attribute (tree * ARG_UNUSED (nod - } - - --/* Backend init. */ -+// Backend init. - - void - d_backend_init (void) - { -- init_global_binding_level (); -+ init_global_binding_level(); - -- /* This allows the code in d-builtins2 to not have to worry about -- converting (C signed char *) to (D char *) for string arguments of -- built-in functions. -- Parameters are (signed_char = false, short_double = false). */ -+ // This allows the code in d-builtins.c to not have to worry about -+ // converting (C signed char *) to (D char *) for string arguments of -+ // built-in functions. -+ // Parameters are (signed_char = false, short_double = false). - build_common_tree_nodes (false, false); - -- d_init_builtins (); -+ d_init_builtins(); - - if (flag_exceptions) -- d_init_exceptions (); -+ d_init_exceptions(); - -- /* This is the C main, not the D main. */ -+ // This is the C main, not the D main. - main_identifier_node = get_identifier ("main"); - } - +-tree +-IRState::arrayElemRef (IndexExp *ae, ArrayScope *asc) +-{ +- Expression *e1 = ae->e1; +- Expression *e2 = ae->e2; - --/* Backend term. */ -+// Backend term. - - void - d_backend_term (void) ---- a/src/gcc/d/d-codegen.cc 2013-06-02 11:37:56.000000000 +0100 -+++ b/src/gcc/d/d-codegen.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-codegen.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -25,140 +25,92 @@ - #include "dfrontend/target.h" - - --Module *cmodule; --IRState *cirstate; --ObjectFile *object_file; -+Module *current_module_decl; -+IRState *current_irstate; - - --// Public routine called from D frontend to hide from glue interface. --// Returns TRUE if all templates are being emitted, either publicly --// or privately, into the current compilation. +- Type *base_type = e1->type->toBasetype(); +- TY base_type_ty = base_type->ty; +- // expression that holds the array data. +- tree array_expr = e1->toElem (this); +- // expression that indexes the array data +- tree subscript_expr = e2->toElem (this); +- // base pointer to the elements +- tree ptr_exp; +- // reference the the element +- tree elem_ref; - --bool --d_gcc_force_templates (void) --{ -- return ObjectFile::emitTemplates == TEprivate; --} +- switch (base_type_ty) +- { +- case Tarray: +- case Tsarray: +- array_expr = asc->setArrayExp (array_expr, e1->type); - - // Return the DECL_CONTEXT for symbol DSYM. - - tree - d_decl_context (Dsymbol *dsym) - { -- Dsymbol *orig_sym = dsym; -+ Dsymbol *parent = dsym; - AggregateDeclaration *ad; - -- while ((dsym = dsym->toParent2())) -+ while ((parent = parent->toParent2())) - { -- if (dsym->isFuncDeclaration()) -+ if (parent->isFuncDeclaration()) - { -- // dwarf2out chokes without this check... (output_pubnames) -- FuncDeclaration *f = orig_sym->isFuncDeclaration(); -- if (f && !needs_static_chain (f)) -+ FuncDeclaration *fd = dsym->isFuncDeclaration(); -+ if (fd && !needs_static_chain (fd)) - return NULL_TREE; - -- return dsym->toSymbol()->Stree; -+ return parent->toSymbol()->Stree; - } -- else if ((ad = dsym->isAggregateDeclaration())) -+ else if ((ad = parent->isAggregateDeclaration())) - { - tree context = ad->type->toCtype(); -+ // Want the underlying RECORD_TYPE. - if (ad->isClassDeclaration()) +- // If it's a static array and the index is constant, +- // the front end has already checked the bounds. +- if (array_bounds_check() && !(base_type_ty == Tsarray && e2->isConst())) +- { +- tree array_len_expr; +- // implement bounds check as a conditional expression: +- // array [inbounds(index) ? index : { throw ArrayBoundsError }] +- +- // First, set up the index expression to only be evaluated once. +- tree index_expr = maybe_make_temp (subscript_expr); +- +- if (base_type_ty == Tarray) - { -- // RECORD_TYPE instead of REFERENCE_TYPE -- context = TREE_TYPE (context); +- array_expr = maybe_make_temp (array_expr); +- array_len_expr = d_array_length (array_expr); - } -+ context = TREE_TYPE (context); -+ - return context; - } -- else if (dsym->isModule()) -- return dsym->toSymbol()->ScontextDecl; -+ else if (parent->isModule()) -+ { -+ // We've reached the top-level module namespace. -+ // Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing -+ // module, but only for extern(D) symbols. -+ Declaration *decl = dsym->isDeclaration(); -+ if (decl != NULL && decl->linkage != LINKd) -+ return NULL_TREE; -+ -+ return parent->toImport()->Stree; -+ } - } - - return NULL_TREE; - } - --// Add local variable VD into the current body. If NO_INIT, --// then variable does not have a default initialiser. -+// Add local variable VD into the current body of function fd. - - void --IRState::emitLocalVar (VarDeclaration *vd, bool no_init) -+build_local_var (VarDeclaration *vd, FuncDeclaration *fd) - { -- if (vd->isDataseg() || vd->isMember()) -- return; -+ gcc_assert (!vd->isDataseg() && !vd->isMember()); - - Symbol *sym = vd->toSymbol(); -- tree var_decl = sym->Stree; -- -- gcc_assert (!TREE_STATIC (var_decl)); -- pushdecl (var_decl); -+ tree var = sym->Stree; - -- if (TREE_CODE (var_decl) == CONST_DECL) -- return; -+ gcc_assert (!TREE_STATIC (var)); - -- DECL_CONTEXT (var_decl) = current_function_decl; -+ set_input_location (vd->loc); -+ d_pushdecl (var); -+ DECL_CONTEXT (var) = fd->toSymbol()->Stree; - - // Compiler generated symbols -- if (vd == this->func->vresult || vd == this->func->v_argptr -- || vd == this->func->v_arguments_var) -- DECL_ARTIFICIAL (var_decl) = 1; -+ if (vd == fd->vresult || vd == fd->v_argptr || vd == fd->v_arguments_var) -+ DECL_ARTIFICIAL (var) = 1; - -- tree var_exp; - if (sym->SframeField) - { - // Fixes debugging local variables. -- SET_DECL_VALUE_EXPR (var_decl, var (vd)); -- DECL_HAS_VALUE_EXPR_P (var_decl) = 1; -- } -- var_exp = var_decl; -- -- // Complete initializer expression (include MODIFY_EXPR, e.g.) -- tree init_exp = NULL_TREE; -- tree init_val = NULL_TREE; +- else +- array_len_expr = ((TypeSArray *) base_type)->dim->toElem (this); - -- if (!no_init && !DECL_INITIAL (var_decl) && vd->init) -- { -- if (!vd->init->isVoidInitializer()) -- { -- ExpInitializer *exp_init = vd->init->isExpInitializer(); -- Expression *ie = exp_init->toExpression(); -- init_exp = ie->toElem (this); +- subscript_expr = d_checked_index (ae->loc, index_expr, +- array_len_expr, false); - } +- +- if (base_type_ty == Tarray) +- ptr_exp = d_array_ptr (array_expr); - else -- no_init = true; +- ptr_exp = build_address (array_expr); +- +- // This conversion is required for static arrays and is just-to-be-safe +- // for dynamic arrays +- ptr_exp = convert (base_type->nextOf()->pointerTo()->toCtype(), ptr_exp); +- break; +- +- case Tpointer: +- // Ignores array scope. +- ptr_exp = array_expr; +- break; +- +- default: +- gcc_unreachable(); - } -- else -- gcc_assert (vd->init == NULL); - -- if (!no_init) -- { -- object_file->doLineNote (vd->loc); +- ptr_exp = void_okay_p (ptr_exp); +- subscript_expr = asc->finish (subscript_expr); +- elem_ref = indirect_ref (TREE_TYPE (TREE_TYPE (ptr_exp)), +- build_array_index (ptr_exp, subscript_expr)); - -- if (!init_val) -- { -- init_val = DECL_INITIAL (var_decl); -- DECL_INITIAL (var_decl) = NULL_TREE; -- } -- if (!init_exp && init_val) -- init_exp = build_vinit (var_exp, init_val); +- return elem_ref; +-} - -- if (init_exp) -- addExp (init_exp); -- else if (!init_val && vd->size (vd->loc)) -- // Zero-length arrays do not have an initializer -- warning (OPT_Wuninitialized, "uninitialized variable '%s'", vd->ident ? vd->ident->string : "(no name)"); -+ SET_DECL_VALUE_EXPR (var, get_decl_tree (vd, fd)); -+ DECL_HAS_VALUE_EXPR_P (var) = 1; - } - } - - // Return an unnamed local temporary of type TYPE. +- + void + IRState::doArraySet (tree in_ptr, tree in_value, tree in_count) + { +@@ -2070,9 +1995,9 @@ + if (call_by_alias_p (func, fd)) + { + // Re-evaluate symbol storage treating 'fd' as public. +- object_file->setupSymbolStorage (fd, callee, true); ++ setup_symbol_storage (fd, callee, true); + } +- object = getFrameForSymbol (fd); ++ object = get_frame_for_symbol (this->func, fd); + } + else if (fd->needThis()) + { +@@ -2182,7 +2107,7 @@ + { + // Actual arguments for declared formal arguments + Parameter *formal_arg = Parameter::getNth (formal_args, fi); +- arg_tree = convertForArgument (arg_exp, formal_arg); ++ arg_tree = convert_for_argument (arg_exp->toElem (this), arg_exp, formal_arg); + ++fi; + } + else +@@ -3019,7 +2944,7 @@ + // ARG0 and ARG1 are the arguments pass to the function. tree --build_local_var (tree type) -+build_local_temp (tree type) +-IRState::floatMod (tree type, tree arg0, tree arg1) ++build_float_modulus (tree type, tree arg0, tree arg1) { - tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type); + tree fmodfn = NULL_TREE; + tree basetype = type; +@@ -3037,7 +2962,7 @@ + if (!fmodfn) + { + // %qT pretty prints the tree type. +- ::error ("tried to perform floating-point modulo division on %qT", type); ++ error ("tried to perform floating-point modulo division on %qT", type); + return error_mark_node; + } - DECL_CONTEXT (decl) = current_function_decl; - DECL_ARTIFICIAL (decl) = 1; - DECL_IGNORED_P (decl) = 1; -- pushdecl (decl); -+ d_pushdecl (decl); +@@ -3130,20 +3055,20 @@ - return decl; - } -@@ -205,22 +157,22 @@ maybe_temporary_var (tree exp, tree *out - // Emit an INIT_EXPR for decl DECL. + switch (i) + { +- case 0: +- case 1: ++ case INTRINSIC_BSF: ++ case INTRINSIC_BSR: + if (!(strcmp (ftype->deco, FuintZint) == 0 || strcmp (ftype->deco, FulongZint) == 0)) + return; + break; - void --IRState::expandDecl (tree decl) -+expand_decl (tree decl) - { -- // nothing, pushdecl will add decl to a BIND_EXPR -+ // Nothing, d_pushdecl will add decl to a BIND_EXPR - if (DECL_INITIAL (decl)) - { - tree exp = build_vinit (decl, DECL_INITIAL (decl)); -- addExp (exp); -+ current_irstate->addExp (exp); - DECL_INITIAL (decl) = NULL_TREE; - } - } +- case 2: ++ case INTRINSIC_BSWAP: + if (!(strcmp (ftype->deco, FuintZuint) == 0)) + return; + break; --// Return the correct decl to be used for variable VD. --// Could be a VAR_DECL, or a FIELD_DECL from a closure. -+// Return the correct decl to be used for variable DECL accessed from -+// function FUNC. Could be a VAR_DECL, or a FIELD_DECL from a closure. +- case 3: +- case 4: +- case 5: ++ case INTRINSIC_BTC: ++ case INTRINSIC_BTR: ++ case INTRINSIC_BTS: + if (!(strcmp (ftype->deco, FlongplongZint) == 0 || strcmp (ftype->deco, FintpintZint) == 0)) + return; + break; +@@ -3170,27 +3095,31 @@ + if (i == -1) + return; - tree --IRState::var (Declaration *decl) -+get_decl_tree (Declaration *decl, FuncDeclaration *func) - { - VarDeclaration *vd = decl->isVarDeclaration(); ++ // Adjust 'i' for this range of enums ++ i += INTRINSIC_COS; ++ gcc_assert (i >= INTRINSIC_COS && i <= INTRINSIC_SQRT); ++ + switch (i) + { +- case 0: +- case 1: +- case 3: +- case 5: ++ case INTRINSIC_COS: ++ case INTRINSIC_FABS: ++ case INTRINSIC_RINT: ++ case INTRINSIC_SIN: + if (!(strcmp (ftype->deco, FeZe) == 0 || strcmp (ftype->deco, FeZe2) == 0)) + return; + break; -@@ -236,12 +188,10 @@ IRState::var (Declaration *decl) - else if (vsym->SframeField != NULL_TREE) - { - // Get the closure holding the var decl. -- FuncDeclaration *fd = vd->toParent2()->isFuncDeclaration(); -- tree frame_ref = get_framedecl (this->func, fd); -- tree field = vsym->SframeField; -+ FuncDeclaration *parent = vd->toParent2()->isFuncDeclaration(); -+ tree frame_ref = get_framedecl (func, parent); +- case 2: ++ case INTRINSIC_LDEXP: + if (!(strcmp (ftype->deco, FrealintZint) == 0)) + return; + break; -- gcc_assert (field != NULL_TREE); -- return component_ref (build_deref (frame_ref), field); -+ return component_ref (build_deref (frame_ref), vsym->SframeField); - } - } +- case 4: ++ case INTRINSIC_RNDTOL: + if (!(strcmp (ftype->deco, FrealZlong) == 0)) + return; + break; -@@ -255,33 +205,33 @@ tree - d_convert (tree type, tree exp) - { - // Check this first before passing to build_dtype. -- if (error_mark_p (type) || error_mark_p (TREE_TYPE (exp))) -+ if (error_operand_p (type) || error_operand_p (exp)) - return error_mark_node; - -- Type *target_type = build_dtype (type); -- Type *expr_type = build_dtype (TREE_TYPE (exp)); -+ Type *totype = build_dtype (type); -+ Type *etype = build_dtype (TREE_TYPE (exp)); - -- if (target_type && expr_type) -- return convert_expr (exp, expr_type, target_type); -+ if (totype && etype) -+ return convert_expr (exp, etype, totype); +- case 6: ++ case INTRINSIC_SQRT: + if (!(strcmp (ftype->deco, "FNaNbNfdZd") == 0 || //double + strcmp (ftype->deco, "FNaNbNffZf") == 0 || //& float version + strcmp (ftype->deco, FeZe) == 0 || +@@ -3199,9 +3128,6 @@ + break; + } - return convert (type, exp); - } +- // Adjust 'i' for this range of enums +- i += INTRINSIC_COS; +- gcc_assert (i >= INTRINSIC_COS && i <= INTRINSIC_SQRT); + tree t = decl->toSymbol()->Stree; --// Return expression EXP, whose type has been convert from EXP_TYPE to TARGET_TYPE. -+// Return expression EXP, whose type has been convert from ETYPE to TOTYPE. + // rndtol returns a long type, sqrt any float type, +@@ -3278,24 +3204,24 @@ - tree --convert_expr (tree exp, Type *exp_type, Type *target_type) -+convert_expr (tree exp, Type *etype, Type *totype) - { - tree result = NULL_TREE; + // Not setting this doesn't seem to cause problems (unlike VAR_DECLs). + if (loc.filename) +- object_file->setDeclLoc (decl, loc); ++ set_decl_location (decl, loc); -- gcc_assert (exp_type && target_type); -- Type *ebtype = exp_type->toBasetype(); -- Type *tbtype = target_type->toBasetype(); -+ gcc_assert (etype && totype); -+ Type *ebtype = etype->toBasetype(); -+ Type *tbtype = totype->toBasetype(); - -- if (d_types_same (exp_type, target_type)) -+ if (d_types_same (etype, totype)) - return exp; - -- if (error_mark_p (exp)) -+ if (error_operand_p (exp)) - return exp; - - switch (ebtype->ty) -@@ -290,8 +240,7 @@ convert_expr (tree exp, Type *exp_type, - if (tbtype->ty == Tdelegate) - { - exp = maybe_make_temp (exp); -- return build_delegate_cst (delegate_method (exp), delegate_object (exp), -- target_type); -+ return build_delegate_cst (delegate_method (exp), delegate_object (exp), totype); - } - else if (tbtype->ty == Tpointer) - { -@@ -301,28 +250,28 @@ convert_expr (tree exp, Type *exp_type, - } - else - { -- ::error ("can't convert a delegate expression to %s", target_type->toChars()); -- return error_mark (target_type); -+ error ("can't convert a delegate expression to %s", totype->toChars()); -+ return error_mark_node; - } - break; + return decl; + } - case Tstruct: - if (tbtype->ty == Tstruct) - { -- if (target_type->size() == exp_type->size()) -+ if (totype->size() == etype->size()) - { - // Allowed to cast to structs with same type size. -- result = build_vconvert (target_type->toCtype(), exp); -+ result = build_vconvert (totype->toCtype(), exp); - } - else if (tbtype->ty == Taarray) - { - tbtype = ((TypeAArray *) tbtype)->getImpl()->type; -- return convert_expr (exp, exp_type, tbtype); -+ return convert_expr (exp, etype, tbtype); - } - else - { -- ::error ("can't convert struct %s to %s", exp_type->toChars(), target_type->toChars()); -- return error_mark (target_type); -+ error ("can't convert struct %s to %s", etype->toChars(), totype->toChars()); -+ return error_mark_node; - } - } - // else, default conversion, which should produce an error -@@ -331,62 +280,56 @@ convert_expr (tree exp, Type *exp_type, - case Tclass: - if (tbtype->ty == Tclass) - { -- ClassDeclaration *target_class_decl = ((TypeClass *) tbtype)->sym; -- ClassDeclaration *obj_class_decl = ((TypeClass *) ebtype)->sym; -- bool use_dynamic = false; -+ ClassDeclaration *cdfrom = tbtype->isClassHandle(); -+ ClassDeclaration *cdto = ebtype->isClassHandle(); - int offset; +-// If NESTED_SYM is a nested function, return the static chain to be +-// used when invoking that function. ++// If SYM is a nested function, return the static chain to be ++// used when calling that function from FUNC. -- if (target_class_decl->isBaseOf (obj_class_decl, &offset)) -+ if (cdfrom->isBaseOf (cdto, &offset) && offset != OFFSET_RUNTIME) - { - // Casting up the inheritance tree: Don't do anything special. - // Cast to an implemented interface: Handle at compile time. -- if (offset == OFFSET_RUNTIME) -- use_dynamic = true; -- else if (offset) -+ if (offset) - { -- tree t = target_type->toCtype(); -+ tree t = totype->toCtype(); - exp = maybe_make_temp (exp); - return build3 (COND_EXPR, t, - build_boolop (NE_EXPR, exp, d_null_pointer), - build_nop (t, build_offset (exp, size_int (offset))), - build_nop (t, d_null_pointer)); - } -- else -- { -- // d_convert will make a NOP cast -- break; -- } -- } -- else if (target_class_decl == obj_class_decl) -- { -- // d_convert will make a NOP cast -+ -+ // d_convert will make a no-op cast - break; - } -- else if (!obj_class_decl->isCOMclass()) -- use_dynamic = true; +-// If NESTED_SYM is a nested class or struct, return the static chain +-// to be used when creating an instance of the class. ++// If SYM is a nested class or struct, return the static chain ++// to be used when creating an instance of the class from FUNC. -- if (use_dynamic) -- { -- // Otherwise, do dynamic cast -- tree args[2]; -+ // More cases for no-op cast -+ if (cdfrom == cdto) -+ break; + tree +-IRState::getFrameForSymbol (Dsymbol *nested_sym) ++get_frame_for_symbol (FuncDeclaration *func, Dsymbol *sym) + { +- FuncDeclaration *nested_func = NULL; ++ FuncDeclaration *nested_func = sym->isFuncDeclaration(); + FuncDeclaration *outer_func = NULL; -- args[0] = exp; -- args[1] = build_address (target_class_decl->toSymbol()->Stree); -+ if (cdfrom->cpp && cdto->cpp) -+ break; +- if ((nested_func = nested_sym->isFuncDeclaration())) ++ if (nested_func != NULL) + { + // Check that the nested function is properly defined. + if (!nested_func->fbody) +@@ -3308,16 +3234,19 @@ + outer_func = nested_func->toParent2()->isFuncDeclaration(); + gcc_assert (outer_func != NULL); -- return build_libcall (obj_class_decl->isInterfaceDeclaration() -- ? LIBCALL_INTERFACE_CAST : LIBCALL_DYNAMIC_CAST, 2, args); -- } -- else -+ // Casting from a C++ interface to a class/non-C++ interface -+ // always results in null as there is no runtime information, -+ // and no way one can derive from the other. -+ if (cdto->isCOMclass() || cdfrom->cpp != cdto->cpp) - { -- warning (OPT_Wcast_result, "cast to %s will produce null result", target_type->toChars()); -- result = d_convert (target_type->toCtype(), d_null_pointer); -+ warning (OPT_Wcast_result, "cast to %s will produce null result", totype->toChars()); -+ result = d_convert (totype->toCtype(), d_null_pointer); -+ // Make sure the expression is still evaluated if necessary - if (TREE_SIDE_EFFECTS (exp)) -- { -- // make sure the expression is still evaluated if necessary -- result = compound_expr (exp, result); -- } -+ result = compound_expr (exp, result); -+ - return result; - } -+ -+ // The offset can only be determined at runtime, do dynamic cast -+ tree args[2]; -+ args[0] = exp; -+ args[1] = build_address (cdfrom->toSymbol()->Stree); -+ -+ return build_libcall (cdto->isInterfaceDeclaration() -+ ? LIBCALL_INTERFACE_CAST : LIBCALL_DYNAMIC_CAST, 2, args); - } - // else default conversion - break; -@@ -394,7 +337,7 @@ convert_expr (tree exp, Type *exp_type, - case Tsarray: - if (tbtype->ty == Tpointer) - { -- result = build_nop (target_type->toCtype(), build_address (exp)); -+ result = build_nop (totype->toCtype(), build_address (exp)); - } - else if (tbtype->ty == Tarray) +- if (this->func != outer_func) ++ if (func != outer_func) { -@@ -406,40 +349,40 @@ convert_expr (tree exp, Type *exp_type, - - if ((dim * esize) % tsize != 0) +- Dsymbol *this_func = this->func; +- if (!this->func->vthis) // if no frame pointer for this function ++ // If no frame pointer for this function ++ if (!func->vthis) { -- ::error ("cannot cast %s to %s since sizes don't line up", -- exp_type->toChars(), target_type->toChars()); -- return error_mark (target_type); -+ error ("cannot cast %s to %s since sizes don't line up", -+ etype->toChars(), totype->toChars()); -+ return error_mark_node; +- nested_sym->error ("is a nested function and cannot be accessed from %s", this->func->toChars()); ++ sym->error ("is a nested function and cannot be accessed from %s", func->toChars()); + return d_null_pointer; } - dim = (dim * esize) / tsize; - - // Assumes casting to dynamic array of same type or void -- return d_array_value (target_type->toCtype(), -- size_int (dim), build_nop (ptrtype, build_address (exp))); -+ return d_array_value (totype->toCtype(), size_int (dim), -+ build_nop (ptrtype, build_address (exp))); - } - else if (tbtype->ty == Tsarray) - { - // D apparently allows casting a static array to any static array type -- return build_vconvert (target_type->toCtype(), exp); -+ return build_vconvert (totype->toCtype(), exp); - } - else if (tbtype->ty == Tstruct) - { - // And allows casting a static array to any struct type too. - // %% type sizes should have already been checked by the frontend. -- gcc_assert (target_type->size() == exp_type->size()); -- result = build_vconvert (target_type->toCtype(), exp); -+ gcc_assert (totype->size() == etype->size()); -+ result = build_vconvert (totype->toCtype(), exp); - } - else - { -- ::error ("cannot cast expression of type %s to type %s", -- exp_type->toChars(), target_type->toChars()); -- return error_mark (target_type); -+ error ("cannot cast expression of type %s to type %s", -+ etype->toChars(), totype->toChars()); -+ return error_mark_node; - } - break; - - case Tarray: - if (tbtype->ty == Tpointer) - { -- return d_convert (target_type->toCtype(), d_array_ptr (exp)); -+ return d_convert (totype->toCtype(), d_array_ptr (exp)); - } - else if (tbtype->ty == Tarray) - { -@@ -452,7 +395,7 @@ convert_expr (tree exp, Type *exp_type, - if (sz_src == sz_dst) - { - // Convert from void[] or elements are the same size -- don't change length -- return build_vconvert (target_type->toCtype(), exp); -+ return build_vconvert (totype->toCtype(), exp); - } - else +- /* Make sure we can get the frame pointer to the outer function, +- else we'll ICE later in tree-ssa. */ ++ ++ Dsymbol *this_func = func; ++ ++ // Make sure we can get the frame pointer to the outer function, ++ // else we'll ICE later in tree-ssa. + while (nested_func != this_func) { -@@ -463,49 +406,49 @@ convert_expr (tree exp, Type *exp_type, - args[1] = build_integer_cst (sz_src * mult, Type::tsize_t->toCtype()); - args[2] = exp; - -- return build_libcall (LIBCALL_ARRAYCAST, 3, args, target_type->toCtype()); -+ return build_libcall (LIBCALL_ARRAYCAST, 3, args, totype->toCtype()); - } - } - else if (tbtype->ty == Tsarray) - { - // %% Strings are treated as dynamic arrays D2. - if (ebtype->isString() && tbtype->isString()) -- return indirect_ref (target_type->toCtype(), d_array_ptr (exp)); -+ return indirect_ref (totype->toCtype(), d_array_ptr (exp)); - } - else - { -- ::error ("cannot cast expression of type %s to %s", -- exp_type->toChars(), target_type->toChars()); -- return error_mark (target_type); -+ error ("cannot cast expression of type %s to %s", -+ etype->toChars(), totype->toChars()); -+ return error_mark_node; - } - break; + FuncDeclaration *fd; +@@ -3327,7 +3256,7 @@ + // Special case for __ensure and __require. + if (nested_func->ident == Id::ensure || nested_func->ident == Id::require) + { +- outer_func = this->func; ++ outer_func = func; + break; + } - case Taarray: - if (tbtype->ty == Taarray) -- return build_vconvert (target_type->toCtype(), exp); -+ return build_vconvert (totype->toCtype(), exp); - else if (tbtype->ty == Tstruct) - { - ebtype = ((TypeAArray *) ebtype)->getImpl()->type; -- return convert_expr (exp, ebtype, target_type); -+ return convert_expr (exp, ebtype, totype); - } - // Can convert associative arrays to void pointers. - else if (tbtype == Type::tvoidptr) -- return build_vconvert (target_type->toCtype(), exp); -+ return build_vconvert (totype->toCtype(), exp); - // else, default conversion, which should product an error - break; +@@ -3335,12 +3264,14 @@ + { + if (outer_func == fd->toParent2()) + break; ++ + gcc_assert (fd->isNested() || fd->vthis); + } + else if ((cd = this_func->isClassDeclaration())) + { + if (!cd->isNested() || !cd->vthis) + goto cannot_get_frame; ++ + if (outer_func == cd->toParent2()) + break; + } +@@ -3348,13 +3279,14 @@ + { + if (!sd->isNested() || !sd->vthis) + goto cannot_get_frame; ++ + if (outer_func == sd->toParent2()) + break; + } + else + { +- cannot_get_frame: +- this->func->error ("cannot get frame pointer to %s", nested_sym->toChars()); ++ cannot_get_frame: ++ func->error ("cannot get frame pointer to %s", sym->toChars()); + return d_null_pointer; + } + this_func = this_func->toParent2(); +@@ -3366,33 +3298,41 @@ + /* It's a class (or struct). NewExp::toElem has already determined its + outer scope is not another class, so it must be a function. */ - case Tpointer: - // Can convert void pointers to associative arrays too... - if (tbtype->ty == Taarray && ebtype == Type::tvoidptr) -- return build_vconvert (target_type->toCtype(), exp); -+ return build_vconvert (totype->toCtype(), exp); - break; +- Dsymbol *sym = nested_sym; +- +- while (sym && !(outer_func = sym->isFuncDeclaration())) ++ while (sym && !sym->isFuncDeclaration()) + sym = sym->toParent2(); - case Tnull: - if (tbtype->ty == Tarray) ++ outer_func = (FuncDeclaration *) sym; ++ + /* Make sure we can access the frame of outer_func. */ +- if (outer_func != this->func) ++ if (outer_func != func) { - tree ptrtype = tbtype->nextOf()->pointerTo()->toCtype(); -- return d_array_value (target_type->toCtype(), -- size_int (0), build_nop (ptrtype, exp)); -+ return d_array_value (totype->toCtype(), size_int (0), -+ build_nop (ptrtype, exp)); - } - break; +- Dsymbol *o = nested_func = this->func; +- do { ++ nested_func = func; ++ while (nested_func && nested_func != outer_func) ++ { ++ Dsymbol *outer = nested_func->toParent2(); ++ + if (!nested_func->isNested()) + { + if (!nested_func->isMember2()) + goto cannot_access_frame; + } +- while ((o = o->toParent2())) ++ ++ while (outer) + { +- if ((nested_func = o->isFuncDeclaration())) ++ if (outer->isFuncDeclaration()) + break; ++ ++ outer = outer->toParent2(); + } +- } while (o && o != outer_func); -@@ -513,57 +456,61 @@ convert_expr (tree exp, Type *exp_type, - if (tbtype->ty == Tsarray) - { - if (tbtype->size() == ebtype->size()) -- return build_vconvert (target_type->toCtype(), exp); -+ return build_vconvert (totype->toCtype(), exp); +- if (!o) ++ nested_func = (FuncDeclaration *) outer; ++ } ++ ++ if (!nested_func) + { +- cannot_access_frame: ++ cannot_access_frame: + error ("cannot access frame of function '%s' from '%s'", +- outer_func->toChars(), this->func->toChars()); ++ outer_func->toChars(), func->toChars()); + return d_null_pointer; + } } - break; +@@ -3400,11 +3340,12 @@ - default: -- exp = fold_convert (exp_type->toCtype(), exp); -+ exp = fold_convert (etype->toCtype(), exp); - gcc_assert (TREE_CODE (exp) != STRING_CST); - break; - } + if (!outer_func) + outer_func = nested_func->toParent2()->isFuncDeclaration(); ++ + gcc_assert (outer_func != NULL); + + FuncFrameInfo *ffo = get_frameinfo (outer_func); + if (ffo->creates_frame || ffo->static_chain) +- return get_framedecl (this->func, outer_func); ++ return get_framedecl (func, outer_func); - return result ? result : -- convert (target_type->toCtype(), exp); -+ convert (totype->toCtype(), exp); + return d_null_pointer; + } +@@ -3444,39 +3385,39 @@ } --// Apply semantics of assignment to a values of type TARGET_TYPE to EXPR -+// Apply semantics of assignment to a values of type TOTYPE to EXPR - // (e.g., pointer = array -> pointer = &array[0]) - --// Return a TREE representation of EXPR implictly converted to TARGET_TYPE -+// Return a TREE representation of EXPR implictly converted to TOTYPE - // for use in assignment expressions MODIFY_EXPR, INIT_EXPR... +-// Starting from the current function, try to find a suitable value of +-// 'this' in nested function instances. +- +-// A suitable 'this' value is an instance of OCD or a class that has +-// OCD as a base. ++// Starting from the current function FUNC, try to find a suitable value of ++// 'this' in nested function instances. A suitable 'this' value is an ++// instance of OCD or a class that has OCD as a base. - tree --convert_for_assignment (tree expr, Type *exp_type, Type *target_type) -+convert_for_assignment (tree expr, Type *etype, Type *totype) +-tree +-IRState::findThis (ClassDeclaration *ocd) ++static tree ++find_this_tree (FuncDeclaration *func, ClassDeclaration *ocd) { -- Type *ebtype = exp_type->toBasetype(); -- Type *tbtype = target_type->toBasetype(); -+ Type *ebtype = etype->toBasetype(); -+ Type *tbtype = totype->toBasetype(); - - // Assuming this only has to handle converting a non Tsarray type to - // arbitrarily dimensioned Tsarrays. - if (tbtype->ty == Tsarray) - { -- Type *sa_elem_type = tbtype->nextOf()->toBasetype(); +- FuncDeclaration *fd = func; - -- while (sa_elem_type->ty == Tsarray) -- sa_elem_type = sa_elem_type->nextOf()->toBasetype(); -+ Type *telem = tbtype->nextOf()->baseElemOf(); +- while (fd) ++ while (func) + { +- AggregateDeclaration *ad = fd->isThis(); ++ AggregateDeclaration *ad = func->isThis(); + ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL; -- if (d_types_compatible (sa_elem_type, ebtype)) -+ if (d_types_compatible (telem, ebtype)) + if (cd != NULL) { - // %% what about implicit converions...? - TypeSArray *sa_type = (TypeSArray *) tbtype; - uinteger_t count = sa_type->dim->toUInteger(); - -- tree ctor = build_constructor (target_type->toCtype(), NULL); -+ tree ctor = build_constructor (totype->toCtype(), NULL); - if (count) - { - vec *ce = NULL; - tree index = build2 (RANGE_EXPR, Type::tsize_t->toCtype(), - integer_zero_node, build_integer_cst (count - 1)); -- tree value = convert_for_assignment (expr, exp_type, sa_type->next); -+ tree value = convert_for_assignment (expr, etype, sa_type->next); + if (ocd == cd) +- return var (fd->vthis); ++ return get_decl_tree (func->vthis, func); + else if (ocd->isBaseOf (cd, NULL)) +- return convert_expr (var (fd->vthis), cd->type, ocd->type); +- else +- fd = d_nested_class (cd); ++ return convert_expr (get_decl_tree (func->vthis, func), cd->type, ocd->type); + -+ // Can't use VAR_DECLs in CONSTRUCTORS. -+ if (TREE_CODE (value) == VAR_DECL) -+ { -+ value = DECL_INITIAL (value); -+ gcc_assert (value); -+ } - -- CONSTRUCTOR_APPEND_ELT (ce, index, object_file->stripVarDecl (value)); -+ CONSTRUCTOR_APPEND_ELT (ce, index, value); - CONSTRUCTOR_ELTS (ctor) = ce; - } - TREE_READONLY (ctor) = 1; -@@ -579,7 +526,7 @@ convert_for_assignment (tree expr, Type - if (integer_zerop (expr)) ++ func = d_nested_class (cd); + } + else { - StructDeclaration *sd = ((TypeStruct *) tbtype)->sym; -- tree var = build_local_var (target_type->toCtype()); -+ tree var = build_local_temp (totype->toCtype()); - - tree init = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMSET), 3, - build_address (var), expr, -@@ -591,29 +538,25 @@ convert_for_assignment (tree expr, Type - gcc_unreachable(); - } - -- return convert_expr (expr, exp_type, target_type); -+ return convert_expr (expr, etype, totype); - } - - // Return a TREE representation of EXPR converted to represent parameter type ARG. - - tree --IRState::convertForArgument (Expression *expr, Parameter *arg) -+convert_for_argument (tree exp_tree, Expression *expr, Parameter *arg) - { - if (arg_reference_p (arg)) - { -- tree exp_tree = expr->toElem (this); -- // front-end already sometimes automatically takes the address -- // TODO: Make this safer? Can this be confused by a non-zero SymOff? -+ // Front-end already sometimes automatically takes the address - if (expr->op != TOKaddress && expr->op != TOKsymoff && expr->op != TOKadd) - exp_tree = build_address (exp_tree); - - return convert (type_passed_as (arg), exp_tree); +- if (fd->isNested()) +- fd = fd->toParent2()->isFuncDeclaration(); +- else +- fd = NULL; ++ if (func->isNested()) ++ { ++ func = func->toParent2()->isFuncDeclaration(); ++ continue; ++ } ++ ++ func = NULL; + } } -- else -- { -- // Lazy arguments: expr should already be a delegate -- return expr->toElem (this); -- } + -+ // Lazy arguments: expr should already be a delegate -+ return exp_tree; + return NULL_TREE; } - // Perform default promotions for data used in expressions. -@@ -633,7 +576,7 @@ convert_for_condition (tree expr, Type * - { - case Taarray: - // Shouldn't this be... -- // result = build_libcall (LIBCALL_AALEN, 1, &expr); -+ // result = _aaLen (&expr); - result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr))); - break; - -@@ -687,17 +630,17 @@ convert_for_condition (tree expr, Type * - // EXP must be a static array or dynamic array. +@@ -3500,7 +3441,7 @@ - tree --IRState::toDArray (Expression *exp) -+d_array_convert (Expression *exp) - { - TY ty = exp->type->toBasetype()->ty; - -- if (ty == Tsarray) -+ if (ty == Tarray) -+ return exp->toElem (current_irstate); -+ else if (ty == Tsarray) - { - Type *totype = exp->type->toBasetype()->nextOf()->arrayOf(); -- return convert_expr (exp->toElem (this), exp->type, totype); -+ return convert_expr (exp->toElem (current_irstate), exp->type, totype); - } -- else if (ty == Tarray) -- return exp->toElem (this); + if (cdo) + { +- vthis_value = findThis (cdo); ++ vthis_value = find_this_tree (this->func, cdo); + if (vthis_value == NULL_TREE) + e->error ("outer class %s 'this' needed to 'new' nested class %s", + cdo->toChars(), cd->toChars()); +@@ -3516,9 +3457,9 @@ + FuncFrameInfo *ffo = get_frameinfo (fdo); + if (ffo->creates_frame || ffo->static_chain + || fdo->hasNestedFrameRefs()) +- vthis_value = getFrameForSymbol (cd); ++ vthis_value = get_frame_for_symbol (this->func, cd); + else if (fdo->vthis && fdo->vthis->type != Type::tvoidptr) +- vthis_value = var (fdo->vthis); ++ vthis_value = get_decl_tree (fdo->vthis, this->func); + else + vthis_value = d_null_pointer; + } +@@ -3533,7 +3474,7 @@ - // Invalid type passed. - gcc_unreachable(); -@@ -736,6 +679,8 @@ declaration_type (Declaration *decl) - TypeDelegate *t = new TypeDelegate (tf); - decl_type = t->merge()->toCtype(); - } -+ else if (decl->isThisDeclaration()) -+ decl_type = insert_type_modifiers (decl_type, MODconst); + if (cdo) + { +- vthis_value = findThis (cdo); ++ vthis_value = find_this_tree (this->func, cdo); + if (vthis_value == NULL_TREE) + e->error ("outer class %s 'this' needed to create nested struct %s", + cdo->toChars(), sd->toChars()); +@@ -3543,9 +3484,9 @@ + FuncFrameInfo *ffo = get_frameinfo (fdo); + if (ffo->creates_frame || ffo->static_chain + || fdo->hasNestedFrameRefs()) +- vthis_value = getFrameForSymbol (sd); ++ vthis_value = get_frame_for_symbol (this->func, sd); + else if (fdo->vthis && fdo->vthis->type != Type::tvoidptr) +- vthis_value = var (fdo->vthis); ++ vthis_value = get_decl_tree (fdo->vthis, this->func); + else + vthis_value = d_null_pointer; + } +@@ -3620,6 +3561,7 @@ + tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, + get_identifier ("__chain"), ptr_type_node); + DECL_CONTEXT (ptr_field) = frame_rec_type; ++ TYPE_READONLY (frame_rec_type) = 1; - return decl_type; - } -@@ -765,6 +710,7 @@ tree - type_passed_as (Parameter *arg) - { - tree arg_type = arg->type->toCtype(); -+ - if (arg_reference_p (arg)) - arg_type = build_reference_type (arg_type); - else if (arg->storageClass & STClazy) -@@ -773,6 +719,7 @@ type_passed_as (Parameter *arg) - TypeDelegate *t = new TypeDelegate (tf); - arg_type = t->merge()->toCtype(); - } -+ - return arg_type; - } + tree fields = chainon (NULL_TREE, ptr_field); -@@ -794,11 +741,13 @@ d_array_type (Type *d_type, uinteger_t s - NULL_TREE); +@@ -3672,7 +3614,7 @@ + v->ident ? get_identifier (v->ident->string) : NULL_TREE, + declaration_type (v)); + s->SframeField = field; +- object_file->setDeclLoc (field, v); ++ set_decl_location (field, v); + DECL_CONTEXT (field) = frame_rec_type; + fields = chainon (fields, field); + TREE_USED (s->Stree) = 1; +@@ -3980,7 +3922,7 @@ + tree ident = var_decl->ident ? get_identifier (var_decl->ident->string) : NULL_TREE; + tree field_decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, ident, + declaration_type (var_decl)); +- object_file->setDeclLoc (field_decl, var_decl); ++ set_decl_location (field_decl, var_decl); + var_decl->csym = new Symbol; + var_decl->csym->Stree = field_decl; - tree array_type = build_array_type (type_node, index_type_node); -+ - if (size == 0) - { - TYPE_SIZE (array_type) = bitsize_zero_node; - TYPE_SIZE_UNIT (array_type) = size_zero_node; - } -+ - return array_type; - } +@@ -4035,7 +3977,7 @@ + DECL_FIELD_BIT_OFFSET (field_decl) = bitsize_zero_node; -@@ -853,7 +802,7 @@ d_attribute_p (const char* name) - return false; + // Must set this or we crash with DWARF debugging. +- object_file->setDeclLoc (field_decl, l); ++ set_decl_location (field_decl, l); - table = new StringTable(); -- table->init(n); -+ table->_init(n); - - for (const attribute_spec *p = d_attribute_table; p->name; p++) - table->insert(p->name, strlen(p->name)); -@@ -876,19 +825,22 @@ build_attributes (Expressions *in_attrs) + TREE_THIS_VOLATILE (field_decl) = TYPE_VOLATILE (TREE_TYPE (field_decl)); - for (size_t i = 0; i < in_attrs->dim; i++) - { -- Expression *attr = (*in_attrs)[i]->ctfeInterpret(); -+ Expression *attr = (*in_attrs)[i]->optimize (WANTexpand); - Dsymbol *sym = attr->type->toDsymbol (0); - - if (!sym) - continue; - -- Dsymbol *mod = (Dsymbol*) sym->getModule(); -+ Dsymbol *mod = (Dsymbol*) sym->getModule(); - if (!(strcmp(mod->toChars(), "attribute") == 0 -- && mod->parent -+ && mod->parent != NULL - && strcmp(mod->parent->toChars(), "gcc") == 0 - && !mod->parent->parent)) - continue; +--- a/src/gcc/d/d-codegen.h ++++ b/src/gcc/d/d-codegen.h +@@ -163,6 +163,7 @@ + extern tree build_two_field_type (tree t1, tree t2, Type *type, const char *n1, const char *n2); + + extern tree build_exception_object (void); ++extern tree build_float_modulus (tree type, tree t1, tree t2); + + extern tree indirect_ref (tree type, tree exp); + extern tree build_deref (tree exp); +@@ -220,6 +221,9 @@ + extern FuncFrameInfo *get_frameinfo (FuncDeclaration *fd); + extern tree get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer); -+ if (attr->op == TOKcall) -+ attr = attr->ctfeInterpret(); ++// Static chain for nested functions ++extern tree get_frame_for_symbol (FuncDeclaration *func, Dsymbol *sym); + - gcc_assert(attr->op == TOKstructliteral); - Expressions *elem = ((StructLiteralExp*) attr)->elements; + extern bool needs_static_chain (FuncDeclaration *f); -@@ -921,7 +873,7 @@ build_attributes (Expressions *in_attrs) - aet = build_string (s->len, (const char *) s->string); - } - else -- aet = ae->toElem (cirstate); -+ aet = ae->toElem (current_irstate); + // Local variables +@@ -227,6 +231,8 @@ + extern tree create_temporary_var (tree type); + extern tree maybe_temporary_var (tree exp, tree *out_var); - args = chainon (args, build_tree_list (0, aet)); - } -@@ -975,31 +927,29 @@ tree - build_integer_cst (dinteger_t value, tree type) ++extern tree get_decl_tree (Declaration *decl, FuncDeclaration *func); ++ + // Temporaries (currently just SAVE_EXPRs) + extern tree maybe_make_temp (tree t); + extern bool d_has_side_effects (tree t); +@@ -405,22 +411,17 @@ { - // The type is error_mark_node, we can't do anything. -- if (error_mark_p (type)) -+ if (error_operand_p (type)) - return type; - - return build_int_cst_type (type, value); - } + public: + // ** Local variables +- void emitLocalVar (VarDeclaration *v, bool no_init = false); ++ void emitLocalVar (VarDeclaration *v, bool no_init); --// Build REAL_CST of type TARGET_TYPE with the value VALUE. -+// Build REAL_CST of type TOTYPE with the value VALUE. + void expandDecl (tree t_decl); - tree --build_float_cst (const real_t& value, Type *target_type) -+build_float_cst (const real_t& value, Type *totype) - { - real_t new_value; -- TypeBasic *tb = target_type->isTypeBasic(); -+ TypeBasic *tb = totype->isTypeBasic(); - - gcc_assert (tb != NULL); - - tree type_node = tb->toCtype(); - real_convert (&new_value.rv(), TYPE_MODE (type_node), &value.rv()); - -+ // Value grew as a result of the conversion. %% precision bug ?? -+ // For now just revert back to original. - if (new_value > value) -- { -- // value grew as a result of the conversion. %% precision bug ?? -- // For now just revert back to original. -- new_value = value; -- } -+ new_value = value; +- tree var (Declaration *decl); +- + // ** Type conversion +- tree convertForArgument (Expression *exp, Parameter *arg); + tree toDArray (Expression *exp); - return build_real (type_node, new_value.rv()); - } -@@ -1022,8 +972,11 @@ cst_to_hwi (double_int cst) - dinteger_t - tree_to_hwi (tree t) - { -- if (host_integerp (t, 0) || host_integerp (t, 1)) -- return tree_low_cst (t, 1); -+ if (TREE_INT_CST_HIGH (t) == 0 -+ || (TREE_INT_CST_HIGH (t) == -1 -+ && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0 -+ && !TYPE_UNSIGNED (TREE_TYPE (t)))) -+ return TREE_INT_CST_LOW (t); + // ** Various expressions + static tree buildOp (enum tree_code code, tree type, tree arg0, tree arg1); + tree buildAssignOp (enum tree_code code, Type *type, Expression *e1, Expression *e2); - return cst_to_hwi (TREE_INT_CST (t)); - } -@@ -1034,7 +987,7 @@ tree - d_array_length (tree exp) - { - // backend will ICE otherwise -- if (error_mark_p (exp)) -+ if (error_operand_p (exp)) - return exp; - - // Get the backend type for the array and pick out the array -@@ -1049,7 +1002,7 @@ tree - d_array_ptr (tree exp) - { - // backend will ICE otherwise -- if (error_mark_p (exp)) -+ if (error_operand_p (exp)) - return exp; - - // Get the backend type for the array and pick out the array -@@ -1091,7 +1044,7 @@ tree - d_array_string (const char *str) - { - unsigned len = strlen (str); -- // Assumes str is null-terminated. -+ // Assumes STR is 0-terminated. - tree str_tree = build_string (len + 1, str); +- tree arrayElemRef (IndexExp *aer_exp, ArrayScope *aryscp); +- + void doArraySet (tree in_ptr, tree in_value, tree in_count); + tree arraySetExpr (tree ptr, tree value, tree count); - TREE_TYPE (str_tree) = d_array_type (Type::tchar, len); -@@ -1117,8 +1070,8 @@ get_array_length (tree exp, Type *type) - return d_array_length (exp); +@@ -430,26 +431,19 @@ + tree call (FuncDeclaration *func_decl, tree object, Expressions *args); + tree call (TypeFunction *guess, tree callable, tree object, Expressions *arguments); - default: -- ::error ("can't determine the length of a %s", type->toChars()); -- return error_mark (type); -+ error ("can't determine the length of a %s", type->toChars()); -+ return error_mark_node; - } - } +- static tree floatMod (tree type, tree arg0, tree arg1); +- + tree typeinfoReference (Type *t); -@@ -1140,6 +1093,52 @@ unhandled_arrayop_p (BinExp *exp) - return false; - } + void buildChain (FuncDeclaration *func); -+// Create BINFO for a ClassDeclaration's inheritance tree. -+// Interfaces are not included. -+ -+tree -+build_class_binfo (tree super, ClassDeclaration *cd) -+{ -+ tree binfo = make_tree_binfo (1); -+ tree ctype = cd->type->toCtype(); -+ -+ // Want RECORD_TYPE, not REFERENCE_TYPE -+ BINFO_TYPE (binfo) = TREE_TYPE (ctype); -+ BINFO_INHERITANCE_CHAIN (binfo) = super; -+ BINFO_OFFSET (binfo) = integer_zero_node; -+ -+ if (cd->baseClass) -+ BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass)); -+ -+ return binfo; -+} -+ -+// Create BINFO for an InterfaceDeclaration's inheritance tree. -+// In order to access all inherited methods in the debugger, -+// the entire tree must be described. -+// This function makes assumptions about interface layout. -+ -+tree -+build_interface_binfo (tree super, ClassDeclaration *cd, unsigned& offset) -+{ -+ tree binfo = make_tree_binfo (cd->baseclasses->dim); -+ tree ctype = cd->type->toCtype(); -+ -+ // Want RECORD_TYPE, not REFERENCE_TYPE -+ BINFO_TYPE (binfo) = TREE_TYPE (ctype); -+ BINFO_INHERITANCE_CHAIN (binfo) = super; -+ BINFO_OFFSET (binfo) = size_int (offset * Target::ptrsize); -+ BINFO_VIRTUAL_P (binfo) = 1; -+ -+ for (size_t i = 0; i < cd->baseclasses->dim; i++, offset++) -+ { -+ BaseClass *bc = (*cd->baseclasses)[i]; -+ BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->base, offset)); -+ } -+ -+ return binfo; -+} -+ - // Returns the .funcptr component from the D delegate EXP. +- tree findThis (ClassDeclaration *target_cd); + tree getVThis (Dsymbol *decl, Expression *e); - tree -@@ -1163,7 +1162,7 @@ delegate_object (tree exp) - } +- // Static chain for nested functions +- tree getFrameForSymbol (Dsymbol *nested_sym); +- + protected: + tree maybeExpandSpecialCall (tree call_exp); + }; - // Build a delegate literal of type TYPE whose pointer function is --// METHOD, and hidden object is OBJECT. -+// METHOD, and hidden object is OBJECT. + // Globals. +-extern Module *cmodule; ++extern Module *current_module_decl; + extern IRState *cirstate; +-extern ObjectFile *object_file; - tree - build_delegate_cst (tree method, tree object, Type *type) -@@ -1254,7 +1253,7 @@ get_object_method (tree thisexp, Express + // Various helpers that need extra state - if (objexp->op == TOKsuper - || objtype->ty == Tstruct || objtype->ty == Tpointer -- || func->isFinal() || !func->isVirtual() || is_dottype) -+ || func->isFinalFunc() || !func->isVirtual() || is_dottype) - { - if (objtype->ty == Tstruct) - thisexp = build_address (thisexp); -@@ -1287,56 +1286,58 @@ get_object_method (tree thisexp, Express - tree - build_two_field_type (tree t1, tree t2, Type *type, const char *n1, const char *n2) - { -- tree rec_type = make_node (RECORD_TYPE); -+ tree rectype = make_node (RECORD_TYPE); - tree f0 = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier (n1), t1); - tree f1 = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier (n2), t2); -- DECL_CONTEXT (f0) = rec_type; -- DECL_CONTEXT (f1) = rec_type; -- TYPE_FIELDS (rec_type) = chainon (f0, f1); -- layout_type (rec_type); -+ -+ DECL_CONTEXT (f0) = rectype; -+ DECL_CONTEXT (f1) = rectype; -+ TYPE_FIELDS (rectype) = chainon (f0, f1); -+ layout_type (rectype); -+ - if (type) - { -- /* This is needed so that maybeExpandSpecialCall knows to -- split dynamic array varargs. */ -- TYPE_LANG_SPECIFIC (rec_type) = build_d_type_lang_specific (type); +--- a/src/gcc/d/d-ctype.cc ++++ b/src/gcc/d/d-ctype.cc +@@ -272,9 +272,7 @@ + } + } + TYPE_VALUES (ctype) = enum_values; - -- /* ObjectFile::declareType will try to declare it as top-level type -- which can break debugging info for element types. */ -- tree stub_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL, -- get_identifier (type->toChars()), rec_type); -- TYPE_STUB_DECL (rec_type) = stub_decl; -- TYPE_NAME (rec_type) = stub_decl; -- DECL_ARTIFICIAL (stub_decl) = 1; -- rest_of_decl_compilation (stub_decl, 0, 0); -+ tree ident = get_identifier (type->toChars()); -+ tree stubdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, ident, rectype); -+ -+ TYPE_STUB_DECL (rectype) = stubdecl; -+ TYPE_NAME (rectype) = stubdecl; -+ DECL_ARTIFICIAL (stubdecl) = 1; -+ rest_of_decl_compilation (stubdecl, 1, 0); +- object_file->initTypeDecl (ctype, sym); +- object_file->declareType (ctype, sym); ++ build_type_decl (ctype, sym); + } } -- return rec_type; -+ -+ return rectype; - } --// Create a SAVE_EXPR if T might have unwanted side effects if referenced -+// Create a SAVE_EXPR if EXP might have unwanted side effects if referenced - // more than once in an expression. +@@ -311,7 +309,7 @@ + agg_layout.go(); + agg_layout.finish (sym->userAttributes); - tree --maybe_make_temp (tree t) -+make_temp (tree exp) - { -- if (d_has_side_effects (t)) -- { -- if (TREE_CODE (t) == CALL_EXPR -- || TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE) -- return save_expr (t); -- else -- return stabilize_reference (t); -- } -+ if (TREE_CODE (exp) == CALL_EXPR -+ || TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE) -+ return save_expr (exp); -+ else -+ return stabilize_reference (exp); -+} +- object_file->initTypeDecl (ctype, sym); ++ build_type_decl (ctype, sym); + TYPE_CONTEXT (ctype) = d_decl_context (sym); + } + } +@@ -672,7 +670,7 @@ -- return t; -+tree -+maybe_make_temp (tree exp) -+{ -+ if (d_has_side_effects (exp)) -+ return make_temp (exp); -+ -+ return exp; - } + agg_layout.finish (sym->userAttributes); --// Return TRUE if T can not be evaluated multiple times (i.e., in a loop body) -+// Return TRUE if EXP can not be evaluated multiple times (i.e., in a loop body) - // without unwanted side effects. +- object_file->initTypeDecl (rec_type, sym); ++ build_type_decl (rec_type, sym); + TYPE_CONTEXT (rec_type) = d_decl_context (sym); + } + } +--- a/src/gcc/d/d-decls.cc ++++ b/src/gcc/d/d-decls.cc +@@ -164,10 +164,10 @@ - bool --d_has_side_effects (tree expr) -+d_has_side_effects (tree exp) - { -- tree t = STRIP_NOPS (expr); -+ tree t = STRIP_NOPS (exp); + DECL_LANG_SPECIFIC (var_decl) = build_d_decl_lang_specific (this); + d_keep (var_decl); +- object_file->setDeclLoc (var_decl, this); ++ set_decl_location (var_decl, this); - // SAVE_EXPR is safe to reference more than once, but not to - // expand in a loop. -@@ -1362,14 +1363,14 @@ tree - build_address (tree exp) - { - tree t, ptrtype; -- tree exp_type = TREE_TYPE (exp); -+ tree type = TREE_TYPE (exp); - d_mark_addressable (exp); + if (decl_kind == VAR_DECL) +- object_file->setupSymbolStorage (this, var_decl); ++ setup_symbol_storage (this, var_decl, false); + else if (decl_kind == PARM_DECL) + { + /* from gcc code: Some languages have different nominal and real types. */ +@@ -234,18 +234,12 @@ + insert_decl_attributes (var_decl, "dllexport"); + #endif - // Gimplify doesn't like &(* (ptr-to-array-type)) with static arrays - if (TREE_CODE (exp) == INDIRECT_REF) - { - t = TREE_OPERAND (exp, 0); -- ptrtype = build_pointer_type (exp_type); -+ ptrtype = build_pointer_type (type); - t = build_nop (ptrtype, t); - } - else -@@ -1377,18 +1378,18 @@ build_address (tree exp) - /* Just convert string literals (char[]) to C-style strings (char *), otherwise - the latter method (char[]*) causes conversion problems during gimplification. */ - if (TREE_CODE (exp) == STRING_CST) -- ptrtype = build_pointer_type (TREE_TYPE (exp_type)); -+ ptrtype = build_pointer_type (TREE_TYPE (type)); - /* Special case for va_list. The backends will be expecting a pointer to vatype, - * but some targets use an array. So fix it. */ -- else if (TYPE_MAIN_VARIANT (exp_type) == TYPE_MAIN_VARIANT (va_list_type_node)) -+ else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node)) +- if (isDataseg() && isThreadlocal()) ++ if (global.params.vtls && isDataseg() && isThreadlocal()) { -- if (TREE_CODE (TYPE_MAIN_VARIANT (exp_type)) == ARRAY_TYPE) -- ptrtype = build_pointer_type (TREE_TYPE (exp_type)); -+ if (TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE) -+ ptrtype = build_pointer_type (TREE_TYPE (type)); - else -- ptrtype = build_pointer_type (exp_type); -+ ptrtype = build_pointer_type (type); +- // Tell backend this is a thread local decl. +- DECL_TLS_MODEL (var_decl) = decl_default_tls_model (var_decl); +- +- if (global.params.vtls) +- { +- char *p = loc.toChars(); +- fprintf (stderr, "%s: %s is thread local\n", p ? p : "", toChars()); +- if (p) +- free (p); +- } ++ char *p = loc.toChars(); ++ fprintf (stderr, "%s: %s is thread local\n", p ? p : "", toChars()); ++ if (p) ++ free (p); } - else -- ptrtype = build_pointer_type (exp_type); -+ ptrtype = build_pointer_type (type); + } + return csym; +@@ -282,9 +276,9 @@ + TREE_TYPE (csym->Stree) = TREE_TYPE (TREE_TYPE (csym->Stree)); + TREE_USED (csym->Stree) = 1; - t = build1 (ADDR_EXPR, ptrtype, exp); +- // In gdc, built-in typeinfo will be referenced as one-only. ++ // Built-in typeinfo will be referenced as one-only. + D_DECL_ONE_ONLY (csym->Stree) = 1; +- object_file->makeDeclOneOnly (csym->Stree); ++ d_comdat_linkage (csym->Stree); } -@@ -1532,6 +1533,79 @@ d_mark_read (tree exp) - return exp; + return csym; } +@@ -477,8 +471,8 @@ + else if (isExport()) + insert_decl_attributes (fndecl, "dllexport"); + #endif +- object_file->setDeclLoc (fndecl, this); +- object_file->setupSymbolStorage (this, fndecl); ++ set_decl_location (fndecl, this); ++ setup_symbol_storage (this, fndecl, false); + if (!ident) + TREE_PUBLIC (fndecl) = 0; -+// Build equality expression between two RECORD_TYPES T1 and T2. -+// CODE is the EQ_EXPR or NE_EXPR comparison. -+// SD is the front-end struct type. -+ -+tree -+build_struct_memcmp (tree_code code, StructDeclaration *sd, tree t1, tree t2) -+{ -+ tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; -+ tree tmemcmp = NULL_TREE; -+ -+ // Let backend take care of empty struct or union comparisons. -+ if (!sd->fields.dim || sd->isUnionDeclaration()) -+ { -+ tmemcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -+ build_address (t1), build_address (t2), -+ size_int (sd->structsize)); -+ -+ return build_boolop (code, tmemcmp, integer_zero_node); -+ } -+ -+ for (size_t i = 0; i < sd->fields.dim; i++) -+ { -+ VarDeclaration *vd = sd->fields[i]; -+ tree sfield = vd->toSymbol()->Stree; -+ -+ tree t1ref = component_ref (t1, sfield); -+ tree t2ref = component_ref (t2, sfield); -+ tree tcmp; -+ -+ if (vd->type->ty == Tstruct) -+ { -+ // Compare inner data structures. -+ StructDeclaration *decl = ((TypeStruct *) vd->type)->sym; -+ tcmp = build_struct_memcmp (code, decl, t1ref, t2ref); -+ } -+ else -+ { -+ tree stype = vd->type->toCtype(); -+ machine_mode mode = int_mode_for_mode (TYPE_MODE (stype)); -+ -+ if (vd->type->isintegral()) -+ { -+ // Integer comparison, no special handling required. -+ tcmp = build_boolop (code, t1ref, t2ref); -+ } -+ else if (mode != BLKmode) -+ { -+ // Compare field bits as their corresponding integer type. -+ // *((T*) &t1) == *((T*) &t2) -+ tree tmode = lang_hooks.types.type_for_mode (mode, 1); -+ -+ t1ref = build_vconvert (tmode, t1ref); -+ t2ref = build_vconvert (tmode, t2ref); -+ -+ tcmp = build_boolop (code, t1ref, t2ref); -+ } -+ else -+ { -+ // Simple memcmp between types. -+ tcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -+ build_address (t1ref), build_address (t2ref), -+ TYPE_SIZE_UNIT (stype)); -+ -+ tcmp = build_boolop (code, tcmp, integer_zero_node); -+ } -+ } -+ -+ tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp; -+ } -+ -+ return tmemcmp; -+} -+ - // Cast EXP (which should be a pointer) to TYPE * and then indirect. The - // back-end requires this cast in many cases. +@@ -569,7 +563,7 @@ + d_keep (thunk_decl); + sthunk->Stree = thunk_decl; -@@ -1606,7 +1680,7 @@ build_array_index (tree ptr, tree index) +- object_file->doThunk (thunk_decl, target_func_decl, offset); ++ use_thunk (thunk_decl, target_func_decl, offset); + + thunk->symbol = sthunk; } +@@ -591,8 +585,8 @@ + csym->Stree = decl; + d_keep (decl); - // backend will ICE otherwise -- if (error_mark_p (result_type_node)) -+ if (error_operand_p (result_type_node)) - return result_type_node; - - if (integer_zerop (index)) -@@ -1619,7 +1693,7 @@ build_array_index (tree ptr, tree index) - // OP could be a plus or minus expression. +- object_file->setupStaticStorage (this, decl); +- object_file->setDeclLoc (decl, this); ++ setup_symbol_storage (this, decl, true); ++ set_decl_location (decl, this); - tree --build_offset_op (enum tree_code op, tree ptr, tree idx) -+build_offset_op (tree_code op, tree ptr, tree idx) - { - gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR); + // ClassInfo cannot be const data, because we use the monitor on it. + TREE_CONSTANT (decl) = 0; +@@ -614,8 +608,8 @@ + csym->Stree = decl; + d_keep (decl); -@@ -1656,7 +1730,7 @@ void_okay_p (tree t) - // and ARG1. Perform relevant conversions needs for correct code operations. +- object_file->setupStaticStorage (this, decl); +- object_file->setDeclLoc (decl, this); ++ setup_symbol_storage (this, decl, true); ++ set_decl_location (decl, this); - tree --IRState::buildOp (tree_code code, tree type, tree arg0, tree arg1) -+build_binary_op (tree_code code, tree type, tree arg0, tree arg1) + TREE_CONSTANT (decl) = 1; + } +@@ -636,8 +630,8 @@ + csym->Stree = decl; + d_keep (decl); + +- object_file->setupStaticStorage (this, decl); +- object_file->setDeclLoc (decl, this); ++ setup_symbol_storage (this, decl, true); ++ set_decl_location (decl, this); + + // Not readonly, moduleinit depends on this. + TREE_CONSTANT (decl) = 0; +@@ -655,8 +649,6 @@ { - tree t0 = TREE_TYPE (arg0); - tree t1 = TREE_TYPE (arg1); -@@ -1667,7 +1741,7 @@ IRState::buildOp (tree_code code, tree t + if (!vtblsym) + { +- tree decl; +- + vtblsym = toSymbolX ("__vtbl", 0, 0, "Z"); - // Deal with float mod expressions immediately. - if (code == FLOAT_MOD_EXPR) -- return floatMod (TREE_TYPE (arg0), arg0, arg1); -+ return build_float_modulus (TREE_TYPE (arg0), arg0, arg1); + /* The DECL_INITIAL value will have a different type object from the +@@ -664,13 +656,13 @@ + TypeSArray *vtbl_type = new TypeSArray (Type::tvoidptr, + new IntegerExp (loc, vtbl.dim, Type::tindex)); - if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1)) - return build_nop (type, build_offset_op (code, arg0, arg1)); -@@ -1687,8 +1761,8 @@ IRState::buildOp (tree_code code, tree t - } - else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp)) +- decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, +- get_identifier (vtblsym->Sident), vtbl_type->toCtype()); ++ tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, ++ get_identifier (vtblsym->Sident), vtbl_type->toCtype()); + vtblsym->Stree = decl; + d_keep (decl); + +- object_file->setupStaticStorage (this, decl); +- object_file->setDeclLoc (decl, this); ++ setup_symbol_storage (this, decl, true); ++ set_decl_location (decl, this); + + TREE_READONLY (decl) = 1; + TREE_CONSTANT (decl) = 1; +@@ -700,31 +692,35 @@ + { + if (!sinit) { -- t = build2 (code, unsignedp ? d_unsigned_type (type) : d_signed_type (type), -- arg0, arg1); -+ tree inttype = unsignedp ? d_unsigned_type (type) : d_signed_type (type); -+ t = build2 (code, inttype, arg0, arg1); ++ StructDeclaration *sd = isStructDeclaration(); + sinit = toSymbolX ("__init", 0, 0, "Z"); + +- StructDeclaration *sd = isStructDeclaration(); + if (sd) + sinit->Salignment = sd->alignment; } - else - { -@@ -1705,34 +1779,6 @@ IRState::buildOp (tree_code code, tree t - return d_convert (type, t); - } --// Build an assignment expression of code CODE, data type TYPE, and --// operands E1 and E2. -- --tree --IRState::buildAssignOp (tree_code code, Type *type, Expression *e1, Expression *e2) --{ -- // Skip casts for lhs assignment. -- Expression *e1b = e1; -- while (e1b->op == TOKcast) -- { -- CastExp *ce = (CastExp *) e1b; -- gcc_assert (d_types_compatible (ce->type, ce->to)); -- e1b = ce->e1; -- } -- -- // Prevent multiple evaluations of LHS -- tree lhs = e1b->toElem (this); -- lhs = stabilize_reference (lhs); -- -- tree rhs = buildOp (code, e1->type->toCtype(), -- convert_expr (lhs, e1b->type, e1->type), e2->toElem (this)); -- -- tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type)); -- -- return convert_expr (expr, e1b->type, type); --} +- if (!sinit->Stree && object_file != NULL) ++ if (!sinit->Stree && current_module_decl) + { +- tree struct_type = type->toCtype(); +- if (POINTER_TYPE_P (struct_type)) +- struct_type = TREE_TYPE (struct_type); // for TypeClass, want the RECORD_TYPE, not the REFERENCE_TYPE +- tree t = build_decl (UNKNOWN_LOCATION, VAR_DECL, +- get_identifier (sinit->Sident), struct_type); +- sinit->Stree = t; +- d_keep (t); - +- object_file->setupStaticStorage (this, t); +- object_file->setDeclLoc (t, this); - - // Builds an array bounds checking condition, returning INDEX if true, - // else throws a RangeError exception. - -@@ -1781,7 +1827,7 @@ array_bounds_check (void) - if (result == 1) - { - // For D2 safe functions only -- FuncDeclaration *func = cirstate->func; -+ FuncDeclaration *func = current_irstate->func; - if (func && func->type->ty == Tfunction) - { - TypeFunction *tf = (TypeFunction *) func->type; -@@ -1793,133 +1839,6 @@ array_bounds_check (void) - return false; +- TREE_ADDRESSABLE (t) = 1; +- TREE_READONLY (t) = 1; +- TREE_CONSTANT (t) = 1; +- DECL_CONTEXT (t) = 0; // These are always global ++ tree stype; ++ if (isStructDeclaration()) ++ stype = type->toCtype(); ++ else ++ stype = TREE_TYPE (type->toCtype()); ++ ++ sinit->Stree = build_decl (UNKNOWN_LOCATION, VAR_DECL, ++ get_identifier (sinit->Sident), stype); ++ d_keep (sinit->Stree); ++ ++ setup_symbol_storage (this, sinit->Stree, true); ++ set_decl_location (sinit->Stree, this); ++ ++ TREE_ADDRESSABLE (sinit->Stree) = 1; ++ TREE_READONLY (sinit->Stree) = 1; ++ TREE_CONSTANT (sinit->Stree) = 1; ++ // These initialisers are always global. ++ DECL_CONTEXT (sinit->Stree) = 0; + } ++ + return sinit; } --// Builds an array index expression from AE. ASC may build a --// BIND_EXPR if temporaries were created for bounds checking. -- --tree --IRState::arrayElemRef (IndexExp *ae, ArrayScope *asc) --{ -- Expression *e1 = ae->e1; -- Expression *e2 = ae->e2; -- -- Type *base_type = e1->type->toBasetype(); -- TY base_type_ty = base_type->ty; -- // expression that holds the array data. -- tree array_expr = e1->toElem (this); -- // expression that indexes the array data -- tree subscript_expr = e2->toElem (this); -- // base pointer to the elements -- tree ptr_exp; -- // reference the the element -- tree elem_ref; -- -- switch (base_type_ty) -- { -- case Tarray: -- case Tsarray: -- array_expr = asc->setArrayExp (array_expr, e1->type); -- -- // If it's a static array and the index is constant, -- // the front end has already checked the bounds. -- if (array_bounds_check() && !(base_type_ty == Tsarray && e2->isConst())) -- { -- tree array_len_expr; -- // implement bounds check as a conditional expression: -- // array [inbounds(index) ? index : { throw ArrayBoundsError }] -- -- // First, set up the index expression to only be evaluated once. -- tree index_expr = maybe_make_temp (subscript_expr); -- -- if (base_type_ty == Tarray) -- { -- array_expr = maybe_make_temp (array_expr); -- array_len_expr = d_array_length (array_expr); -- } -- else -- array_len_expr = ((TypeSArray *) base_type)->dim->toElem (this); -- -- subscript_expr = d_checked_index (ae->loc, index_expr, -- array_len_expr, false); -- } -- -- if (base_type_ty == Tarray) -- ptr_exp = d_array_ptr (array_expr); -- else -- ptr_exp = build_address (array_expr); -- -- // This conversion is required for static arrays and is just-to-be-safe -- // for dynamic arrays -- ptr_exp = convert (base_type->nextOf()->pointerTo()->toCtype(), ptr_exp); -- break; -- -- case Tpointer: -- // Ignores array scope. -- ptr_exp = array_expr; -- break; +@@ -733,28 +729,23 @@ + Symbol * + TypedefDeclaration::toInitializer (void) + { +- Symbol *s; - -- default: -- gcc_unreachable(); + if (!sinit) ++ sinit = toSymbolX ("__init", 0, 0, "Z"); ++ ++ if (!sinit->Stree && current_module_decl) + { +- s = toSymbolX ("__init", 0, 0, "Z"); +- sinit = s; +- sinit->Sdt = ((TypeTypedef *) type)->sym->init->toDt(); - } - -- ptr_exp = void_okay_p (ptr_exp); -- subscript_expr = asc->finish (subscript_expr); -- elem_ref = indirect_ref (TREE_TYPE (TREE_TYPE (ptr_exp)), -- build_array_index (ptr_exp, subscript_expr)); -- -- return elem_ref; --} -- -- --void --IRState::doArraySet (tree in_ptr, tree in_value, tree in_count) --{ -- startBindings(); -- -- tree count = build_local_var (size_type_node); -- DECL_INITIAL (count) = in_count; -- expandDecl (count); -- -- tree ptr = build_local_var (TREE_TYPE (in_ptr)); -- DECL_INITIAL (ptr) = in_ptr; -- expandDecl (ptr); -- -- tree ptr_type = TREE_TYPE (ptr); -- tree count_type = TREE_TYPE (count); -- -- tree value = NULL_TREE; -- -- if (!d_has_side_effects (in_value)) -- value = in_value; -- else +- if (!sinit->Stree && object_file != NULL) - { -- value = build_local_var (TREE_TYPE (in_value)); -- DECL_INITIAL (value) = in_value; -- expandDecl (value); -- } -- -- startLoop (NULL); -- continueHere(); -- exitIfFalse (build2 (NE_EXPR, boolean_type_node, -- d_convert (TREE_TYPE (count), integer_zero_node), count)); -- -- addExp (vmodify_expr (build_deref (ptr), value)); -- addExp (vmodify_expr (ptr, build_offset (ptr, TYPE_SIZE_UNIT (TREE_TYPE (ptr_type))))); -- addExp (vmodify_expr (count, build2 (MINUS_EXPR, count_type, count, -- d_convert (count_type, integer_one_node)))); -- -- endLoop(); -- endBindings(); --} -- --// Create a tree node to set multiple elements to a single value --tree --IRState::arraySetExpr (tree ptr, tree value, tree count) --{ -- pushStatementList(); -- doArraySet (ptr, value, count); -- return popStatementList(); --} +- tree t = build_decl (UNKNOWN_LOCATION, VAR_DECL, +- get_identifier (sinit->Sident), type->toCtype()); +- sinit->Stree = t; +- d_keep (t); - - // Builds a BIND_EXPR around BODY for the variables VAR_CHAIN. - - tree -@@ -1935,7 +1854,7 @@ bind_expr (tree var_chain, tree body) - body = compound_expr (ini, body); +- object_file->setupStaticStorage (this, t); +- object_file->setDeclLoc (t, this); +- TREE_CONSTANT (t) = 1; +- TREE_READONLY (t) = 1; +- DECL_CONTEXT (t) = 0; ++ sinit->Stree = build_decl (UNKNOWN_LOCATION, VAR_DECL, ++ get_identifier (sinit->Sident), type->toCtype()); ++ d_keep (sinit->Stree); ++ ++ setup_symbol_storage (this, sinit->Stree, true); ++ set_decl_location (sinit->Stree, this); ++ ++ TREE_CONSTANT (sinit->Stree) = 1; ++ TREE_READONLY (sinit->Stree) = 1; ++ DECL_CONTEXT (sinit->Stree) = 0; } - -- return save_expr (build3 (BIND_EXPR, TREE_TYPE (body), var_chain, body, NULL_TREE)); -+ return make_temp (build3 (BIND_EXPR, TREE_TYPE (body), var_chain, body, NULL_TREE)); - } - - // Like compound_expr, but ARG0 or ARG1 might be NULL_TREE. -@@ -1964,17 +1883,6 @@ maybe_vcompound_expr (tree arg0, tree ar - return vcompound_expr (arg0, arg1); ++ + return sinit; } --// Returns TRUE if T is an ERROR_MARK node. -- --bool --error_mark_p (tree t) --{ -- return (t == error_mark_node -- || (t && TREE_TYPE (t) == error_mark_node) -- || (t && TREE_CODE (t) == NOP_EXPR -- && TREE_OPERAND (t, 0) == error_mark_node)); --} +@@ -763,31 +754,29 @@ + Symbol * + EnumDeclaration::toInitializer (void) + { +- Symbol *s; - - // Returns the TypeFunction class for Type T. - // Assumes T is already ->toBasetype() - -@@ -2014,133 +1922,46 @@ call_by_alias_p (FuncDeclaration *caller - return true; - } + if (!sinit) + { + Identifier *ident_save = ident; + if (!ident) + ident = Lexer::uniqueId("__enum"); +- s = toSymbolX ("__init", 0, 0, "Z"); ++ sinit = toSymbolX ("__init", 0, 0, "Z"); + ident = ident_save; +- sinit = s; + } --// Entry point for call routines. Extracts the callee, object, --// and function type from expression EXPR, passing down ARGUMENTS. +- if (!sinit->Stree && object_file != NULL) ++ if (!sinit->Stree && current_module_decl) + { +- tree t = build_decl (UNKNOWN_LOCATION, VAR_DECL, +- get_identifier (sinit->Sident), type->toCtype()); +- sinit->Stree = t; +- d_keep (t); - --tree --IRState::call (Expression *expr, Expressions *arguments) --{ -- // Calls to delegates can sometimes look like this: -- if (expr->op == TOKcomma) -- { -- CommaExp *ce = (CommaExp *) expr; -- expr = ce->e2; -- -- VarExp *ve; -- gcc_assert (ce->e2->op == TOKvar); -- ve = (VarExp *) ce->e2; -- gcc_assert (ve->var->isFuncDeclaration() && !ve->var->needThis()); -- } -- -- Type *t = expr->type->toBasetype(); -- TypeFunction *tf = NULL; -- tree callee = expr->toElem (this); -- tree object = NULL_TREE; -- -- if (D_METHOD_CALL_EXPR (callee)) -- { -- /* This could be a delegate expression (TY == Tdelegate), but not -- actually a delegate variable. */ -- // %% Is this ever not a DotVarExp ? -- if (expr->op == TOKdotvar) -- { -- /* This gets the true function type, the latter way can sometimes -- be incorrect. Example: ref functions in D2. */ -- tf = get_function_type (((DotVarExp *) expr)->var->type); -- } -- else -- tf = get_function_type (t); -- -- extract_from_method_call (callee, callee, object); -- } -- else if (t->ty == Tdelegate) -- { -- tf = (TypeFunction *) ((TypeDelegate *) t)->next; -- callee = maybe_make_temp (callee); -- object = delegate_object (callee); -- callee = delegate_method (callee); -- } -- else if (expr->op == TOKvar) -- { -- FuncDeclaration *fd = ((VarExp *) expr)->var->isFuncDeclaration(); -- gcc_assert (fd); -- tf = (TypeFunction *) fd->type; -- if (fd->isNested()) -- { -- if (call_by_alias_p (func, fd)) -- { -- // Re-evaluate symbol storage treating 'fd' as public. -- object_file->setupSymbolStorage (fd, callee, true); -- } -- object = getFrameForSymbol (fd); -- } -- else if (fd->needThis()) -- { -- expr->error ("need 'this' to access member %s", fd->toChars()); -- object = d_null_pointer; // continue processing... -- } -- } -- else -- { -- tf = get_function_type (t); -- } -- return call (tf, callee, object, arguments); --} -- --// Like above, but is assumed to be a direct call to FUNC_DECL. --// ARGS are the arguments passed. -+// Entry point for call routines. Builds a function call to FD. -+// OBJECT is the 'this' reference passed and ARGS are the arguments to FD. - - tree --IRState::call (FuncDeclaration *func_decl, Expressions *args) -+d_build_call (FuncDeclaration *fd, tree object, Expressions *args) - { -- // Otherwise need to copy code from above -- gcc_assert (!func_decl->isNested()); -- -- return call (get_function_type (func_decl->type), -- func_decl->toSymbol()->Stree, NULL_TREE, args); -+ return d_build_call (get_function_type (fd->type), -+ build_address (fd->toSymbol()->Stree), object, args); +- object_file->setupStaticStorage (this, t); +- object_file->setDeclLoc (t, this); +- TREE_CONSTANT (t) = 1; +- TREE_READONLY (t) = 1; +- DECL_CONTEXT (t) = 0; ++ sinit->Stree = build_decl (UNKNOWN_LOCATION, VAR_DECL, ++ get_identifier (sinit->Sident), type->toCtype()); ++ d_keep (sinit->Stree); ++ ++ setup_symbol_storage (this, sinit->Stree, true); ++ set_decl_location (sinit->Stree, this); ++ ++ TREE_CONSTANT (sinit->Stree) = 1; ++ TREE_READONLY (sinit->Stree) = 1; ++ DECL_CONTEXT (sinit->Stree) = 0; + } ++ + return sinit; } --// Like above, but FUNC_DECL is a nested function, method, delegate or lambda. --// OBJECT is the 'this' reference passed and ARGS are the arguments passed. -- --tree --IRState::call (FuncDeclaration *func_decl, tree object, Expressions *args) --{ -- return call (get_function_type (func_decl->type), -- build_address (func_decl->toSymbol()->Stree), object, args); --} -- --// Builds a CALL_EXPR of type FUNC_TYPE to CALLABLE. OBJECT holds the 'this' pointer, -+// Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the 'this' pointer, - // ARGUMENTS are evaluated in left to right order, saved and promoted before passing. +@@ -848,7 +837,7 @@ + TYPE_BINFO (rec_type) = intfc_binfo_for (NULL_TREE, this, offset); + } - tree --IRState::call (TypeFunction *func_type, tree callable, tree object, Expressions *arguments) -+d_build_call (TypeFunction *tf, tree callable, tree object, Expressions *arguments) +- object_file->declareType (rec_type, this); ++ build_type_decl (rec_type, this); + } + + void +@@ -875,7 +864,7 @@ + StructDeclaration::toDebug (void) { -- tree func_type_node = TREE_TYPE (callable); -- tree actual_callee = callable; -+ IRState *irs = current_irstate; -+ tree ctype = TREE_TYPE (callable); -+ tree callee = callable; - tree saved_args = NULL_TREE; - - tree arg_list = NULL_TREE; - -- if (POINTER_TYPE_P (func_type_node)) -- func_type_node = TREE_TYPE (func_type_node); -+ if (POINTER_TYPE_P (ctype)) -+ ctype = TREE_TYPE (ctype); - else -- actual_callee = build_address (callable); -+ callee = build_address (callable); + tree ctype = type->toCtype(); +- object_file->declareType (ctype, this); ++ build_type_decl (ctype, this); + rest_of_type_compilation (ctype, 1); + } -- gcc_assert (function_type_p (func_type_node)); -- gcc_assert (func_type != NULL); -- gcc_assert (func_type->ty == Tfunction); -+ gcc_assert (function_type_p (ctype)); -+ gcc_assert (tf != NULL); -+ gcc_assert (tf->ty == Tfunction); - - // Evaluate the callee before calling it. -- if (TREE_SIDE_EFFECTS (actual_callee)) -+ if (TREE_SIDE_EFFECTS (callee)) - { -- actual_callee = maybe_make_temp (actual_callee); -- saved_args = actual_callee; -+ callee = maybe_make_temp (callee); -+ saved_args = callee; +--- a/src/gcc/d/d-elem.cc ++++ b/src/gcc/d/d-elem.cc +@@ -1038,11 +1038,69 @@ } - -- bool is_d_vararg = func_type->varargs == 1 && func_type->linkage == LINKd; -- -- if (TREE_CODE (func_type_node) == FUNCTION_TYPE) -+ if (TREE_CODE (ctype) == FUNCTION_TYPE) + else { - if (object != NULL_TREE) - gcc_unreachable(); -@@ -2151,72 +1972,82 @@ IRState::call (TypeFunction *func_type, - if (TREE_CODE (callable) == FUNCTION_DECL) - { - error ("need 'this' to access member %s", IDENTIFIER_POINTER (DECL_NAME (callable))); -- return error_mark (func_type); -+ return error_mark_node; - } - - // Probably an internal error - gcc_unreachable(); - } +- /* arrayElemRef will call aryscp.finish. This result +- of this function may be used as an lvalue and we +- do not want it to be a BIND_EXPR. */ +- ArrayScope aryscp (lengthVar, loc); +- return irs->arrayElemRef (this, &aryscp); ++ // Build an array index expression. ArrayScope may build a BIND_EXPR ++ // if temporaries were created for bounds checking. ++ ArrayScope arrscope (lengthVar, loc); + - /* If this is a delegate call or a nested function being called as - a delegate, the object should not be NULL. */ - if (object != NULL_TREE) - arg_list = build_tree_list (NULL_TREE, object); - -- Parameters *formal_args = func_type->parameters; // can be NULL for genCfunc decls -- size_t n_formal_args = formal_args ? (int) Parameter::dim (formal_args) : 0; -- size_t n_actual_args = arguments ? arguments->dim : 0; -- size_t fi = 0; -- -- // assumes arguments->dim <= formal_args->dim if (!this->varargs) -- for (size_t ai = 0; ai < n_actual_args; ++ai) -+ if (arguments) - { -- tree arg_tree; -- Expression *arg_exp = (*arguments)[ai]; -- -- if (ai == 0 && is_d_vararg) -- { -- // The hidden _arguments parameter -- arg_tree = arg_exp->toElem (this); -- } -- else if (fi < n_formal_args) -+ // First pass, evaluated expanded tuples in function arguments. -+ for (size_t i = 0; i < arguments->dim; ++i) - { -- // Actual arguments for declared formal arguments -- Parameter *formal_arg = Parameter::getNth (formal_args, fi); -- arg_tree = convertForArgument (arg_exp, formal_arg); -- ++fi; -+ Lagain: -+ Expression *arg = (*arguments)[i]; -+ gcc_assert (arg->op != TOKtuple); ++ // The expression that holds the array data. ++ tree t1 = e1->toElem (irs); ++ // The expression that indexes the array data. ++ tree t2 = e2->toElem (irs); ++ // The base pointer to the elements. ++ tree ptrexp; ++ ++ switch (tb1->ty) ++ { ++ case Tarray: ++ case Tsarray: ++ t1 = arrscope.setArrayExp (t1, e1->type); + -+ if (arg->op == TOKcomma) ++ // If it's a static array and the index is constant, ++ // the front end has already checked the bounds. ++ if (array_bounds_check() && !(tb1->ty == Tsarray && e2->isConst())) + { -+ CommaExp *ce = (CommaExp *) arg; -+ tree tce = ce->e1->toElem (irs); -+ saved_args = maybe_vcompound_expr (saved_args, tce); -+ (*arguments)[i] = ce->e2; -+ goto Lagain; -+ } - } -- else ++ // Implement bounds check as a conditional expression: ++ // array [inbounds(index) ? index : { throw ArrayBoundsError}] ++ tree length; + -+ // if _arguments[] is the first argument. -+ size_t dvarargs = (tf->linkage == LINKd && tf->varargs == 1); -+ size_t nparams = Parameter::dim (tf->parameters); ++ // First, set up the index expression to only be evaluated once. ++ tree index = maybe_make_temp (t2); + -+ // Assumes arguments->dim <= formal_args->dim if (!this->varargs) -+ for (size_t i = 0; i < arguments->dim; ++i) - { -- if (flag_split_darrays && arg_exp->type->toBasetype()->ty == Tarray) -+ Expression *arg = (*arguments)[i]; -+ tree targ; ++ if (tb1->ty == Tarray) ++ { ++ t1 = maybe_make_temp (t1); ++ length = d_array_length (t1); ++ } ++ else ++ length = ((TypeSArray *) tb1)->dim->toElem (irs); + -+ if (i < dvarargs) - { -- tree da_exp = maybe_make_temp (arg_exp->toElem (this)); -- arg_list = chainon (arg_list, build_tree_list (0, d_array_length (da_exp))); -- arg_list = chainon (arg_list, build_tree_list (0, d_array_ptr (da_exp))); -- continue; -+ // The hidden _arguments parameter -+ targ = arg->toElem (irs); ++ t2 = d_checked_index (loc, index, length, false); + } -+ else if (i - dvarargs < nparams && i >= dvarargs) -+ { -+ // Actual arguments for declared formal arguments -+ Parameter *parg = Parameter::getNth (tf->parameters, i - dvarargs); -+ targ = convert_for_argument (arg->toElem (irs), arg, parg); - } - else - { -- arg_tree = arg_exp->toElem (this); -- /* Not all targets support passing unpromoted types, so -- promote anyway. */ -- tree prom_type = lang_hooks.types.type_promotes_to (TREE_TYPE (arg_tree)); -- if (prom_type != TREE_TYPE (arg_tree)) -- arg_tree = convert (prom_type, arg_tree); -+ // Not all targets support passing unpromoted types, so -+ // promote anyway. -+ targ = arg->toElem (irs); -+ tree ptype = lang_hooks.types.type_promotes_to (TREE_TYPE (targ)); + -+ if (ptype != TREE_TYPE (targ)) -+ targ = convert (ptype, targ); - } -- } -- /* Evaluate the argument before passing to the function. -- Needed for left to right evaluation. */ -- if (func_type->linkage == LINKd && TREE_SIDE_EFFECTS (arg_tree)) -- { -- arg_tree = maybe_make_temp (arg_tree); -- saved_args = maybe_vcompound_expr (saved_args, arg_tree); -- } - -- arg_list = chainon (arg_list, build_tree_list (0, arg_tree)); -+ // Evaluate the argument before passing to the function. -+ // Needed for left to right evaluation. -+ if (tf->linkage == LINKd && TREE_SIDE_EFFECTS (targ)) -+ { -+ targ = maybe_make_temp (targ); -+ saved_args = maybe_vcompound_expr (saved_args, targ); -+ } -+ arg_list = chainon (arg_list, build_tree_list (0, targ)); ++ if (tb1->ty == Tarray) ++ ptrexp = d_array_ptr (t1); ++ else ++ ptrexp = build_address (t1); ++ ++ // This conversion is required for static arrays and is ++ // just-to-be-safe for dynamic arrays. ++ ptrexp = convert (tb1->nextOf()->pointerTo()->toCtype(), ptrexp); ++ break; ++ ++ case Tpointer: ++ // Ignores ArrayScope. ++ ptrexp = t1; ++ break; ++ ++ default: ++ gcc_unreachable(); + } ++ ++ ptrexp = void_okay_p (ptrexp); ++ t2 = arrscope.finish (t2); ++ ++ return indirect_ref (TREE_TYPE (TREE_TYPE (ptrexp)), ++ build_array_index (ptrexp, t2)); } - -- tree result = d_build_call (TREE_TYPE (func_type_node), actual_callee, arg_list); -- result = maybeExpandSpecialCall (result); -+ tree result = d_build_call_list (TREE_TYPE (ctype), callee, arg_list); -+ result = maybe_expand_builtin (result); - - return maybe_compound_expr (saved_args, result); } -@@ -2253,21 +2084,11 @@ d_assert_call (Loc loc, LibCall libcall, - // List kept in ascii collating order to allow binary search - - static const char *libcall_ids[LIBCALL_count] = { -- /*"_d_invariant",*/ "_D9invariant12_d_invariantFC6ObjectZv", -- "_aApplyRcd1", "_aApplyRcd2", "_aApplyRcw1", "_aApplyRcw2", -- "_aApplyRdc1", "_aApplyRdc2", "_aApplyRdw1", "_aApplyRdw2", -- "_aApplyRwc1", "_aApplyRwc2", "_aApplyRwd1", "_aApplyRwd2", -- "_aApplycd1", "_aApplycd2", "_aApplycw1", "_aApplycw2", -- "_aApplydc1", "_aApplydc2", "_aApplydw1", "_aApplydw2", -- "_aApplywc1", "_aApplywc2", "_aApplywd1", "_aApplywd2", -- "_aaApply", "_aaApply2", -+ "_D9invariant12_d_invariantFC6ObjectZv", - "_aaDelX", "_aaEqual", - "_aaGetRvalueX", "_aaGetX", -- "_aaInX", "_aaLen", -- "_adCmp", "_adCmp2", -- "_adDupT", "_adEq", "_adEq2", -- "_adReverse", "_adReverseChar", "_adReverseWchar", -- "_adSort", "_adSortChar", "_adSortWchar", -+ "_aaInX", -+ "_adCmp2", "_adEq2", - "_d_allocmemory", "_d_array_bounds", - "_d_arrayappendT", "_d_arrayappendcTX", - "_d_arrayappendcd", "_d_arrayappendwd", -@@ -2280,11 +2101,9 @@ static const char *libcall_ids[LIBCALL_c - "_d_assert", "_d_assert_msg", - "_d_assocarrayliteralTX", - "_d_callfinalizer", "_d_callinterfacefinalizer", -- "_d_criticalenter", "_d_criticalexit", - "_d_delarray", "_d_delarray_t", "_d_delclass", - "_d_delinterface", "_d_delmemory", - "_d_dynamic_cast", "_d_hidden_func", "_d_interface_cast", -- "_d_monitorenter", "_d_monitorexit", - "_d_newarrayT", "_d_newarrayiT", - "_d_newarraymTX", "_d_newarraymiTX", - "_d_newclass", "_d_newitemT", "_d_newitemiT", -@@ -2304,9 +2123,7 @@ get_libcall (LibCall libcall) - { - FuncDeclaration *decl = libcall_decls[libcall]; -- static Type *aa_type = NULL; -- static Type *dg_type = NULL; -- static Type *dg2_type = NULL; -+ static Type *aatype = NULL; +@@ -1360,7 +1418,7 @@ + if (!decl_reference_p (sym_exp->var)) + { + rec_type = sym_exp->var->type->toBasetype(); +- rec_tree = irs->var (sym_exp->var); ++ rec_tree = get_decl_tree (sym_exp->var, irs->func); + the_offset = sym_exp->offset; + } + } +@@ -1492,7 +1550,7 @@ + if (e1->op == TOKnull) + this_tree = e1->toElem (irs); + else +- this_tree = irs->getFrameForSymbol (func); ++ this_tree = get_frame_for_symbol (irs->func, func); + } + else + { +@@ -1537,7 +1595,7 @@ + else if (var_decl) + { + if (!(var_decl->storage_class & STCfield)) +- return irs->var (var_decl); ++ return get_decl_tree (var_decl, irs->func); + else + { + tree this_tree = e1->toElem (irs); +@@ -1695,7 +1753,7 @@ - if (!decl) - { -@@ -2315,27 +2132,8 @@ get_libcall (LibCall libcall) - bool varargs = false; + case Tdelegate: + return build_method_call (build_address (fd->toSymbol()->Stree), +- irs->getFrameForSymbol (fd), type); ++ get_frame_for_symbol (irs->func, fd), type); - // Build generic AA type void*[void*] -- if (aa_type == NULL) -- aa_type = new TypeAArray (Type::tvoidptr, Type::tvoidptr); -- -- // Build generic delegate type int(void*) -- if (dg_type == NULL) -- { -- Parameters *fn_parms = new Parameters; -- fn_parms->push (new Parameter (STCin, Type::tvoidptr, NULL, NULL)); -- Type *fn_type = new TypeFunction (fn_parms, Type::tint32, false, LINKd); -- dg_type = new TypeDelegate (fn_type); -- } -- -- // Build generic delegate type int(void*, void*) -- if (dg2_type == NULL) -- { -- Parameters *fn_parms = new Parameters; -- fn_parms->push (new Parameter (STCin, Type::tvoidptr, NULL, NULL)); -- fn_parms->push (new Parameter (STCin, Type::tvoidptr, NULL, NULL)); -- Type *fn_type = new TypeFunction (fn_parms, Type::tint32, false, LINKd); -- dg2_type = new TypeDelegate (fn_type); -- } -+ if (aatype == NULL) -+ aatype = new TypeAArray (Type::tvoidptr, Type::tvoidptr); + default: + ::error ("Unexpected FuncExp type"); +@@ -1727,7 +1785,7 @@ + if (var->ident == Id::ctfe) + return integer_zero_node; - switch (libcall) - { -@@ -2365,20 +2163,20 @@ get_libcall (LibCall libcall) - break; +- exp = irs->var (var); ++ exp = get_decl_tree (var, irs->func); + TREE_USED (exp) = 1; - case LIBCALL_NEWCLASS: -- targs.push (ClassDeclaration::classinfo->type->constOf()); -- treturn = build_object_type (); -+ targs.push (Type::typeinfoclass->type->constOf()); -+ treturn = build_object_type(); - break; - - case LIBCALL_NEWARRAYT: - case LIBCALL_NEWARRAYIT: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tsize_t); - treturn = Type::tvoid->arrayOf(); - break; - - case LIBCALL_NEWARRAYMTX: - case LIBCALL_NEWARRAYMITX: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tsize_t); - targs.push (Type::tsize_t); - treturn = Type::tvoid->arrayOf(); -@@ -2386,7 +2184,7 @@ get_libcall (LibCall libcall) - - case LIBCALL_NEWITEMT: - case LIBCALL_NEWITEMIT: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - treturn = Type::tvoidptr; - break; - -@@ -2406,7 +2204,7 @@ get_libcall (LibCall libcall) - - case LIBCALL_DELARRAYT: - targs.push (Type::tvoid->arrayOf()->pointerTo()); -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - break; - - case LIBCALL_DELMEMORY: -@@ -2420,7 +2218,7 @@ get_libcall (LibCall libcall) - - case LIBCALL_ARRAYSETLENGTHT: - case LIBCALL_ARRAYSETLENGTHIT: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tsize_t); - targs.push (Type::tvoid->arrayOf()->pointerTo()); - treturn = Type::tvoid->arrayOf(); -@@ -2428,59 +2226,52 @@ get_libcall (LibCall libcall) - - case LIBCALL_DYNAMIC_CAST: - case LIBCALL_INTERFACE_CAST: -- targs.push (build_object_type ()); -- targs.push (ClassDeclaration::classinfo->type); -- treturn = build_object_type (); -+ targs.push (build_object_type()); -+ targs.push (Type::typeinfoclass->type); -+ treturn = build_object_type(); - break; - -- case LIBCALL_ADEQ: - case LIBCALL_ADEQ2: -- case LIBCALL_ADCMP: - case LIBCALL_ADCMP2: - targs.push (Type::tvoid->arrayOf()); - targs.push (Type::tvoid->arrayOf()); -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - treturn = Type::tint32; - break; - - case LIBCALL_AAEQUAL: -- targs.push (Type::typeinfo->type->constOf()); -- targs.push (aa_type); -- targs.push (aa_type); -+ targs.push (Type::dtypeinfo->type->constOf()); -+ targs.push (aatype); -+ targs.push (aatype); - treturn = Type::tint32; - break; - -- case LIBCALL_AALEN: -- targs.push (aa_type); -- treturn = Type::tsize_t; -- break; -- - case LIBCALL_AAINX: -- targs.push (aa_type); -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (aatype); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tvoidptr); - treturn = Type::tvoidptr; - break; - - case LIBCALL_AAGETX: -- targs.push (aa_type->pointerTo()); -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (aatype->pointerTo()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tsize_t); - targs.push (Type::tvoidptr); - treturn = Type::tvoidptr; - break; - - case LIBCALL_AAGETRVALUEX: -- targs.push (aa_type); -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (aatype); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tsize_t); - targs.push (Type::tvoidptr); - treturn = Type::tvoidptr; - break; - - case LIBCALL_AADELX: -- targs.push (aa_type); -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (aatype); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tvoidptr); - treturn = Type::tbool; - break; -@@ -2500,28 +2291,29 @@ get_libcall (LibCall libcall) - break; - - case LIBCALL_ARRAYCATT: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tint8->arrayOf()); - targs.push (Type::tint8->arrayOf()); - treturn = Type::tint8->arrayOf(); - break; - - case LIBCALL_ARRAYCATNT: -- targs.push (Type::typeinfo->type->constOf()); -- targs.push (Type::tuns32); // Currently 'uint', even if 64-bit -+ targs.push (Type::dtypeinfo->type->constOf()); -+ // Currently 'uint', even if 64-bit -+ targs.push (Type::tuns32); - varargs = true; - treturn = Type::tvoid->arrayOf(); - break; - - case LIBCALL_ARRAYAPPENDT: -- targs.push (Type::typeinfo->type); //->constOf()); -+ targs.push (Type::dtypeinfo->type); //->constOf()); - targs.push (Type::tint8->arrayOf()->pointerTo()); - targs.push (Type::tint8->arrayOf()); - treturn = Type::tvoid->arrayOf(); - break; - - case LIBCALL_ARRAYAPPENDCTX: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tint8->arrayOf()->pointerTo()); - targs.push (Type::tsize_t); - treturn = Type::tint8->arrayOf(); -@@ -2541,7 +2333,7 @@ get_libcall (LibCall libcall) - - case LIBCALL_ARRAYASSIGN: - case LIBCALL_ARRAYCTOR: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tvoid->arrayOf()); - targs.push (Type::tvoid->arrayOf()); - treturn = Type::tvoid->arrayOf(); -@@ -2552,20 +2344,13 @@ get_libcall (LibCall libcall) - targs.push (Type::tvoidptr); - targs.push (Type::tvoidptr); - targs.push (Type::tsize_t); -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - treturn = Type::tvoidptr; - break; - -- case LIBCALL_MONITORENTER: -- case LIBCALL_MONITOREXIT: - case LIBCALL_THROW: - case LIBCALL_INVARIANT: -- targs.push (build_object_type ()); -- break; -- -- case LIBCALL_CRITICALENTER: -- case LIBCALL_CRITICALEXIT: -- targs.push (Type::tvoidptr); -+ targs.push (build_object_type()); - break; - - case LIBCALL_SWITCH_USTRING: -@@ -2585,117 +2370,20 @@ get_libcall (LibCall libcall) - targs.push (Type::tchar->arrayOf()); - treturn = Type::tint32; - break; -+ - case LIBCALL_ASSOCARRAYLITERALTX: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tvoid->arrayOf()); - targs.push (Type::tvoid->arrayOf()); - treturn = Type::tvoidptr; - break; - - case LIBCALL_ARRAYLITERALTX: -- targs.push (Type::typeinfo->type->constOf()); -+ targs.push (Type::dtypeinfo->type->constOf()); - targs.push (Type::tsize_t); - treturn = Type::tvoidptr; - break; - -- case LIBCALL_ADSORTCHAR: -- case LIBCALL_ADREVERSECHAR: -- targs.push (Type::tchar->arrayOf()); -- treturn = Type::tchar->arrayOf(); -- break; -- -- case LIBCALL_ADSORTWCHAR: -- case LIBCALL_ADREVERSEWCHAR: -- targs.push (Type::twchar->arrayOf()); -- treturn = Type::twchar->arrayOf(); -- break; -- -- case LIBCALL_ADDUPT: -- targs.push (Type::typeinfo->type->constOf()); -- targs.push (Type::tvoid->arrayOf()); -- treturn = Type::tvoid->arrayOf(); -- break; -- -- case LIBCALL_ADREVERSE: -- targs.push (Type::tvoid->arrayOf()); -- targs.push (Type::tsize_t); -- treturn = Type::tvoid->arrayOf(); -- break; -- -- case LIBCALL_ADSORT: -- targs.push (Type::tvoid->arrayOf()); -- targs.push (Type::typeinfo->type->constOf()); -- treturn = Type::tvoid->arrayOf(); -- break; -- -- case LIBCALL_AAAPPLY: -- targs.push (aa_type); -- targs.push (Type::tsize_t); -- targs.push (dg_type); -- treturn = Type::tint32; -- break; -- -- case LIBCALL_AAAPPLY2: -- targs.push (aa_type); -- targs.push (Type::tsize_t); -- targs.push (dg2_type); -- treturn = Type::tint32; -- break; -- -- case LIBCALL_AAPPLYCD1: -- case LIBCALL_AAPPLYCW1: -- case LIBCALL_AAPPLYRCD1: -- case LIBCALL_AAPPLYRCW1: -- targs.push (Type::tchar->arrayOf()); -- targs.push (dg_type); -- treturn = Type::tint32; -- break; -- -- case LIBCALL_AAPPLYCD2: -- case LIBCALL_AAPPLYCW2: -- case LIBCALL_AAPPLYRCD2: -- case LIBCALL_AAPPLYRCW2: -- targs.push (Type::tchar->arrayOf()); -- targs.push (dg2_type); -- treturn = Type::tint32; -- break; -- -- case LIBCALL_AAPPLYDC1: -- case LIBCALL_AAPPLYDW1: -- case LIBCALL_AAPPLYRDC1: -- case LIBCALL_AAPPLYRDW1: -- targs.push (Type::tdchar->arrayOf()); -- targs.push (dg_type); -- treturn = Type::tint32; -- break; -- -- case LIBCALL_AAPPLYDC2: -- case LIBCALL_AAPPLYDW2: -- case LIBCALL_AAPPLYRDC2: -- case LIBCALL_AAPPLYRDW2: -- targs.push (Type::tdchar->arrayOf()); -- targs.push (dg2_type); -- treturn = Type::tint32; -- break; -- -- case LIBCALL_AAPPLYWC1: -- case LIBCALL_AAPPLYWD1: -- case LIBCALL_AAPPLYRWC1: -- case LIBCALL_AAPPLYRWD1: -- targs.push (Type::twchar->arrayOf()); -- targs.push (dg_type); -- treturn = Type::tint32; -- break; -- -- case LIBCALL_AAPPLYWC2: -- case LIBCALL_AAPPLYWD2: -- case LIBCALL_AAPPLYRWC2: -- case LIBCALL_AAPPLYRWD2: -- targs.push (Type::twchar->arrayOf()); -- targs.push (dg2_type); -- treturn = Type::tint32; -- break; -- - case LIBCALL_HIDDEN_FUNC: - /* Argument is an Object, but can't use that as - LIBCALL_HIDDEN_FUNC is needed before the Object type is -@@ -2707,22 +2395,17 @@ get_libcall (LibCall libcall) - gcc_unreachable(); - } + // For variables that are references (currently only out/inout arguments; +@@ -1741,7 +1799,7 @@ + { + size_t offset = ((SymOffExp *) this)->offset; -- // Build extern(C) function. -- Identifier *id = Lexer::idPool(libcall_ids[libcall]); -- TypeFunction *tf = new TypeFunction(NULL, treturn, 0, LINKc); -- tf->varargs = varargs ? 1 : 0; -- -- decl = new FuncDeclaration(0, 0, id, STCstatic, tf); -- decl->protection = PROTpublic; -- decl->linkage = LINKc; -- - // Add parameter types. - Parameters *args = new Parameters; - args->setDim (targs.dim); - for (size_t i = 0; i < targs.dim; i++) - (*args)[i] = new Parameter (0, targs[i], NULL, NULL); - -- tf->parameters = args; -+ // Build extern(C) function. -+ decl = FuncDeclaration::genCfunc (args, treturn, libcall_ids[libcall]); -+ -+ TypeFunction *tf = (TypeFunction *) decl->type; -+ tf->varargs = varargs ? 1 : 0; - libcall_decls[libcall] = decl; - - // These functions do not return except through catching a thrown exception. -@@ -2753,7 +2436,7 @@ build_libcall (LibCall libcall, unsigned - for (int i = n_args - 1; i >= 0; i--) - arg_list = tree_cons (NULL_TREE, args[i], arg_list); - -- tree result = d_build_call (type->toCtype(), callee, arg_list); -+ tree result = d_build_call_list (type->toCtype(), callee, arg_list); - - // Assumes caller knows what it is doing. - if (force_type != NULL_TREE) -@@ -2767,7 +2450,7 @@ build_libcall (LibCall libcall, unsigned - // attributes of the funcion and the SIDE_EFFECTS flags of the arguments. +- exp = irs->var (var); ++ exp = get_decl_tree (var, irs->func); + TREE_USED (exp) = 1; - tree --d_build_call (tree type, tree callee, tree args) -+d_build_call_list (tree type, tree callee, tree args) + if (decl_reference_p (var)) +@@ -2347,16 +2405,17 @@ + ThisExp::toElem (IRState *irs) { - int nargs = list_length (args); - tree *pargs = new tree[nargs]; -@@ -2778,7 +2461,7 @@ d_build_call (tree type, tree callee, tr - } + tree this_tree = NULL_TREE; ++ FuncDeclaration *fd = irs->func; - // Conveniently construct the function arguments for passing --// to the real d_build_call function. -+// to the d_build_call_list function. + if (var) + { + gcc_assert(var->isVarDeclaration()); +- this_tree = irs->var (var); ++ this_tree = get_decl_tree (var, fd); + } + else + { +- gcc_assert (irs->func && irs->func->vthis); +- this_tree = irs->var (irs->func->vthis); ++ gcc_assert (fd && fd->vthis); ++ this_tree = get_decl_tree (fd->vthis, fd); + } - tree - d_build_call_nary (tree callee, int n_args, ...) -@@ -2792,22 +2475,166 @@ d_build_call_nary (tree callee, int n_ar - arg_list = tree_cons (NULL_TREE, va_arg (ap, tree), arg_list); - va_end (ap); + if (type->ty == Tstruct) +--- a/src/gcc/d/dfrontend/argtypes.c ++++ b/src/gcc/d/dfrontend/argtypes.c +@@ -157,14 +157,6 @@ + #endif + } -- return d_build_call (TREE_TYPE (fntype), build_address (callee), nreverse (arg_list)); -+ return d_build_call_list (TREE_TYPE (fntype), build_address (callee), nreverse (arg_list)); -+} -+ -+// Call an fold the intrinsic call CALLEE with the argument ARG -+// with the built-in function CODE passed. -+ -+static tree -+expand_intrinsic_op (built_in_function code, tree callee, tree arg) -+{ -+ tree exp = d_build_call_nary (builtin_decl_explicit (code), 1, arg); -+ return fold_convert (TREE_TYPE (callee), fold (exp)); +-TypeTuple *TypeDArray::toArgTypes() +-{ +- /* Should be done as if it were: +- * struct S { size_t length; void* ptr; } +- */ +- return new TypeTuple(Type::tsize_t, Type::tvoidptr); +-} +- + TypeTuple *TypeAArray::toArgTypes() + { + return new TypeTuple(Type::tvoidptr); +@@ -175,14 +167,6 @@ + return new TypeTuple(Type::tvoidptr); + } + +-TypeTuple *TypeDelegate::toArgTypes() +-{ +- /* Should be done as if it were: +- * struct S { void* ptr; void* funcptr; } +- */ +- return new TypeTuple(Type::tvoidptr, Type::tvoidptr); +-} +- + /************************************* + * Convert a floating point type into the equivalent integral type. + */ +@@ -276,6 +260,38 @@ + return t; + } + ++TypeTuple *TypeDArray::toArgTypes() ++{ ++ /* Should be done as if it were: ++ * struct S { size_t length; void* ptr; } ++ */ ++ if (global.params.is64bit && !global.params.isLP64) ++ { ++ // For X32 ABI on 64bit, D arrays fit into a single integer register. ++ unsigned offset = Type::tsize_t->size(0); ++ Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset); ++ if (t) ++ return new TypeTuple(t); ++ } ++ return new TypeTuple(Type::tsize_t, Type::tvoidptr); +} + -+// Like expand_intrinsic_op, but takes two arguments. -+ -+static tree -+expand_intrinsic_op2 (built_in_function code, tree callee, tree arg1, tree arg2) ++TypeTuple *TypeDelegate::toArgTypes() +{ -+ tree exp = d_build_call_nary (builtin_decl_explicit (code), 2, arg1, arg2); -+ return fold_convert (TREE_TYPE (callee), fold (exp)); ++ /* Should be done as if it were: ++ * struct S { size_t length; void* ptr; } ++ */ ++ if (global.params.is64bit && !global.params.isLP64) ++ { ++ // For X32 ABI on 64bit, D arrays fit into a single integer register. ++ unsigned offset = Type::tsize_t->size(0); ++ Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset); ++ if (t) ++ return new TypeTuple(t); ++ } ++ return new TypeTuple(Type::tvoidptr, Type::tvoidptr); +} + -+// Expand a front-end instrinsic call to bsr whose arguments are ARG. -+// The original call expression is held in CALLEE. + TypeTuple *TypeStruct::toArgTypes() + { + //printf("TypeStruct::toArgTypes() %s\n", toChars()); +--- a/src/gcc/d/dfrontend/artistic.txt ++++ b/src/gcc/d/dfrontend/artistic.txt +@@ -1,117 +1,117 @@ +- +- +- +- +- The "Artistic License" +- +- Preamble +- +-The intent of this document is to state the conditions under which a +-Package may be copied, such that the Copyright Holder maintains some +-semblance of artistic control over the development of the package, +-while giving the users of the package the right to use and distribute +-the Package in a more-or-less customary fashion, plus the right to make +-reasonable modifications. +- +-Definitions: +- +- "Package" refers to the collection of files distributed by the +- Copyright Holder, and derivatives of that collection of files +- created through textual modification. +- +- "Standard Version" refers to such a Package if it has not been +- modified, or has been modified in accordance with the wishes +- of the Copyright Holder as specified below. +- +- "Copyright Holder" is whoever is named in the copyright or +- copyrights for the package. +- +- "You" is you, if you're thinking about copying or distributing +- this Package. +- +- "Reasonable copying fee" is whatever you can justify on the +- basis of media cost, duplication charges, time of people involved, +- and so on. (You will not be required to justify it to the +- Copyright Holder, but only to the computing community at large +- as a market that must bear the fee.) +- +- "Freely Available" means that no fee is charged for the item +- itself, though there may be fees involved in handling the item. +- It also means that recipients of the item may redistribute it +- under the same conditions they received it. +- +-1. You may make and give away verbatim copies of the source form of the +-Standard Version of this Package without restriction, provided that you +-duplicate all of the original copyright notices and associated disclaimers. +- +-2. You may apply bug fixes, portability fixes and other modifications +-derived from the Public Domain or from the Copyright Holder. A Package +-modified in such a way shall still be considered the Standard Version. +- +-3. You may otherwise modify your copy of this Package in any way, provided +-that you insert a prominent notice in each changed file stating how and +-when you changed that file, and provided that you do at least ONE of the +-following: +- +- a) place your modifications in the Public Domain or otherwise make them +- Freely Available, such as by posting said modifications to Usenet or +- an equivalent medium, or placing the modifications on a major archive +- site such as uunet.uu.net, or by allowing the Copyright Holder to include +- your modifications in the Standard Version of the Package. +- +- b) use the modified Package only within your corporation or organization. +- +- c) rename any non-standard executables so the names do not conflict +- with standard executables, which must also be provided, and provide +- a separate manual page for each non-standard executable that clearly +- documents how it differs from the Standard Version. +- +- d) make other distribution arrangements with the Copyright Holder. +- +-4. You may distribute the programs of this Package in object code or +-executable form, provided that you do at least ONE of the following: +- +- a) distribute a Standard Version of the executables and library files, +- together with instructions (in the manual page or equivalent) on where +- to get the Standard Version. +- +- b) accompany the distribution with the machine-readable source of +- the Package with your modifications. +- +- c) give non-standard executables non-standard names, and clearly +- document the differences in manual pages (or equivalent), together +- with instructions on where to get the Standard Version. +- +- d) make other distribution arrangements with the Copyright Holder. +- +-5. You may charge a reasonable copying fee for any distribution of this +-Package. You may charge any fee you choose for support of this +-Package. You may not charge a fee for this Package itself. However, +-you may distribute this Package in aggregate with other (possibly +-commercial) programs as part of a larger (possibly commercial) software +-distribution provided that you do not advertise this Package as a +-product of your own. You may embed this Package's interpreter within +-an executable of yours (by linking); this shall be construed as a mere +-form of aggregation, provided that the complete Standard Version of the +-interpreter is so embedded. +- +-6. The source code and object code supplied as input to or produced as +-output from the programs of this Package do not automatically fall +-under the copyright of this Package, but belong to whoever generated +-them, and may be sold commercially, and may be aggregated with this +-Package. +- +-7. Aggregation of this Package with a commercial distribution is always +-permitted provided that the use of this Package is embedded; that is, +-when no overt attempt is made to make this Package's interfaces visible +-to the end user of the commercial distribution. Such use shall not be +-construed as a distribution of this Package. +- +-8. The name of the Copyright Holder may not be used to endorse or promote +-products derived from this software without specific prior written permission. +- +-9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +-IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +-WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +- +- The End + -+static tree -+expand_intrinsic_bsr (tree callee, tree arg) -+{ -+ // Intrinsic bsr gets turned into (size - 1) - count_leading_zeros(arg). -+ // %% TODO: The return value is supposed to be undefined if arg is zero. -+ tree type = TREE_TYPE (arg); -+ tree tsize = build_integer_cst (TREE_INT_CST_LOW (TYPE_SIZE (type)) - 1, type); -+ tree exp = expand_intrinsic_op (BUILT_IN_CLZL, callee, arg); -+ -+ // Handle int -> long conversions. -+ if (TREE_TYPE (exp) != type) -+ exp = fold_convert (type, exp); + -+ exp = fold_build2 (MINUS_EXPR, type, tsize, exp); -+ return fold_convert (TREE_TYPE (callee), exp); -+} + -+// Expand the front-end built-in function INTRINSIC, which is either a -+// call to bt, btc, btr, or bts. These intrinsics take two arguments, -+// ARG1 and ARG2, and the original call expression is held in CALLEE. + -+static tree -+expand_intrinsic_bt (Intrinsic intrinsic, tree callee, tree arg1, tree arg2) -+{ -+ tree type = TREE_TYPE (TREE_TYPE (arg1)); -+ tree exp = build_integer_cst (TREE_INT_CST_LOW (TYPE_SIZE (type)), type); -+ tree_code code; -+ tree tval; -+ -+ // arg1[arg2 / exp] -+ arg1 = build_array_index (arg1, fold_build2 (TRUNC_DIV_EXPR, type, arg2, exp)); -+ arg1 = indirect_ref (type, arg1); -+ -+ // mask = 1 << (arg2 % exp); -+ arg2 = fold_build2 (TRUNC_MOD_EXPR, type, arg2, exp); -+ arg2 = fold_build2 (LSHIFT_EXPR, type, size_one_node, arg2); -+ -+ // cond = arg1[arg2 / size] & mask; -+ exp = fold_build2 (BIT_AND_EXPR, type, arg1, arg2); -+ -+ // cond ? -1 : 0; -+ exp = fold_build3 (COND_EXPR, TREE_TYPE (callee), d_truthvalue_conversion (exp), -+ integer_minus_one_node, integer_zero_node); -+ -+ // Update the bit as needed. -+ code = (intrinsic == INTRINSIC_BTC) ? BIT_XOR_EXPR : -+ (intrinsic == INTRINSIC_BTR) ? BIT_AND_EXPR : -+ (intrinsic == INTRINSIC_BTS) ? BIT_IOR_EXPR : ERROR_MARK; -+ gcc_assert (code != ERROR_MARK); -+ -+ // arg1[arg2 / size] op= mask -+ if (intrinsic == INTRINSIC_BTR) -+ arg2 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg2), arg2); -+ -+ tval = build_local_temp (TREE_TYPE (callee)); -+ exp = vmodify_expr (tval, exp); -+ arg1 = vmodify_expr (arg1, fold_build2 (code, TREE_TYPE (arg1), arg1, arg2)); ++ The "Artistic License" + -+ return compound_expr (exp, compound_expr (arg1, tval)); -+} ++ Preamble + -+// Expand a front-end built-in call to va_arg, whose arguments are -+// ARG1 and optionally ARG2. -+// The original call expression is held in CALLEE. -+ -+// The cases handled here are: -+// va_arg!T(ap); -+// => return (T) VA_ARG_EXP -+// -+// va_arg!T(ap, T arg); -+// => return arg = (T) VA_ARG_EXP; ++The intent of this document is to state the conditions under which a ++Package may be copied, such that the Copyright Holder maintains some ++semblance of artistic control over the development of the package, ++while giving the users of the package the right to use and distribute ++the Package in a more-or-less customary fashion, plus the right to make ++reasonable modifications. + -+static tree -+expand_intrinsic_vaarg (tree callee, tree arg1, tree arg2) -+{ -+ tree type; ++Definitions: + -+ STRIP_NOPS (arg1); ++ "Package" refers to the collection of files distributed by the ++ Copyright Holder, and derivatives of that collection of files ++ created through textual modification. + -+ if (TREE_CODE (arg1) == ADDR_EXPR) -+ arg1 = TREE_OPERAND (arg1, 0); ++ "Standard Version" refers to such a Package if it has not been ++ modified, or has been modified in accordance with the wishes ++ of the Copyright Holder as specified below. + -+ if (arg2 == NULL_TREE) -+ type = TREE_TYPE (callee); -+ else -+ { -+ STRIP_NOPS (arg2); -+ gcc_assert (TREE_CODE (arg2) == ADDR_EXPR); -+ arg2 = TREE_OPERAND (arg2, 0); -+ type = TREE_TYPE (arg2); -+ } ++ "Copyright Holder" is whoever is named in the copyright or ++ copyrights for the package. + -+ // Silently convert promoted types. -+ tree ptype = lang_hooks.types.type_promotes_to (type); -+ tree exp = build1 (VA_ARG_EXPR, ptype, arg1); ++ "You" is you, if you're thinking about copying or distributing ++ this Package. + -+ if (type != ptype) -+ exp = fold_convert (type, exp); ++ "Reasonable copying fee" is whatever you can justify on the ++ basis of media cost, duplication charges, time of people involved, ++ and so on. (You will not be required to justify it to the ++ Copyright Holder, but only to the computing community at large ++ as a market that must bear the fee.) + -+ if (arg2 != NULL_TREE) -+ exp = vmodify_expr (arg2, exp); ++ "Freely Available" means that no fee is charged for the item ++ itself, though there may be fees involved in handling the item. ++ It also means that recipients of the item may redistribute it ++ under the same conditions they received it. + -+ return exp; - } - --// If CALL_EXP is a BUILT_IN_FRONTEND, expand and return inlined -+// Expand a front-end built-in call to va_start, whose arguments are -+// ARG1 and ARG2. The original call expression is held in CALLEE. ++1. You may make and give away verbatim copies of the source form of the ++Standard Version of this Package without restriction, provided that you ++duplicate all of the original copyright notices and associated disclaimers. + -+static tree -+expand_intrinsic_vastart (tree callee, tree arg1, tree arg2) -+{ -+ // The va_list argument should already have its address taken. -+ // The second argument, however, is inout and that needs to be -+ // fixed to prevent a warning. -+ -+ // Could be casting... so need to check type too? -+ STRIP_NOPS (arg1); -+ STRIP_NOPS (arg2); -+ gcc_assert (TREE_CODE (arg1) == ADDR_EXPR && TREE_CODE (arg2) == ADDR_EXPR); -+ -+ arg2 = TREE_OPERAND (arg2, 0); -+ // Assuming nobody tries to change the return type. -+ return expand_intrinsic_op2 (BUILT_IN_VA_START, callee, arg1, arg2); -+} ++2. You may apply bug fixes, portability fixes and other modifications ++derived from the Public Domain or from the Copyright Holder. A Package ++modified in such a way shall still be considered the Standard Version. + -+// If CALLEXP is a BUILT_IN_FRONTEND, expand and return inlined - // compiler generated instructions. Most map onto GCC builtins, - // others require a little extra work around them. - - tree --IRState::maybeExpandSpecialCall (tree call_exp) -+maybe_expand_builtin (tree callexp) - { - // More code duplication from C -- CallExpr ce (call_exp); -+ CallExpr ce (callexp); - tree callee = ce.callee(); -- tree op1 = NULL_TREE, op2 = NULL_TREE; -- tree exp = NULL_TREE, val; -- enum tree_code code; - - if (POINTER_TYPE_P (TREE_TYPE (callee))) - callee = TREE_OPERAND (callee, 0); -@@ -2816,210 +2643,107 @@ IRState::maybeExpandSpecialCall (tree ca - && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_FRONTEND) - { - Intrinsic intrinsic = (Intrinsic) DECL_FUNCTION_CODE (callee); -+ tree op1, op2; - tree type; -- Type *d_type; ++3. You may otherwise modify your copy of this Package in any way, provided ++that you insert a prominent notice in each changed file stating how and ++when you changed that file, and provided that you do at least ONE of the ++following: + - switch (intrinsic) - { - case INTRINSIC_BSF: -- /* builtin count_trailing_zeros matches behaviour of bsf. -- %% TODO: The return value is supposed to be undefined if op1 is zero. */ -+ // builtin count_trailing_zeros matches behaviour of bsf. -+ // %% TODO: The return value is supposed to be undefined if op1 is zero. - op1 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_CTZL), 1, op1); -+ return expand_intrinsic_op (BUILT_IN_CTZL, callexp, op1); - - case INTRINSIC_BSR: -- /* bsr becomes 31-(clz), but parameter passed to bsf may not be a 32bit type!! -- %% TODO: The return value is supposed to be undefined if op1 is zero. */ - op1 = ce.nextArg(); -- type = TREE_TYPE (op1); -- -- op2 = build_integer_cst (tree_low_cst (TYPE_SIZE (type), 1) - 1, type); -- exp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_CLZL), 1, op1); -- -- // Handle int -> long conversions. -- if (TREE_TYPE (exp) != type) -- exp = fold_convert (type, exp); -- -- return fold_build2 (MINUS_EXPR, type, op2, exp); -+ return expand_intrinsic_bsr (callexp, op1); - - case INTRINSIC_BTC: - case INTRINSIC_BTR: - case INTRINSIC_BTS: - op1 = ce.nextArg(); - op2 = ce.nextArg(); -- type = TREE_TYPE (TREE_TYPE (op1)); -- -- exp = build_integer_cst (tree_low_cst (TYPE_SIZE (type), 1), type); -- -- // op1[op2 / exp] -- op1 = build_array_index (op1, fold_build2 (TRUNC_DIV_EXPR, type, op2, exp)); -- op1 = indirect_ref (type, op1); -- -- // mask = 1 << (op2 % exp); -- op2 = fold_build2 (TRUNC_MOD_EXPR, type, op2, exp); -- op2 = fold_build2 (LSHIFT_EXPR, type, size_one_node, op2); -- -- // cond = op1[op2 / size] & mask; -- exp = fold_build2 (BIT_AND_EXPR, type, op1, op2); -- -- // cond ? -1 : 0; -- exp = build3 (COND_EXPR, TREE_TYPE (call_exp), d_truthvalue_conversion (exp), -- integer_minus_one_node, integer_zero_node); -- -- // Update the bit as needed. -- code = (intrinsic == INTRINSIC_BTC) ? BIT_XOR_EXPR : -- (intrinsic == INTRINSIC_BTR) ? BIT_AND_EXPR : -- (intrinsic == INTRINSIC_BTS) ? BIT_IOR_EXPR : ERROR_MARK; -- gcc_assert (code != ERROR_MARK); -- -- // op1[op2 / size] op= mask -- if (intrinsic == INTRINSIC_BTR) -- op2 = build1 (BIT_NOT_EXPR, TREE_TYPE (op2), op2); -- -- val = build_local_var (TREE_TYPE (call_exp)); -- exp = vmodify_expr (val, exp); -- op1 = vmodify_expr (op1, fold_build2 (code, TREE_TYPE (op1), op1, op2)); -- return compound_expr (exp, compound_expr (op1, val)); -+ return expand_intrinsic_bt (intrinsic, callexp, op1, op2); - - case INTRINSIC_BSWAP: - /* Backend provides builtin bswap32. - Assumes first argument and return type is uint. */ - op1 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_BSWAP32), 1, op1); -+ return expand_intrinsic_op (BUILT_IN_BSWAP32, callexp, op1); - -- case INTRINSIC_COS: - // Math intrinsics just map to their GCC equivalents. -+ case INTRINSIC_COS: - op1 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_COSL), 1, op1); -+ return expand_intrinsic_op (BUILT_IN_COSL, callexp, op1); - - case INTRINSIC_SIN: - op1 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_SINL), 1, op1); -+ return expand_intrinsic_op (BUILT_IN_SINL, callexp, op1); - - case INTRINSIC_RNDTOL: -- // %% not sure if llroundl stands as a good replacement -- // for the expected behaviour of rndtol. -+ // Not sure if llroundl stands as a good replacement for the -+ // expected behaviour of rndtol. - op1 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_LLROUNDL), 1, op1); -+ return expand_intrinsic_op (BUILT_IN_LLROUNDL, callexp, op1); - - case INTRINSIC_SQRT: - // Have float, double and real variants of sqrt. - op1 = ce.nextArg(); -- type = TREE_TYPE (op1); -- // Could have used mathfn_built_in, but that only returns -- // implicit built in decls. -- if (TYPE_MAIN_VARIANT (type) == double_type_node) -- exp = builtin_decl_explicit (BUILT_IN_SQRT); -- else if (TYPE_MAIN_VARIANT (type) == float_type_node) -- exp = builtin_decl_explicit (BUILT_IN_SQRTF); -- else if (TYPE_MAIN_VARIANT (type) == long_double_type_node) -- exp = builtin_decl_explicit (BUILT_IN_SQRTL); -+ type = TYPE_MAIN_VARIANT (TREE_TYPE (op1)); - // op1 is an integral type - use double precision. -- else if (INTEGRAL_TYPE_P (TYPE_MAIN_VARIANT (type))) -- { -- op1 = convert (double_type_node, op1); -- exp = builtin_decl_explicit (BUILT_IN_SQRT); -- } -+ if (INTEGRAL_TYPE_P (type)) -+ op1 = convert (double_type_node, op1); - -- gcc_assert (exp); // Should never trigger. -- return d_build_call_nary (exp, 1, op1); -+ if (type == double_type_node) -+ return expand_intrinsic_op (BUILT_IN_SQRT, callexp, op1); -+ else if (type == float_type_node) -+ return expand_intrinsic_op (BUILT_IN_SQRTF, callexp, op1); -+ else if (type == long_double_type_node) -+ return expand_intrinsic_op (BUILT_IN_SQRTL, callexp, op1); ++ a) place your modifications in the Public Domain or otherwise make them ++ Freely Available, such as by posting said modifications to Usenet or ++ an equivalent medium, or placing the modifications on a major archive ++ site such as uunet.uu.net, or by allowing the Copyright Holder to include ++ your modifications in the Standard Version of the Package. + -+ gcc_unreachable(); -+ break; - - case INTRINSIC_LDEXP: - op1 = ce.nextArg(); - op2 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_LDEXPL), 2, op1, op2); -+ return expand_intrinsic_op2 (BUILT_IN_LDEXPL, callexp, op1, op2); - - case INTRINSIC_FABS: - op1 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_FABSL), 1, op1); -+ return expand_intrinsic_op (BUILT_IN_FABSL, callexp, op1); - - case INTRINSIC_RINT: - op1 = ce.nextArg(); -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_RINTL), 1, op1); -+ return expand_intrinsic_op (BUILT_IN_RINTL, callexp, op1); - - case INTRINSIC_VA_ARG: -- case INTRINSIC_C_VA_ARG: - op1 = ce.nextArg(); -- STRIP_NOPS (op1); -- -- if (TREE_CODE (op1) == ADDR_EXPR) -- op1 = TREE_OPERAND (op1, 0); -- -- if (intrinsic == INTRINSIC_C_VA_ARG) -- type = TREE_TYPE (TREE_TYPE (callee)); -- else -- { -- op2 = ce.nextArg(); -- STRIP_NOPS (op2); -- gcc_assert (TREE_CODE (op2) == ADDR_EXPR); -- op2 = TREE_OPERAND (op2, 0); -- type = TREE_TYPE (op2); -- } -- -- d_type = build_dtype (type); -- if (flag_split_darrays -- && (d_type && d_type->toBasetype()->ty == Tarray)) -- { -- /* should create a temp var of type TYPE and move the binding -- to outside this expression. */ -- tree ltype = TREE_TYPE (TYPE_FIELDS (type)); -- tree ptype = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (type))); -- tree lvar = create_temporary_var (ltype); -- tree pvar = create_temporary_var (ptype); -- -- op1 = stabilize_reference (op1); -- -- tree e1 = vmodify_expr (lvar, build1 (VA_ARG_EXPR, ltype, op1)); -- tree e2 = vmodify_expr (pvar, build1 (VA_ARG_EXPR, ptype, op1)); -- tree val = d_array_value (type, lvar, pvar); -- -- exp = compound_expr (compound_expr (e1, e2), val); -- exp = bind_expr (lvar, bind_expr (pvar, exp)); -- } -- else -- { -- tree type2 = lang_hooks.types.type_promotes_to (type); -- exp = build1 (VA_ARG_EXPR, type2, op1); -- // silently convert promoted type... -- if (type != type2) -- exp = convert (type, exp); -- } -- -- if (intrinsic == INTRINSIC_VA_ARG) -- exp = vmodify_expr (op2, exp); -+ op2 = ce.nextArg(); -+ return expand_intrinsic_vaarg (callexp, op1, op2); - -- return exp; -+ case INTRINSIC_C_VA_ARG: -+ op1 = ce.nextArg(); -+ return expand_intrinsic_vaarg (callexp, op1, NULL_TREE); - - case INTRINSIC_VA_START: -- /* The va_list argument should already have its -- address taken. The second argument, however, is -- inout and that needs to be fixed to prevent a warning. */ - op1 = ce.nextArg(); - op2 = ce.nextArg(); -- type = TREE_TYPE (op1); -- -- // could be casting... so need to check type too? -- STRIP_NOPS (op1); -- STRIP_NOPS (op2); -- gcc_assert (TREE_CODE (op1) == ADDR_EXPR -- && TREE_CODE (op2) == ADDR_EXPR); -- -- op2 = TREE_OPERAND (op2, 0); -- // assuming nobody tries to change the return type -- return d_build_call_nary (builtin_decl_explicit (BUILT_IN_VA_START), 2, op1, op2); -+ return expand_intrinsic_vastart (callexp, op1, op2); - - default: - gcc_unreachable(); - } - } - -- return call_exp; -+ return callexp; - } - - // Build and return the correct call to fmod depending on TYPE. - // ARG0 and ARG1 are the arguments pass to the function. - - tree --IRState::floatMod (tree type, tree arg0, tree arg1) -+build_float_modulus (tree type, tree arg0, tree arg1) - { - tree fmodfn = NULL_TREE; - tree basetype = type; -@@ -3037,7 +2761,7 @@ IRState::floatMod (tree type, tree arg0, - if (!fmodfn) - { - // %qT pretty prints the tree type. -- ::error ("tried to perform floating-point modulo division on %qT", type); -+ error ("tried to perform floating-point modulo division on %qT", type); - return error_mark_node; - } - -@@ -3056,11 +2780,11 @@ IRState::floatMod (tree type, tree arg0, - // Returns typeinfo reference for type T. - - tree --IRState::typeinfoReference (Type *t) -+build_typeinfo (Type *t) - { -- tree ti_ref = t->getInternalTypeInfo (NULL)->toElem (this); -- gcc_assert (POINTER_TYPE_P (TREE_TYPE (ti_ref))); -- return ti_ref; -+ tree tinfo = t->getInternalTypeInfo (NULL)->toElem (current_irstate); -+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (tinfo))); -+ return tinfo; - } - - // Checks if DECL is an intrinsic or runtime library function that -@@ -3081,29 +2805,23 @@ maybe_set_builtin_frontend (FuncDeclarat - if (libcall_decls[libcall] == decl) - return; - -+ // This should have been done either by the front-end or get_libcall. - TypeFunction *tf = (TypeFunction *) decl->type; -- if (tf->parameters == NULL) -- { -- FuncDeclaration *new_decl = get_libcall (libcall); -- new_decl->toSymbol(); -- -- decl->type = new_decl->type; -- decl->csym = new_decl->csym; -- } -+ gcc_assert (tf->parameters != NULL); - - libcall_decls[libcall] = decl; - } - else - { - // Check if it's a front-end builtin. -- static const char FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real) -- static const char FeZe2[] = "FNaNbNeeZe"; // @trusted pure nothrow real function(real) -- static const char FuintZint[] = "FNaNbNfkZi"; // @safe pure nothrow int function(uint) -- static const char FuintZuint[] = "FNaNbNfkZk"; // @safe pure nothrow uint function(uint) -- static const char FulongZint[] = "FNaNbNfmZi"; // @safe pure nothrow int function(uint) -- static const char FrealZlong [] = "FNaNbNfeZl"; // @safe pure nothrow long function(real) -- static const char FlongplongZint [] = "FNaNbNfPmmZi"; // @safe pure nothrow int function(long*, long) -- static const char FintpintZint [] = "FNaNbNfPkkZi"; // @safe pure nothrow int function(int*, int) -+ static const char FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real) -+ static const char FeZe2[] = "FNaNbNeeZe"; // @trusted pure nothrow real function(real) -+ static const char FuintZint[] = "FNaNbNfkZi"; // @safe pure nothrow int function(uint) -+ static const char FuintZuint[] = "FNaNbNfkZk"; // @safe pure nothrow uint function(uint) -+ static const char FulongZint[] = "FNaNbNfmZi"; // @safe pure nothrow int function(uint) -+ static const char FrealZlong [] = "FNaNbNfeZl"; // @safe pure nothrow long function(real) -+ static const char FlongplongZint [] = "FNaNbPmmZi"; // pure nothrow int function(long*, long) -+ static const char FintpintZint [] = "FNaNbPkkZi"; // pure nothrow int function(int*, int) - static const char FrealintZint [] = "FNaNbNfeiZe"; // @safe pure nothrow real function(real, int) - - Dsymbol *dsym = decl->toParent(); -@@ -3130,20 +2848,20 @@ maybe_set_builtin_frontend (FuncDeclarat - - switch (i) - { -- case 0: -- case 1: -+ case INTRINSIC_BSF: -+ case INTRINSIC_BSR: - if (!(strcmp (ftype->deco, FuintZint) == 0 || strcmp (ftype->deco, FulongZint) == 0)) - return; - break; - -- case 2: -+ case INTRINSIC_BSWAP: - if (!(strcmp (ftype->deco, FuintZuint) == 0)) - return; - break; - -- case 3: -- case 4: -- case 5: -+ case INTRINSIC_BTC: -+ case INTRINSIC_BTR: -+ case INTRINSIC_BTS: - if (!(strcmp (ftype->deco, FlongplongZint) == 0 || strcmp (ftype->deco, FintpintZint) == 0)) - return; - break; -@@ -3161,8 +2879,7 @@ maybe_set_builtin_frontend (FuncDeclarat - // Matches order of Intrinsic enum - static const char *math_names[] = { - "cos", "fabs", "ldexp", -- "rint", "rndtol", "sin", -- "sqrt", -+ "rint", "rndtol", "sin", "sqrt", - }; - const size_t sz = sizeof (math_names) / sizeof (char *); - int i = binary (decl->ident->string, math_names, sz); -@@ -3170,38 +2887,39 @@ maybe_set_builtin_frontend (FuncDeclarat - if (i == -1) - return; - -+ // Adjust 'i' for this range of enums -+ i += INTRINSIC_COS; -+ gcc_assert (i >= INTRINSIC_COS && i <= INTRINSIC_SQRT); ++ b) use the modified Package only within your corporation or organization. + - switch (i) - { -- case 0: -- case 1: -- case 3: -- case 5: -+ case INTRINSIC_COS: -+ case INTRINSIC_FABS: -+ case INTRINSIC_RINT: -+ case INTRINSIC_SIN: - if (!(strcmp (ftype->deco, FeZe) == 0 || strcmp (ftype->deco, FeZe2) == 0)) - return; - break; - -- case 2: -+ case INTRINSIC_LDEXP: - if (!(strcmp (ftype->deco, FrealintZint) == 0)) - return; - break; - -- case 4: -+ case INTRINSIC_RNDTOL: - if (!(strcmp (ftype->deco, FrealZlong) == 0)) - return; - break; - -- case 6: -- if (!(strcmp (ftype->deco, "FNaNbNfdZd") == 0 || //double -- strcmp (ftype->deco, "FNaNbNffZf") == 0 || //& float version -- strcmp (ftype->deco, FeZe) == 0 || -- strcmp (ftype->deco, FeZe2) == 0)) -+ case INTRINSIC_SQRT: -+ if (!(strcmp (ftype->deco, "FNaNbNfdZd") == 0 -+ || strcmp (ftype->deco, "FNaNbNffZf") == 0 -+ || strcmp (ftype->deco, FeZe) == 0 -+ || strcmp (ftype->deco, FeZe2) == 0)) - return; - break; - } - -- // Adjust 'i' for this range of enums -- i += INTRINSIC_COS; -- gcc_assert (i >= INTRINSIC_COS && i <= INTRINSIC_SQRT); - tree t = decl->toSymbol()->Stree; - - // rndtol returns a long type, sqrt any float type, -@@ -3278,24 +2996,24 @@ d_build_label (Loc loc, Identifier *iden - - // Not setting this doesn't seem to cause problems (unlike VAR_DECLs). - if (loc.filename) -- object_file->setDeclLoc (decl, loc); -+ set_decl_location (decl, loc); - - return decl; - } - --// If NESTED_SYM is a nested function, return the static chain to be --// used when invoking that function. -+// If SYM is a nested function, return the static chain to be -+// used when calling that function from FUNC. - --// If NESTED_SYM is a nested class or struct, return the static chain --// to be used when creating an instance of the class. -+// If SYM is a nested class or struct, return the static chain -+// to be used when creating an instance of the class from FUNC. - - tree --IRState::getFrameForSymbol (Dsymbol *nested_sym) -+get_frame_for_symbol (FuncDeclaration *func, Dsymbol *sym) - { -- FuncDeclaration *nested_func = NULL; -+ FuncDeclaration *nested_func = sym->isFuncDeclaration(); - FuncDeclaration *outer_func = NULL; - -- if ((nested_func = nested_sym->isFuncDeclaration())) -+ if (nested_func != NULL) - { - // Check that the nested function is properly defined. - if (!nested_func->fbody) -@@ -3308,16 +3026,19 @@ IRState::getFrameForSymbol (Dsymbol *nes - outer_func = nested_func->toParent2()->isFuncDeclaration(); - gcc_assert (outer_func != NULL); - -- if (this->func != outer_func) -+ if (func != outer_func) - { -- Dsymbol *this_func = this->func; -- if (!this->func->vthis) // if no frame pointer for this function -+ // If no frame pointer for this function -+ if (!func->vthis) - { -- nested_sym->error ("is a nested function and cannot be accessed from %s", this->func->toChars()); -+ sym->error ("is a nested function and cannot be accessed from %s", func->toChars()); - return d_null_pointer; - } -- /* Make sure we can get the frame pointer to the outer function, -- else we'll ICE later in tree-ssa. */ ++ c) rename any non-standard executables so the names do not conflict ++ with standard executables, which must also be provided, and provide ++ a separate manual page for each non-standard executable that clearly ++ documents how it differs from the Standard Version. + -+ Dsymbol *this_func = func; ++ d) make other distribution arrangements with the Copyright Holder. + -+ // Make sure we can get the frame pointer to the outer function, -+ // else we'll ICE later in tree-ssa. - while (nested_func != this_func) - { - FuncDeclaration *fd; -@@ -3327,7 +3048,7 @@ IRState::getFrameForSymbol (Dsymbol *nes - // Special case for __ensure and __require. - if (nested_func->ident == Id::ensure || nested_func->ident == Id::require) - { -- outer_func = this->func; -+ outer_func = func; - break; - } - -@@ -3335,12 +3056,14 @@ IRState::getFrameForSymbol (Dsymbol *nes - { - if (outer_func == fd->toParent2()) - break; ++4. You may distribute the programs of this Package in object code or ++executable form, provided that you do at least ONE of the following: + - gcc_assert (fd->isNested() || fd->vthis); - } - else if ((cd = this_func->isClassDeclaration())) - { - if (!cd->isNested() || !cd->vthis) - goto cannot_get_frame; ++ a) distribute a Standard Version of the executables and library files, ++ together with instructions (in the manual page or equivalent) on where ++ to get the Standard Version. + - if (outer_func == cd->toParent2()) - break; - } -@@ -3348,13 +3071,14 @@ IRState::getFrameForSymbol (Dsymbol *nes - { - if (!sd->isNested() || !sd->vthis) - goto cannot_get_frame; ++ b) accompany the distribution with the machine-readable source of ++ the Package with your modifications. + - if (outer_func == sd->toParent2()) - break; - } - else - { -- cannot_get_frame: -- this->func->error ("cannot get frame pointer to %s", nested_sym->toChars()); -+ cannot_get_frame: -+ func->error ("cannot get frame pointer to %s", sym->toChars()); - return d_null_pointer; - } - this_func = this_func->toParent2(); -@@ -3366,33 +3090,41 @@ IRState::getFrameForSymbol (Dsymbol *nes - /* It's a class (or struct). NewExp::toElem has already determined its - outer scope is not another class, so it must be a function. */ - -- Dsymbol *sym = nested_sym; -- -- while (sym && !(outer_func = sym->isFuncDeclaration())) -+ while (sym && !sym->isFuncDeclaration()) - sym = sym->toParent2(); - -+ outer_func = (FuncDeclaration *) sym; ++ c) give non-standard executables non-standard names, and clearly ++ document the differences in manual pages (or equivalent), together ++ with instructions on where to get the Standard Version. + - /* Make sure we can access the frame of outer_func. */ -- if (outer_func != this->func) -+ if (outer_func != func) - { -- Dsymbol *o = nested_func = this->func; -- do { -+ nested_func = func; -+ while (nested_func && nested_func != outer_func) -+ { -+ Dsymbol *outer = nested_func->toParent2(); ++ d) make other distribution arrangements with the Copyright Holder. + - if (!nested_func->isNested()) - { - if (!nested_func->isMember2()) - goto cannot_access_frame; - } -- while ((o = o->toParent2())) -+ -+ while (outer) - { -- if ((nested_func = o->isFuncDeclaration())) -+ if (outer->isFuncDeclaration()) - break; -+ -+ outer = outer->toParent2(); - } -- } while (o && o != outer_func); - -- if (!o) -+ nested_func = (FuncDeclaration *) outer; -+ } -+ -+ if (!nested_func) - { -- cannot_access_frame: -+ cannot_access_frame: - error ("cannot access frame of function '%s' from '%s'", -- outer_func->toChars(), this->func->toChars()); -+ outer_func->toChars(), func->toChars()); - return d_null_pointer; - } - } -@@ -3400,11 +3132,12 @@ IRState::getFrameForSymbol (Dsymbol *nes - - if (!outer_func) - outer_func = nested_func->toParent2()->isFuncDeclaration(); ++5. You may charge a reasonable copying fee for any distribution of this ++Package. You may charge any fee you choose for support of this ++Package. You may not charge a fee for this Package itself. However, ++you may distribute this Package in aggregate with other (possibly ++commercial) programs as part of a larger (possibly commercial) software ++distribution provided that you do not advertise this Package as a ++product of your own. You may embed this Package's interpreter within ++an executable of yours (by linking); this shall be construed as a mere ++form of aggregation, provided that the complete Standard Version of the ++interpreter is so embedded. + - gcc_assert (outer_func != NULL); - - FuncFrameInfo *ffo = get_frameinfo (outer_func); - if (ffo->creates_frame || ffo->static_chain) -- return get_framedecl (this->func, outer_func); -+ return get_framedecl (func, outer_func); - - return d_null_pointer; - } -@@ -3444,48 +3177,47 @@ d_nested_struct (StructDeclaration *sd) - } - - --// Starting from the current function, try to find a suitable value of --// 'this' in nested function instances. -- --// A suitable 'this' value is an instance of OCD or a class that has --// OCD as a base. -+// Starting from the current function FUNC, try to find a suitable value of -+// 'this' in nested function instances. A suitable 'this' value is an -+// instance of OCD or a class that has OCD as a base. - --tree --IRState::findThis (ClassDeclaration *ocd) -+static tree -+find_this_tree (FuncDeclaration *func, ClassDeclaration *ocd) - { -- FuncDeclaration *fd = func; -- -- while (fd) -+ while (func) - { -- AggregateDeclaration *ad = fd->isThis(); -+ AggregateDeclaration *ad = func->isThis(); - ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL; - - if (cd != NULL) - { - if (ocd == cd) -- return var (fd->vthis); -+ return get_decl_tree (func->vthis, func); - else if (ocd->isBaseOf (cd, NULL)) -- return convert_expr (var (fd->vthis), cd->type, ocd->type); -- else -- fd = d_nested_class (cd); -+ return convert_expr (get_decl_tree (func->vthis, func), cd->type, ocd->type); ++6. The source code and object code supplied as input to or produced as ++output from the programs of this Package do not automatically fall ++under the copyright of this Package, but belong to whoever generated ++them, and may be sold commercially, and may be aggregated with this ++Package. + -+ func = d_nested_class (cd); - } - else - { -- if (fd->isNested()) -- fd = fd->toParent2()->isFuncDeclaration(); -- else -- fd = NULL; -+ if (func->isNested()) -+ { -+ func = func->toParent2()->isFuncDeclaration(); -+ continue; -+ } ++7. Aggregation of this Package with a commercial distribution is always ++permitted provided that the use of this Package is embedded; that is, ++when no overt attempt is made to make this Package's interfaces visible ++to the end user of the commercial distribution. Such use shall not be ++construed as a distribution of this Package. + -+ func = NULL; - } - } ++8. The name of the Copyright Holder may not be used to endorse or promote ++products derived from this software without specific prior written permission. + - return NULL_TREE; - } - --// Return the outer class/struct 'this' value. --// This is here mostly due to removing duplicate code, --// and clean implementation purposes. -+// Retrieve the outer class/struct 'this' value of DECL from the function FD -+// where E is the expression requiring 'this'. - - tree --IRState::getVThis (Dsymbol *decl, Expression *e) -+build_vthis (Dsymbol *decl, FuncDeclaration *fd, Expression *e) - { - ClassDeclaration *cd = decl->isClassDeclaration(); - StructDeclaration *sd = decl->isStructDeclaration(); -@@ -3500,25 +3232,23 @@ IRState::getVThis (Dsymbol *decl, Expres - - if (cdo) - { -- vthis_value = findThis (cdo); -+ vthis_value = find_this_tree (fd, cdo); - if (vthis_value == NULL_TREE) - e->error ("outer class %s 'this' needed to 'new' nested class %s", - cdo->toChars(), cd->toChars()); - } - else if (fdo) - { -- /* If a class nested in a function has no methods -- and there are no other nested functions, -- lower_nested_functions is never called and any -- STATIC_CHAIN_EXPR created here will never be -- translated. Use a null pointer for the link in -- this case. */ -+ // If a class nested in a function has no methods and there -+ // are no other nested functions, any static chain created -+ // here will never be translated. Use a null pointer for the -+ // link in this case. - FuncFrameInfo *ffo = get_frameinfo (fdo); - if (ffo->creates_frame || ffo->static_chain - || fdo->hasNestedFrameRefs()) -- vthis_value = getFrameForSymbol (cd); -+ vthis_value = get_frame_for_symbol (fd, cd); - else if (fdo->vthis && fdo->vthis->type != Type::tvoidptr) -- vthis_value = var (fdo->vthis); -+ vthis_value = get_decl_tree (fdo->vthis, fd); - else - vthis_value = d_null_pointer; - } -@@ -3533,7 +3263,7 @@ IRState::getVThis (Dsymbol *decl, Expres - - if (cdo) - { -- vthis_value = findThis (cdo); -+ vthis_value = find_this_tree (fd, cdo); - if (vthis_value == NULL_TREE) - e->error ("outer class %s 'this' needed to create nested struct %s", - cdo->toChars(), sd->toChars()); -@@ -3543,9 +3273,7 @@ IRState::getVThis (Dsymbol *decl, Expres - FuncFrameInfo *ffo = get_frameinfo (fdo); - if (ffo->creates_frame || ffo->static_chain - || fdo->hasNestedFrameRefs()) -- vthis_value = getFrameForSymbol (sd); -- else if (fdo->vthis && fdo->vthis->type != Type::tvoidptr) -- vthis_value = var (fdo->vthis); -+ vthis_value = get_frame_for_symbol (fd, sd); - else - vthis_value = d_null_pointer; - } -@@ -3556,53 +3284,6 @@ IRState::getVThis (Dsymbol *decl, Expres - return vthis_value; - } - --// Build static chain decl for FUNC to be passed to nested functions in D. -- --void --IRState::buildChain (FuncDeclaration *func) --{ -- FuncFrameInfo *ffi = get_frameinfo (func); -- -- if (ffi->is_closure) -- { -- // Build closure pointer, which is initialised on heap. -- func->buildClosure (this); -- return; -- } -- -- if (!ffi->creates_frame) -- return; -- -- tree frame_rec_type = build_frame_type (func); -- gcc_assert(COMPLETE_TYPE_P (frame_rec_type)); -- -- tree frame_decl = build_local_var (frame_rec_type); -- DECL_NAME (frame_decl) = get_identifier ("__frame"); -- DECL_IGNORED_P (frame_decl) = 0; -- expandDecl (frame_decl); -- -- // set the first entry to the parent frame, if any -- tree chain_field = component_ref (frame_decl, TYPE_FIELDS (frame_rec_type)); -- tree chain_expr = vmodify_expr (chain_field, this->sthis); -- addExp (chain_expr); -- -- // copy parameters that are referenced nonlocally -- for (size_t i = 0; i < func->closureVars.dim; i++) -- { -- VarDeclaration *v = func->closureVars[i]; -- if (!v->isParameter()) -- continue; -- -- Symbol *vsym = v->toSymbol(); -- -- tree frame_field = component_ref (frame_decl, vsym->SframeField); -- tree frame_expr = vmodify_expr (frame_field, vsym->Stree); -- addExp (frame_expr); -- } -- -- this->sthis = build_address (frame_decl); --} -- - tree - build_frame_type (FuncDeclaration *func) - { -@@ -3620,6 +3301,7 @@ build_frame_type (FuncDeclaration *func) - tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, - get_identifier ("__chain"), ptr_type_node); - DECL_CONTEXT (ptr_field) = frame_rec_type; -+ TYPE_READONLY (frame_rec_type) = 1; - - tree fields = chainon (NULL_TREE, ptr_field); - -@@ -3672,15 +3354,20 @@ build_frame_type (FuncDeclaration *func) - v->ident ? get_identifier (v->ident->string) : NULL_TREE, - declaration_type (v)); - s->SframeField = field; -- object_file->setDeclLoc (field, v); -+ set_decl_location (field, v); - DECL_CONTEXT (field) = frame_rec_type; - fields = chainon (fields, field); - TREE_USED (s->Stree) = 1; - -- /* Can't do nrvo if the variable is put in a frame. */ -+ // Can't do nrvo if the variable is put in a frame. - if (func->nrvo_can && func->nrvo_var == v) - func->nrvo_can = 0; -+ -+ // Because the value needs to survive the end of the scope. -+ if (ffi->is_closure && v->needsAutoDtor()) -+ v->error("has scoped destruction, cannot build closure"); - } ++9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR ++IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + - TYPE_FIELDS (frame_rec_type) = fields; - layout_type (frame_rec_type); - d_keep (frame_rec_type); -@@ -3782,7 +3469,7 @@ get_frameinfo (FuncDeclaration *fd) - tree - get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer) - { -- tree result = cirstate->sthis; -+ tree result = current_irstate->sthis; - FuncDeclaration *fd = inner; - - while (fd && fd != outer) -@@ -3835,7 +3522,7 @@ get_framedecl (FuncDeclaration *inner, F - } - - // Special case: If a function returns a nested class with functions --// but there are no "closure variables" the frontend (needsClosure) -+// but there are no "closure variables" the frontend (needsClosure) - // returns false even though the nested class _is_ returned from the - // function. (See case 4 in needsClosure) - // A closure is strictly speaking not necessary, but we also can not -@@ -3853,7 +3540,7 @@ is_degenerate_closure (FuncDeclaration * - gcc_assert(tret); - tret = tret->toBasetype(); - if (tret->ty == Tclass || tret->ty == Tstruct) -- { -+ { - Dsymbol *st = tret->toDsymbol(NULL); - for (Dsymbol *s = st->parent; s; s = s->parent) - { -@@ -3880,7 +3567,7 @@ needs_static_chain (FuncDeclaration *f) - { - s = f->toParent(); - ti = s->isTemplateInstance(); -- if (ti && ti->isnested == NULL && ti->parent->isModule()) -+ if (ti && ti->enclosing == NULL && ti->parent->isModule()) - return false; - - pf = f->toParent2()->isFuncDeclaration(); -@@ -3916,7 +3603,7 @@ needs_static_chain (FuncDeclaration *f) - // Construct a WrappedExp, whose components are an EXP_NODE, which contains - // a list of instructions in GCC to be passed through. - --WrappedExp::WrappedExp (Loc loc, enum TOK op, tree exp_node, Type *type) -+WrappedExp::WrappedExp (Loc loc, TOK op, tree exp_node, Type *type) - : Expression (loc, op, sizeof (WrappedExp)) - { - this->exp_node = exp_node; -@@ -3943,135 +3630,149 @@ WrappedExp::toElem (IRState *) - // out base class fields first, and adds all interfaces last. - - void --AggLayout::visit (AggregateDeclaration *decl) -+layout_aggregate_type (AggLayout *al, AggregateDeclaration *decl) - { -- ClassDeclaration *class_decl = decl->isClassDeclaration(); -+ ClassDeclaration *cd = decl->isClassDeclaration(); -+ bool inherited_p = (al->decl != decl); - -- if (class_decl && class_decl->baseClass) -- AggLayout::visit (class_decl->baseClass); -+ if (cd != NULL) -+ { -+ if (cd->baseClass) -+ layout_aggregate_type (al, cd->baseClass); -+ else -+ { -+ // This is the base class (Object) or interface. -+ tree objtype = TREE_TYPE (cd->type->toCtype()); - -- if (decl->fields.dim) -- doFields (&decl->fields, decl); -+ // Add the virtual table pointer, and optionally the monitor fields. -+ tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, -+ get_identifier ("__vptr"), d_vtbl_ptr_type_node); -+ DECL_ARTIFICIAL (field) = 1; -+ DECL_IGNORED_P (field) = inherited_p; - -- if (class_decl && class_decl->vtblInterfaces) -- doInterfaces (class_decl->vtblInterfaces); --} -+ insert_aggregate_field (al, field, 0); - -+ DECL_VIRTUAL_P (field) = 1; -+ DECL_FCONTEXT (field) = objtype; -+ TYPE_VFIELD (al->type) = field; - --// Add all FIELDS into aggregate AGG. -+ if (cd->cpp == false) -+ { -+ field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, -+ get_identifier ("__monitor"), ptr_type_node); -+ DECL_FCONTEXT (field) = objtype; -+ DECL_ARTIFICIAL (field) = 1; -+ DECL_IGNORED_P (field) = inherited_p; -+ insert_aggregate_field (al, field, Target::ptrsize); -+ } -+ } -+ } - --void --AggLayout::doFields (VarDeclarations *fields, AggregateDeclaration *agg) --{ -- bool inherited = agg != this->aggDecl_; -- tree fcontext; -+ if (decl->fields.dim) -+ { -+ tree fcontext = decl->type->toCtype(); - -- fcontext = agg->type->toCtype(); -- if (POINTER_TYPE_P (fcontext)) -- fcontext = TREE_TYPE (fcontext); -+ if (POINTER_TYPE_P (fcontext)) -+ fcontext = TREE_TYPE (fcontext); - -- for (size_t i = 0; i < fields->dim; i++) -- { -- // %% D anonymous unions just put the fields into the outer struct... -- // does this cause problems? -- VarDeclaration *var_decl = (*fields)[i]; -- gcc_assert (var_decl && var_decl->storage_class & STCfield); -+ for (size_t i = 0; i < decl->fields.dim; i++) -+ { -+ // D anonymous unions just put the fields into the outer struct... -+ // Does this cause problems? -+ VarDeclaration *var = decl->fields[i]; -+ gcc_assert (var && var->isField()); - -- tree ident = var_decl->ident ? get_identifier (var_decl->ident->string) : NULL_TREE; -- tree field_decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, ident, -- declaration_type (var_decl)); -- object_file->setDeclLoc (field_decl, var_decl); -- var_decl->csym = new Symbol; -- var_decl->csym->Stree = field_decl; -+ tree ident = var->ident ? get_identifier (var->ident->string) : NULL_TREE; -+ tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, ident, -+ declaration_type (var)); -+ set_decl_location (field, var); -+ var->csym = new Symbol; -+ var->csym->Stree = field; - -- DECL_CONTEXT (field_decl) = this->aggType_; -- DECL_FCONTEXT (field_decl) = fcontext; -- DECL_FIELD_OFFSET (field_decl) = size_int (var_decl->offset); -- DECL_FIELD_BIT_OFFSET (field_decl) = bitsize_zero_node; -+ DECL_CONTEXT (field) = al->type; -+ DECL_FCONTEXT (field) = fcontext; -+ DECL_FIELD_OFFSET (field) = size_int (var->offset); -+ DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node; - -- DECL_ARTIFICIAL (field_decl) = DECL_IGNORED_P (field_decl) = inherited; -- SET_DECL_OFFSET_ALIGN (field_decl, TYPE_ALIGN (TREE_TYPE (field_decl))); -+ DECL_ARTIFICIAL (field) = inherited_p; -+ DECL_IGNORED_P (field) = inherited_p; -+ SET_DECL_OFFSET_ALIGN (field, TYPE_ALIGN (TREE_TYPE (field))); - -- layout_decl (field_decl, 0); -+ TREE_THIS_VOLATILE (field) = TYPE_VOLATILE (TREE_TYPE (field)); -+ layout_decl (field, 0); - -- TREE_THIS_VOLATILE (field_decl) = TYPE_VOLATILE (TREE_TYPE (field_decl)); -+ if (var->size (var->loc)) -+ { -+ gcc_assert (DECL_MODE (field) != VOIDmode); -+ gcc_assert (DECL_SIZE (field) != NULL_TREE); -+ } - -- if (var_decl->size (var_decl->loc)) -- { -- gcc_assert (DECL_MODE (field_decl) != VOIDmode); -- gcc_assert (DECL_SIZE (field_decl) != NULL_TREE); -+ TYPE_FIELDS(al->type) = chainon (TYPE_FIELDS (al->type), field); - } -- -- TYPE_FIELDS(this->aggType_) = chainon (TYPE_FIELDS (this->aggType_), field_decl); - } --} - --// Write out all interfaces BASES for a class. -- --void --AggLayout::doInterfaces (BaseClasses *bases) --{ -- for (size_t i = 0; i < bases->dim; i++) -+ if (cd && cd->vtblInterfaces) - { -- BaseClass *bc = (*bases)[i]; -- tree decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, -- Type::tvoidptr->pointerTo()->toCtype()); -- DECL_ARTIFICIAL (decl) = 1; -- DECL_IGNORED_P (decl) = 1; -- addField (decl, bc->offset); -+ for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) -+ { -+ BaseClass *bc = (*cd->vtblInterfaces)[i]; -+ tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, -+ Type::tvoidptr->pointerTo()->toCtype()); -+ DECL_ARTIFICIAL (field) = 1; -+ DECL_IGNORED_P (field) = 1; -+ insert_aggregate_field (al, field, bc->offset); -+ } - } - } - --// Add single field FIELD_DECL at OFFSET into aggregate. -+// Add a compiler generated field DECL at OFFSET into aggregate. - - void --AggLayout::addField (tree field_decl, size_t offset) -+insert_aggregate_field (AggLayout *al, tree decl, size_t offset) - { -- Loc l (this->aggDecl_->getModule(), 1); -- -- DECL_CONTEXT (field_decl) = this->aggType_; -- SET_DECL_OFFSET_ALIGN (field_decl, TYPE_ALIGN (TREE_TYPE (field_decl))); -- DECL_FIELD_OFFSET (field_decl) = size_int (offset); -- DECL_FIELD_BIT_OFFSET (field_decl) = bitsize_zero_node; -+ DECL_CONTEXT (decl) = al->type; -+ SET_DECL_OFFSET_ALIGN (decl, TYPE_ALIGN (TREE_TYPE (decl))); -+ DECL_FIELD_OFFSET (decl) = size_int (offset); -+ DECL_FIELD_BIT_OFFSET (decl) = bitsize_zero_node; - - // Must set this or we crash with DWARF debugging. -- object_file->setDeclLoc (field_decl, l); -+ set_decl_location (decl, al->decl->loc); - -- TREE_THIS_VOLATILE (field_decl) = TYPE_VOLATILE (TREE_TYPE (field_decl)); -+ TREE_THIS_VOLATILE (decl) = TYPE_VOLATILE (TREE_TYPE (decl)); - -- layout_decl (field_decl, 0); -- TYPE_FIELDS(this->aggType_) = chainon (TYPE_FIELDS (this->aggType_), field_decl); -+ layout_decl (decl, 0); -+ TYPE_FIELDS(al->type) = chainon (TYPE_FIELDS (al->type), decl); - } - --// Wrap-up and compute finalised aggregate type. ATTRS are --// if any GCC attributes were applied to the type declaration. -+// Wrap-up and compute finalised aggregate type. Writing out -+// any GCC attributes that were applied to the type declaration. - - void --AggLayout::finish (Expressions *attrs) -+finish_aggregate_type (AggLayout *al, Expressions *attrs) - { -- unsigned structsize = this->aggDecl_->structsize; -- unsigned alignsize = this->aggDecl_->alignsize; -+ unsigned structsize = al->decl->structsize; -+ unsigned alignsize = al->decl->alignsize; - -- TYPE_SIZE (this->aggType_) = NULL_TREE; -+ TYPE_SIZE (al->type) = NULL_TREE; - - if (attrs) -- decl_attributes (&this->aggType_, build_attributes (attrs), -+ decl_attributes (&al->type, build_attributes (attrs), - ATTR_FLAG_TYPE_IN_PLACE); - -- TYPE_SIZE (this->aggType_) = bitsize_int (structsize * BITS_PER_UNIT); -- TYPE_SIZE_UNIT (this->aggType_) = size_int (structsize); -- TYPE_ALIGN (this->aggType_) = alignsize * BITS_PER_UNIT; -- TYPE_PACKED (this->aggType_) = (alignsize == 1); -+ TYPE_SIZE (al->type) = bitsize_int (structsize * BITS_PER_UNIT); -+ TYPE_SIZE_UNIT (al->type) = size_int (structsize); -+ TYPE_ALIGN (al->type) = alignsize * BITS_PER_UNIT; -+ TYPE_PACKED (al->type) = (alignsize == 1); - -- compute_record_mode (this->aggType_); -+ compute_record_mode (al->type); - - // Set up variants. -- for (tree x = TYPE_MAIN_VARIANT (this->aggType_); x; x = TYPE_NEXT_VARIANT (x)) -+ for (tree x = TYPE_MAIN_VARIANT (al->type); x; x = TYPE_NEXT_VARIANT (x)) - { -- TYPE_FIELDS (x) = TYPE_FIELDS (this->aggType_); -- TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (this->aggType_); -- TYPE_ALIGN (x) = TYPE_ALIGN (this->aggType_); -- TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (this->aggType_); -+ TYPE_FIELDS (x) = TYPE_FIELDS (al->type); -+ TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (al->type); -+ TYPE_ALIGN (x) = TYPE_ALIGN (al->type); -+ TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (al->type); - } - } - ---- a/src/gcc/d/d-codegen.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-codegen.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-codegen.h -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -45,34 +45,12 @@ enum LibCall - { - LIBCALL_NONE = -1, - LIBCALL_INVARIANT, -- LIBCALL_AAPPLYRCD1, LIBCALL_AAPPLYRCD2, -- LIBCALL_AAPPLYRCW1, LIBCALL_AAPPLYRCW2, -- LIBCALL_AAPPLYRDC1, LIBCALL_AAPPLYRDC2, -- LIBCALL_AAPPLYRDW1, LIBCALL_AAPPLYRDW2, -- LIBCALL_AAPPLYRWC1, LIBCALL_AAPPLYRWC2, -- LIBCALL_AAPPLYRWD1, LIBCALL_AAPPLYRWD2, -- LIBCALL_AAPPLYCD1, LIBCALL_AAPPLYCD2, -- LIBCALL_AAPPLYCW1, LIBCALL_AAPPLYCW2, -- LIBCALL_AAPPLYDC1, LIBCALL_AAPPLYDC2, -- LIBCALL_AAPPLYDW1, LIBCALL_AAPPLYDW2, -- LIBCALL_AAPPLYWC1, LIBCALL_AAPPLYWC2, -- LIBCALL_AAPPLYWD1, LIBCALL_AAPPLYWD2, -- LIBCALL_AAAPPLY, LIBCALL_AAAPPLY2, - - LIBCALL_AADELX, LIBCALL_AAEQUAL, - LIBCALL_AAGETRVALUEX, LIBCALL_AAGETX, - LIBCALL_AAINX, -- LIBCALL_AALEN, - -- LIBCALL_ADCMP, LIBCALL_ADCMP2, -- LIBCALL_ADDUPT, -- LIBCALL_ADEQ, LIBCALL_ADEQ2, -- LIBCALL_ADREVERSE, -- LIBCALL_ADREVERSECHAR, -- LIBCALL_ADREVERSEWCHAR, -- LIBCALL_ADSORT, -- LIBCALL_ADSORTCHAR, -- LIBCALL_ADSORTWCHAR, -+ LIBCALL_ADCMP2, LIBCALL_ADEQ2, - - LIBCALL_ALLOCMEMORY, - LIBCALL_ARRAY_BOUNDS, -@@ -96,9 +74,6 @@ enum LibCall - LIBCALL_CALLFINALIZER, - LIBCALL_CALLINTERFACEFINALIZER, - -- LIBCALL_CRITICALENTER, -- LIBCALL_CRITICALEXIT, -- - LIBCALL_DELARRAY, LIBCALL_DELARRAYT, - LIBCALL_DELCLASS, LIBCALL_DELINTERFACE, - LIBCALL_DELMEMORY, -@@ -107,9 +82,6 @@ enum LibCall - LIBCALL_HIDDEN_FUNC, - LIBCALL_INTERFACE_CAST, - -- LIBCALL_MONITORENTER, -- LIBCALL_MONITOREXIT, -- - LIBCALL_NEWARRAYT, LIBCALL_NEWARRAYIT, - LIBCALL_NEWARRAYMTX, LIBCALL_NEWARRAYMITX, - LIBCALL_NEWCLASS, LIBCALL_NEWITEMT, -@@ -147,6 +119,8 @@ extern tree d_mark_used (tree exp); - extern tree d_mark_read (tree exp); - extern tree build_address (tree exp); - -+extern tree build_struct_memcmp (tree_code code, StructDeclaration *sd, tree arg0, tree arg1); -+ - // Routines to handle variables that are references. - extern bool decl_reference_p (Declaration *decl); - extern tree declaration_type (Declaration *decl); -@@ -163,6 +137,7 @@ extern tree insert_type_modifiers (tree - extern tree build_two_field_type (tree t1, tree t2, Type *type, const char *n1, const char *n2); - - extern tree build_exception_object (void); -+extern tree build_float_modulus (tree type, tree t1, tree t2); - - extern tree indirect_ref (tree type, tree exp); - extern tree build_deref (tree exp); -@@ -171,9 +146,6 @@ extern tree maybe_compound_expr (tree ar - extern tree maybe_vcompound_expr (tree arg0, tree arg1); - - extern tree bind_expr (tree var_chain, tree body); -- --extern bool error_mark_p (tree t); -- - extern tree d_build_label (Loc loc, Identifier *ident); - - // Type conversion. -@@ -184,9 +156,11 @@ extern tree convert_expr (tree exp, Type - extern tree convert_for_assignment (tree expr, Type *exp_type, Type *target_type); - extern tree convert_for_condition (tree expr, Type *type); - -+extern tree d_array_convert (Expression *exp); -+ - // Simple constants - extern tree build_integer_cst (dinteger_t value, tree type = integer_type_node); --extern tree build_float_cst (const real_t& value, Type *target_type); -+extern tree build_float_cst (const real_t& value, Type *totype); - - extern dinteger_t cst_to_hwi (double_int cst); - extern dinteger_t tree_to_hwi (tree t); -@@ -205,12 +179,15 @@ extern tree get_array_length (tree exp, - extern tree void_okay_p (tree t); - - // Various expressions -+extern tree build_binary_op (tree_code code, tree type, tree arg0, tree arg1); - extern tree build_array_index (tree ptr, tree index); --extern tree build_offset_op (enum tree_code op, tree ptr, tree idx); -+extern tree build_offset_op (tree_code op, tree ptr, tree idx); - extern tree build_offset (tree ptr_node, tree byte_offset); - - // Function calls --extern tree d_build_call (tree type, tree callee, tree args); -+extern tree d_build_call (FuncDeclaration *fd, tree object, Expressions *args); -+extern tree d_build_call (TypeFunction *tf, tree callable, tree object, Expressions *arguments); -+extern tree d_build_call_list (tree type, tree callee, tree args); - extern tree d_build_call_nary (tree callee, int n_args, ...); - - extern tree d_assert_call (Loc loc, LibCall libcall, tree msg = NULL_TREE); -@@ -220,14 +197,24 @@ extern tree build_frame_type (FuncDeclar - extern FuncFrameInfo *get_frameinfo (FuncDeclaration *fd); - extern tree get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer); - -+extern tree build_vthis (Dsymbol *decl, FuncDeclaration *fd, Expression *e); -+ -+// Static chain for nested functions -+extern tree get_frame_for_symbol (FuncDeclaration *func, Dsymbol *sym); -+ - extern bool needs_static_chain (FuncDeclaration *f); - - // Local variables --extern tree build_local_var (tree type); -+extern void build_local_var (VarDeclaration *vd, FuncDeclaration *fd); -+extern tree build_local_temp (tree type); - extern tree create_temporary_var (tree type); - extern tree maybe_temporary_var (tree exp, tree *out_var); -+extern void expand_decl (tree decl); -+ -+extern tree get_decl_tree (Declaration *decl, FuncDeclaration *func); - - // Temporaries (currently just SAVE_EXPRs) -+extern tree make_temp (tree t); - extern tree maybe_make_temp (tree t); - extern bool d_has_side_effects (tree t); - -@@ -238,6 +225,10 @@ extern bool array_bounds_check (void); - extern tree d_checked_index (Loc loc, tree index, tree upr, bool inclusive); - extern tree d_bounds_condition (tree index, tree upr, bool inclusive); - -+// Classes -+extern tree build_class_binfo (tree super, ClassDeclaration *cd); -+extern tree build_interface_binfo (tree super, ClassDeclaration *cd, unsigned& offset); -+ - // Delegates - extern tree delegate_method (tree exp); - extern tree delegate_object (tree exp); -@@ -255,6 +246,8 @@ extern tree maybe_expand_builtin (tree c - - extern void maybe_set_builtin_frontend (FuncDeclaration *decl); - -+extern tree build_typeinfo (Type *t); -+ - // Type management for D frontend types. - // Returns TRUE if T1 and T2 are mutably the same type. - inline bool -@@ -342,7 +335,7 @@ build_vconvert (tree t, tree e) - } - - inline tree --build_boolop (enum tree_code code, tree arg0, tree arg1) -+build_boolop (tree_code code, tree arg0, tree arg1) - { - return fold_build2_loc (input_location, code, boolean_type_node, arg0, arg1); - } -@@ -359,14 +352,6 @@ vcompound_expr (tree arg0, tree arg1) - return build2_loc (input_location, COMPOUND_EXPR, void_type_node, arg0, arg1); - } - --// Giving error_mark_node a type allows for some assumptions about --// the type of an arbitrary expression. --inline tree --error_mark (Type *t) --{ -- return build1_loc (input_location, NOP_EXPR, t->toCtype(), error_mark_node); --} -- - // Routines for built in structured types - inline tree - real_part (tree c) -@@ -391,99 +376,34 @@ extern TypeFunction *get_function_type ( - extern bool call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee); - - --// Code generation routines should be in a separate namespace, but so many --// routines need a reference to an IRState to expand Expressions. Solution --// is to make IRState the code generation namespace with the actual IR state --// routines as a mixin. Also a lot of routines are static (don't need IR --// state or expand Expressions), but are still called using . or ->. -- --// Functions without a verb create trees --// Functions with 'do' affect the current instruction stream (or output assembler code). --// functions with other names are for attribute manipulate, etc. -- --struct IRState : IRBase --{ -- public: -- // ** Local variables -- void emitLocalVar (VarDeclaration *v, bool no_init = false); -- -- void expandDecl (tree t_decl); -- -- tree var (Declaration *decl); -- -- // ** Type conversion -- tree convertForArgument (Expression *exp, Parameter *arg); -- tree toDArray (Expression *exp); -- -- // ** Various expressions -- static tree buildOp (enum tree_code code, tree type, tree arg0, tree arg1); -- tree buildAssignOp (enum tree_code code, Type *type, Expression *e1, Expression *e2); -- -- tree arrayElemRef (IndexExp *aer_exp, ArrayScope *aryscp); -- -- void doArraySet (tree in_ptr, tree in_value, tree in_count); -- tree arraySetExpr (tree ptr, tree value, tree count); -- -- // ** Function calls -- tree call (Expression *expr, Expressions *arguments); -- tree call (FuncDeclaration *func_decl, Expressions *args); -- tree call (FuncDeclaration *func_decl, tree object, Expressions *args); -- tree call (TypeFunction *guess, tree callable, tree object, Expressions *arguments); -- -- static tree floatMod (tree type, tree arg0, tree arg1); -- -- tree typeinfoReference (Type *t); -- -- void buildChain (FuncDeclaration *func); -- -- tree findThis (ClassDeclaration *target_cd); -- tree getVThis (Dsymbol *decl, Expression *e); -- -- // Static chain for nested functions -- tree getFrameForSymbol (Dsymbol *nested_sym); -- -- protected: -- tree maybeExpandSpecialCall (tree call_exp); --}; -- - // Globals. --extern Module *cmodule; --extern IRState *cirstate; --extern ObjectFile *object_file; -+extern Module *current_module_decl; -+extern IRState *current_irstate; - - // Various helpers that need extra state - --struct WrappedExp : Expression -+class WrappedExp : public Expression - { -+public: - tree exp_node; -- WrappedExp (Loc loc, enum TOK op, tree exp_node, Type *type); -+ WrappedExp (Loc loc, TOK op, tree exp_node, Type *type); - void toCBuffer (OutBuffer *buf, HdrGenState *hgs); - elem *toElem (IRState *irs); - }; - --class AggLayout -+struct AggLayout - { -- public: -- AggLayout (AggregateDeclaration *ini_agg_decl, tree ini_agg_type) -- : aggDecl_(ini_agg_decl), -- aggType_(ini_agg_type) -- { } -- -- void go (void) -- { visit (this->aggDecl_); } -- -- void visit (AggregateDeclaration *decl); -- -- void doFields (VarDeclarations *fields, AggregateDeclaration *agg); -- void doInterfaces (BaseClasses *bases); -- void addField (tree field_decl, size_t offset); -- void finish (Expressions *attrs); -- -- private: -- AggregateDeclaration *aggDecl_; -- tree aggType_; -+ AggLayout (AggregateDeclaration *indecl, tree intype) -+ : decl (indecl), type (intype) { } -+ -+ AggregateDeclaration *decl; -+ tree type; - }; - -+extern void layout_aggregate_type (AggLayout *al, AggregateDeclaration *decl); -+extern void insert_aggregate_field (AggLayout *al, tree field, size_t offset); -+extern void finish_aggregate_type (AggLayout *al, Expressions *attrs); -+ - class ArrayScope - { - public: ---- a/src/gcc/d/d-convert.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-convert.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-convert.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -26,19 +26,19 @@ static tree - d_convert_basic (tree type, tree expr) - { - tree e = expr; -- enum tree_code code = TREE_CODE (type); -- const char *invalid_conv_diag; -- tree ret; -+ tree_code code = TREE_CODE (type); - - if (type == error_mark_node - || expr == error_mark_node - || TREE_TYPE (expr) == error_mark_node) - return error_mark_node; - -- invalid_conv_diag = targetm.invalid_conversion (TREE_TYPE (expr), type); -+ const char *invalid_conv_diag -+ = targetm.invalid_conversion (TREE_TYPE (expr), type); -+ - if (invalid_conv_diag) - { -- error (invalid_conv_diag); -+ error ("%s", invalid_conv_diag); - return error_mark_node; - } - -@@ -50,11 +50,12 @@ d_convert_basic (tree type, tree expr) - && TYPE_DOMAIN (type) == TYPE_DOMAIN (TREE_TYPE (expr))) - return expr; - -- ret = targetm.convert_to_type (type, expr); -+ tree ret = targetm.convert_to_type (type, expr); - if (ret) - return ret; - - STRIP_TYPE_NOPS (e); -+ tree etype = TREE_TYPE (e); - - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold_convert (type, expr); -@@ -73,6 +74,14 @@ d_convert_basic (tree type, tree expr) - - case INTEGER_TYPE: - case ENUMERAL_TYPE: -+ if (TREE_CODE (etype) == POINTER_TYPE -+ || TREE_CODE (etype) == REFERENCE_TYPE) -+ { -+ // Convert to an unsigned integer of the correct width first. -+ tree utype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), 1); -+ e = fold_build1 (CONVERT_EXPR, utype, e); -+ } -+ - ret = convert_to_integer (type, e); - goto maybe_fold; - -@@ -121,7 +130,7 @@ d_convert_basic (tree type, tree expr) - tree - convert (tree type, tree expr) - { -- enum tree_code code = TREE_CODE (type); -+ tree_code code = TREE_CODE (type); - tree etype = TREE_TYPE (expr); - - switch (code) ---- a/src/gcc/d/d-ctype.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-ctype.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-ctype.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -32,7 +32,7 @@ Type::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - switch (ty) - { -@@ -134,7 +134,7 @@ Type::toCtype (void) - - - case Terror: -- return error_mark_node; -+ return d_unknown_type_node; - - /* We can get Tident with forward references. There seems to - be a legitame case (dstress:debug_info_03). I have not seen this -@@ -186,7 +186,7 @@ TypeTypedef::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - tree basetype = sym->basetype->toCtype(); - const char *name = toChars(); -@@ -217,10 +217,10 @@ TypeEnum::toCtype (void) - { - if (!ctype) - { -- /* Enums in D2 can have a base type that is not necessarily integral. -- So don't bother trying to make an ENUMERAL_TYPE using them. */ - if (!sym->memtype->isintegral() || sym->memtype->ty == Tbool) - { -+ // Enums in D2 can have a base type that is not necessarily integral. -+ // So don't bother trying to make an ENUMERAL_TYPE using them. - ctype = sym->memtype->toCtype(); - } - else -@@ -234,9 +234,8 @@ TypeEnum::toCtype (void) - if (flag_short_enums) - TYPE_PACKED (ctype) = 1; - -- TYPE_PRECISION (ctype) = size (0) * 8; -+ TYPE_PRECISION (ctype) = size (sym->loc) * 8; - TYPE_SIZE (ctype) = 0; -- TYPE_MAIN_VARIANT (ctype) = TYPE_MAIN_VARIANT (cmemtype); - - if (sym->userAttributes) - decl_attributes (&ctype, build_attributes (sym->userAttributes), -@@ -247,34 +246,34 @@ TypeEnum::toCtype (void) - layout_type (ctype); - TYPE_UNSIGNED (ctype) = TYPE_UNSIGNED (cmemtype); - -- // Move this to toDebug() ? - tree enum_values = NULL_TREE; - if (sym->members) - { - for (size_t i = 0; i < sym->members->dim; i++) - { -- EnumMember *member = (sym->members->tdata()[i])->isEnumMember(); -+ EnumMember *member = (*sym->members)[i]->isEnumMember(); - // Templated functions can seep through to the backend - just ignore for now. - if (member == NULL) - continue; - -- char *ident = NULL; -- if (sym->ident) -- ident = concat (sym->ident->string, ".", -- member->ident->string, NULL); -- -- tree tident = get_identifier (ident ? ident : member->ident->string); -- tree tvalue = build_integer_cst (member->value->toInteger(), ctype); -- enum_values = chainon (enum_values, build_tree_list (tident, tvalue)); -+ tree ident = get_identifier (member->ident->string); -+ tree value = build_integer_cst (member->value->toInteger(), cmemtype); -+ -+ // Build a identifier for the enumeration constant. -+ tree decl = build_decl (UNKNOWN_LOCATION, CONST_DECL, ident, cmemtype); -+ set_decl_location (decl, member->loc); -+ DECL_CONTEXT (decl) = ctype; -+ TREE_CONSTANT (decl) = 1; -+ TREE_READONLY (decl) = 1; -+ DECL_INITIAL (decl) = value; - -- if (sym->ident) -- free (ident); -+ // Add this enumeration constant to the list for this type. -+ enum_values = chainon (enum_values, build_tree_list (ident, decl)); - } - } -- TYPE_VALUES (ctype) = enum_values; - -- object_file->initTypeDecl (ctype, sym); -- object_file->declareType (ctype, sym); -+ TYPE_VALUES (ctype) = enum_values; -+ build_type_decl (ctype, sym); - } - } - -@@ -291,7 +290,7 @@ TypeStruct::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - // need to set this right away in case of self-references - ctype = make_node (sym->isUnionDeclaration() ? UNION_TYPE : RECORD_TYPE); -@@ -307,11 +306,11 @@ TypeStruct::toCtype (void) - TYPE_PACKED (ctype) = (sym->alignsize == 1); - compute_record_mode (ctype); - -- AggLayout agg_layout (sym, ctype); -- agg_layout.go(); -- agg_layout.finish (sym->userAttributes); -+ AggLayout al = AggLayout (sym, ctype); -+ layout_aggregate_type (&al, sym); -+ finish_aggregate_type (&al, sym->userAttributes); - -- object_file->initTypeDecl (ctype, sym); -+ build_type_decl (ctype, sym); - TYPE_CONTEXT (ctype) = d_decl_context (sym); - } - } -@@ -335,7 +334,7 @@ TypeFunction::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - tree type_list = NULL_TREE; - tree ret_type; -@@ -372,12 +371,16 @@ TypeFunction::toCtype (void) - TYPE_LANG_SPECIFIC (ctype) = build_d_type_lang_specific (this); - d_keep (ctype); - -- if (next->toBasetype()->ty == Tstruct) -+ if (ret_type != void_type_node) - { -- // Non-POD structs must return in memory. -- TypeStruct *ts = (TypeStruct *) next->toBasetype(); -- if (!ts->sym->isPOD()) -- TREE_ADDRESSABLE (ctype) = 1; -+ Type *tn = next->baseElemOf(); -+ if (tn->ty == Tstruct) -+ { -+ // Non-POD structs must return in memory. -+ TypeStruct *ts = (TypeStruct *) tn->toBasetype(); -+ if (!ts->sym->isPOD()) -+ TREE_ADDRESSABLE (ctype) = 1; -+ } - } - - switch (linkage) -@@ -394,7 +397,7 @@ TypeFunction::toCtype (void) - break; - - default: -- fprintf (stderr, "linkage = %d\n", linkage); -+ fprintf (global.stdmsg, "linkage = %d\n", linkage); - gcc_unreachable(); - } - } -@@ -403,7 +406,7 @@ TypeFunction::toCtype (void) - return ctype; - } - --enum RET -+RET - TypeFunction::retStyle (void) - { - /* Return by reference or pointer. */ -@@ -426,13 +429,13 @@ TypeVector::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - int nunits = ((TypeSArray *) basetype)->dim->toUInteger(); - tree inner = elementType()->toCtype(); - - if (inner == void_type_node) -- inner = Type::tint8->toCtype(); -+ inner = Type::tuns8->toCtype(); - - ctype = build_vector_type (inner, nunits); - layout_type (ctype); -@@ -518,7 +521,7 @@ TypeAArray::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - /* Library functions expect a struct-of-pointer which could be passed - differently from a pointer. */ -@@ -528,6 +531,7 @@ TypeAArray::toCtype (void) - DECL_CONTEXT (ptr) = ctype; - TYPE_FIELDS (ctype) = ptr; - TYPE_NAME (ctype) = get_identifier (toChars()); -+ TYPE_TRANSPARENT_AGGR (ctype) = 1; - layout_type (ctype); - - TYPE_LANG_SPECIFIC (ctype) = build_d_type_lang_specific (this); -@@ -548,7 +552,7 @@ TypePointer::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - ctype = build_pointer_type (next->toCtype()); - } -@@ -567,7 +571,7 @@ TypeDelegate::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { - gcc_assert (next->toBasetype()->ty == Tfunction); - tree nexttype = next->toCtype(); -@@ -599,81 +603,48 @@ TypeClass::toCtype (void) - ctype = castMod(0)->toCtype(); - ctype = insert_type_modifiers (ctype, mod); - } -- else -+ else - { -- tree rec_type; -- Array base_class_decls; -- bool inherited = sym->baseClass != 0; -- tree obj_rec_type; -- tree vfield; -- -- /* Need to set ctype right away in case of self-references to -- the type during this call. */ -- rec_type = make_node (RECORD_TYPE); -- ctype = build_reference_type (rec_type); -- d_keep (ctype); // because BINFO moved out to toDebug -- -- obj_rec_type = TREE_TYPE (build_object_type()->toCtype()); -+ // Need to set ctype right away in case of self-references to -+ // the type during this call. -+ tree basetype = make_node (RECORD_TYPE); -+ ctype = build_reference_type (basetype); -+ d_keep (ctype); - -- // Note that this is set on the reference type, not the record type. -+ // Note that this is set on both the reference type and record type. - TYPE_LANG_SPECIFIC (ctype) = build_d_type_lang_specific (this); -+ TYPE_LANG_SPECIFIC (basetype) = TYPE_LANG_SPECIFIC (ctype); - -- AggLayout agg_layout (sym, rec_type); -- -- // Most of this silly code is just to produce correct debugging information. -+ // Add the fields of each base class -+ AggLayout al = AggLayout (sym, basetype); -+ layout_aggregate_type (&al, sym); -+ finish_aggregate_type (&al, sym->userAttributes); - -- /* gdb apparently expects the vtable field to be named -- "_vptr$...." (stabsread.c) Otherwise, the debugger gives -- lots of annoying error messages. C++ appends the class -- name of the first base witht that field after the '$'. */ -- /* update: annoying messages might not appear anymore after making -- other changes */ -- // Add the virtual table pointer -- tree decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, -- get_identifier ("_vptr$"), d_vtbl_ptr_type_node); -- agg_layout.addField (decl, 0); // %% target stuff.. -- -- if (inherited) -- { -- vfield = copy_node (decl); -- DECL_ARTIFICIAL (decl) = DECL_IGNORED_P (decl) = 1; -- } -+ // Create BINFO even if debugging is off. This is needed to keep -+ // references to inherited types. -+ if (!sym->isInterfaceDeclaration()) -+ TYPE_BINFO (basetype) = build_class_binfo (NULL_TREE, sym); - else - { -- vfield = decl; -+ unsigned offset = 0; -+ TYPE_BINFO (basetype) = build_interface_binfo (NULL_TREE, sym, offset); - } -- DECL_VIRTUAL_P (vfield) = 1; -- TYPE_VFIELD (rec_type) = vfield; // This only seems to affect debug info -- TREE_ADDRESSABLE (rec_type) = 1; - -- if (!sym->isInterfaceDeclaration()) -+ // Same for virtual methods too. -+ for (size_t i = 0; i < sym->vtbl.dim; i++) - { -- DECL_FCONTEXT (vfield) = obj_rec_type; -- -- // Add the monitor -- // %% target type -- decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, -- get_identifier ("_monitor"), ptr_type_node); -- DECL_FCONTEXT (decl) = obj_rec_type; -- DECL_ARTIFICIAL (decl) = DECL_IGNORED_P (decl) = inherited; -- agg_layout.addField (decl, Target::ptrsize); -+ FuncDeclaration *fd = sym->vtbl[i]->isFuncDeclaration(); -+ tree method = fd ? fd->toSymbol()->Stree : NULL_TREE; - -- // Add the fields of each base class -- agg_layout.go(); -- } -- else -- { -- ClassDeclaration *p = sym; -- while (p->baseclasses->dim) -- p = (p->baseclasses->tdata()[0])->base; -- -- DECL_FCONTEXT (vfield) = TREE_TYPE (p->type->toCtype()); -+ if (method && DECL_CONTEXT (method) == basetype) -+ { -+ DECL_CHAIN (method) = TYPE_METHODS (basetype); -+ TYPE_METHODS (basetype) = method; -+ } - } - -- agg_layout.finish (sym->userAttributes); -- -- object_file->initTypeDecl (rec_type, sym); -- TYPE_CONTEXT (rec_type) = d_decl_context (sym); -+ build_type_decl (basetype, sym); -+ TYPE_CONTEXT (basetype) = d_decl_context (sym); - } - } - ---- a/src/gcc/d/d-decls.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-decls.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-decls.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -28,34 +28,16 @@ - #include "init.h" - #include "module.h" - #include "statement.h" -+#include "ctfe.h" - - #include "dfrontend/target.h" - --// Construct a SymbolDeclaration, whose components are a symbol S --// and a struct declaration DSYM. -- --SymbolDeclaration::SymbolDeclaration (Loc loc, Symbol *s, StructDeclaration *dsym) -- : Declaration (new Identifier (s->Sident, TOKidentifier)) --{ -- this->loc = loc; -- sym = s; -- this->dsym = dsym; -- storage_class |= STCconst; --} -- - // Create the symbol with tree for struct initialisers. - - Symbol * - SymbolDeclaration::toSymbol (void) - { -- // Create the actual back-end value if not yet done -- if (!sym->Stree) -- { -- if (dsym) -- dsym->toInitializer(); -- gcc_assert (sym->Stree); -- } -- return sym; -+ return dsym->toInitializer(); - } - - -@@ -65,14 +47,19 @@ SymbolDeclaration::toSymbol (void) - Symbol * - Dsymbol::toSymbolX (const char *prefix, int, type *, const char *suffix) - { -- const char *n = mangle(); -- unsigned nlen = strlen (n); -- size_t sz = (2 + nlen + sizeof (size_t) * 3 + strlen (prefix) + strlen (suffix) + 1); -+ const char *symbol = mangle(); -+ unsigned prefixlen = strlen (prefix); -+ size_t sz = (2 + strlen (symbol) + sizeof (size_t) * 3 + prefixlen + strlen (suffix) + 1); - Symbol *s = new Symbol(); - - s->Sident = XNEWVEC (const char, sz); -- snprintf (CONST_CAST (char *, s->Sident), sz, "_D%s%zu%s%s", -- n, strlen (prefix), prefix, suffix); -+ snprintf (CONST_CAST (char *, s->Sident), sz, "_D%s%u%s%s", -+ symbol, prefixlen, prefix, suffix); -+ -+ s->prettyIdent = XNEWVEC (const char, sz); -+ snprintf (CONST_CAST (char *, s->prettyIdent), sz, "%s.%s", -+ toPrettyChars(), prefix); -+ - return s; - } - -@@ -80,30 +67,69 @@ Dsymbol::toSymbolX (const char *prefix, - Symbol * - Dsymbol::toSymbol (void) - { -- fprintf (stderr, "Dsymbol::toSymbol() '%s', kind = '%s'\n", toChars(), kind()); -+ fprintf (global.stdmsg, "Dsymbol::toSymbol() '%s', kind = '%s'\n", toChars(), kind()); - gcc_unreachable(); // BUG: implement - return NULL; - } - --// Generate an import symbol from symbol. -+// Generate an import symbol for debug. If this is a module or package symbol, -+// then build the chain of NAMESPACE_DECLs. - - Symbol * - Dsymbol::toImport (void) - { - if (!isym) - { -- if (!csym) -- csym = toSymbol(); -- isym = toImport (csym); -+ Module *m = this->isModule(); -+ if (m != NULL) -+ { -+ isym = new Symbol(); -+ isym->prettyIdent = this->toPrettyChars(); -+ -+ // Build the module namespace, this is considered toplevel, -+ // regardless if there are parent packages. -+ tree decl = build_decl (UNKNOWN_LOCATION, NAMESPACE_DECL, -+ get_identifier (isym->prettyIdent), -+ void_type_node); -+ isym->Stree = decl; -+ d_keep (decl); -+ -+ Loc loc = (m->md != NULL) ? m->md->loc : Loc (m, 1); -+ set_decl_location (decl, loc); -+ -+ if (output_module_p (m)) -+ DECL_EXTERNAL (decl) = 1; -+ -+ TREE_PUBLIC (decl) = 1; -+ DECL_CONTEXT (decl) = NULL_TREE; -+ } -+ else -+ { -+ // Any other kind of symbol should have their csym set. -+ // If this is an unexpected import, the compiler will throw an error. -+ if (!csym) -+ csym = toSymbol(); -+ -+ isym = toImport (csym); -+ } - } -+ - return isym; - } - -+// Generate an IMPORTED_DECL from symbol SYM. -+ - Symbol * --Dsymbol::toImport (Symbol *) -+Dsymbol::toImport (Symbol *sym) - { -- // This is not used in GDC (yet?) -- return NULL; -+ tree decl = make_node (IMPORTED_DECL); -+ TREE_TYPE (decl) = void_type_node; -+ IMPORTED_DECL_ASSOCIATED_DECL (decl) = sym->Stree; -+ d_keep (decl); -+ -+ Symbol *s = new Symbol(); -+ s->Stree = decl; -+ return s; - } - - -@@ -114,12 +140,9 @@ VarDeclaration::toSymbol (void) - { - if (!csym) - { -- tree var_decl; -- enum tree_code decl_kind; -- - // For field declaration, it is possible for toSymbol to be called - // before the parent's toCtype() -- if (storage_class & STCfield) -+ if (isField()) - { - AggregateDeclaration *parent_decl = toParent()->isAggregateDeclaration(); - gcc_assert (parent_decl); -@@ -139,115 +162,88 @@ VarDeclaration::toSymbol (void) - else - csym->Sident = ident->string; - -- if (storage_class & STCparameter) -- decl_kind = PARM_DECL; -- else if (storage_class & STCmanifest) -- decl_kind = CONST_DECL; -- else -- decl_kind = VAR_DECL; -- -- var_decl = build_decl (UNKNOWN_LOCATION, decl_kind, get_identifier (csym->Sident), -- declaration_type (this)); -- -- csym->Stree = var_decl; -+ tree_code code = isParameter() ? PARM_DECL -+ : !canTakeAddressOf() ? CONST_DECL -+ : VAR_DECL; -+ -+ tree decl = build_decl (UNKNOWN_LOCATION, code, -+ get_identifier (ident->string), -+ declaration_type (this)); -+ DECL_CONTEXT (decl) = d_decl_context (this); -+ set_decl_location (decl, this); - -- if (decl_kind != CONST_DECL) -+ if (isParameter()) - { -- if (isDataseg()) -- { -- tree id = get_identifier (csym->Sident); -- if (protection == PROTpublic || storage_class & (STCstatic | STCextern)) -- id = targetm.mangle_decl_assembler_name (var_decl, id); -- SET_DECL_ASSEMBLER_NAME (var_decl, id); -- } -+ DECL_ARG_TYPE (decl) = TREE_TYPE (decl); -+ gcc_assert (TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL); - } -+ else if (!canTakeAddressOf()) -+ { -+ // Manifest constants have no address in memory. -+ TREE_CONSTANT (decl) = 1; -+ TREE_READONLY (decl) = 1; -+ TREE_STATIC (decl) = 0; -+ } -+ else if (isDataseg()) -+ { -+ if (this->mangleOverride) -+ set_user_assembler_name (decl, this->mangleOverride); -+ else -+ { -+ tree mangle = get_identifier (csym->Sident); - -- DECL_LANG_SPECIFIC (var_decl) = build_d_decl_lang_specific (this); -- d_keep (var_decl); -- object_file->setDeclLoc (var_decl, this); -- -- if (decl_kind == VAR_DECL) -- object_file->setupSymbolStorage (this, var_decl); -- else if (decl_kind == PARM_DECL) -- { -- /* from gcc code: Some languages have different nominal and real types. */ -- // %% What about DECL_ORIGINAL_TYPE, DECL_ARG_TYPE_AS_WRITTEN, DECL_ARG_TYPE ? -- DECL_ARG_TYPE (var_decl) = TREE_TYPE (var_decl); -- DECL_CONTEXT (var_decl) = d_decl_context (this); -- gcc_assert (TREE_CODE (DECL_CONTEXT (var_decl)) == FUNCTION_DECL); -- } -- else if (decl_kind == CONST_DECL) -- { -- /* Not sure how much of an optimization this is... It is needed -- for foreach loops on tuples which 'declare' the index variable -- as a constant for each iteration. */ -- Expression *e = NULL; -+ if (protection == PROTpublic || storage_class & (STCstatic | STCextern)) -+ mangle = targetm.mangle_decl_assembler_name (decl, mangle); - -- if (init) -- { -- if (!init->isVoidInitializer()) -- { -- e = init->toExpression(); -- gcc_assert (e != NULL); -- } -+ SET_DECL_ASSEMBLER_NAME (decl, mangle); - } -- else -- e = type->defaultInit(); - -- if (e) -- DECL_INITIAL (var_decl) = e->toElem (cirstate); -+ setup_symbol_storage (this, decl, false); - } - -+ DECL_LANG_SPECIFIC (decl) = build_d_decl_lang_specific (this); -+ d_keep (decl); -+ csym->Stree = decl; -+ - // Can't set TREE_STATIC, etc. until we get to toObjFile as this could be -- // called from a varaible in an imported module -- // %% (out const X x) doesn't mean the reference is const... -+ // called from a variable in an imported module. - if ((isConst() || isImmutable()) && (storage_class & STCinit) - && !decl_reference_p (this)) - { -- // %% CONST_DECLS don't have storage, so we can't use those, -- // but it would be nice to get the benefit of them (could handle in -- // VarExp -- makeAddressOf could switch back to the VAR_DECL -- -- if (!TREE_STATIC (var_decl)) -- TREE_READONLY (var_decl) = 1; -+ if (!TREE_STATIC (decl)) -+ TREE_READONLY (decl) = 1; - else - csym->Sreadonly = true; - -- // can at least do this... -- // const doesn't seem to matter for aggregates, so prevent problems.. -+ // Const doesn't seem to matter for aggregates, so prevent problems. - if (isConst() && isDataseg()) -- TREE_CONSTANT (var_decl) = 1; -+ TREE_CONSTANT (decl) = 1; - } - - // Propagate volatile. -- if (TYPE_VOLATILE (TREE_TYPE (var_decl))) -- TREE_THIS_VOLATILE (var_decl) = 1; -+ if (TYPE_VOLATILE (TREE_TYPE (decl))) -+ TREE_THIS_VOLATILE (decl) = 1; - - #if TARGET_DLLIMPORT_DECL_ATTRIBUTES - // Have to test for import first - if (isImportedSymbol()) - { -- insert_decl_attributes (var_decl, "dllimport"); -- DECL_DLLIMPORT_P (var_decl) = 1; -+ insert_decl_attribute (decl, "dllimport"); -+ DECL_DLLIMPORT_P (decl) = 1; - } - else if (isExport()) -- insert_decl_attributes (var_decl, "dllexport"); -+ insert_decl_attribute (decl, "dllexport"); - #endif - -- if (isDataseg() && isThreadlocal()) -+ if (global.params.vtls && isDataseg() && isThreadlocal()) - { -- // Tell backend this is a thread local decl. -- DECL_TLS_MODEL (var_decl) = decl_default_tls_model (var_decl); -- -- if (global.params.vtls) -- { -- char *p = loc.toChars(); -- fprintf (stderr, "%s: %s is thread local\n", p ? p : "", toChars()); -- if (p) -- free (p); -- } -+ char *p = loc.toChars(); -+ fprintf (global.stdmsg, "%s: %s is thread local\n", p ? p : "", toChars()); -+ if (p) -+ free (p); - } - } -+ - return csym; - } - -@@ -259,14 +255,6 @@ ClassInfoDeclaration::toSymbol (void) - return cd->toSymbol(); - } - --// Create the symbol with tree for moduleinfo decls. -- --Symbol * --ModuleInfoDeclaration::toSymbol (void) --{ -- return mod->toSymbol(); --} -- - // Create the symbol with tree for typeinfo decls. - - Symbol * -@@ -280,12 +268,14 @@ TypeInfoDeclaration::toSymbol (void) - // given TypeInfo. It is the actual data, not a reference - gcc_assert (TREE_CODE (TREE_TYPE (csym->Stree)) == REFERENCE_TYPE); - TREE_TYPE (csym->Stree) = TREE_TYPE (TREE_TYPE (csym->Stree)); -+ relayout_decl (csym->Stree); - TREE_USED (csym->Stree) = 1; - -- // In gdc, built-in typeinfo will be referenced as one-only. -+ // Built-in typeinfo will be referenced as one-only. - D_DECL_ONE_ONLY (csym->Stree) = 1; -- object_file->makeDeclOneOnly (csym->Stree); -+ d_comdat_linkage (csym->Stree); - } -+ - return csym; - } - -@@ -317,180 +307,154 @@ FuncDeclaration::toSymbol (void) - { - csym = new Symbol(); - -- if (!isym) -- { -- tree id; -- TypeFunction *ftype = (TypeFunction *) (tintro ? tintro : type); -- tree fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, -- NULL_TREE, NULL_TREE); -- tree fntype = NULL_TREE; -- tree vindex = NULL_TREE; -+ TypeFunction *ftype = (TypeFunction *) (tintro ? tintro : type); -+ tree fntype = NULL_TREE; -+ tree vindex = NULL_TREE; - -- csym->Stree = fndecl; -- -- if (ident) -- id = get_identifier (ident->string); -- else -- { -- static unsigned unamed_seq = 0; -- char buf[64]; -- snprintf (buf, sizeof(buf), "___unamed_%u", ++unamed_seq); -- id = get_identifier (buf); -- } -- DECL_NAME (fndecl) = id; -- DECL_CONTEXT (fndecl) = d_decl_context (this); -- -- if (needs_static_chain (this)) -- { -- D_DECL_STATIC_CHAIN (fndecl) = 1; -- // Save context and set decl_function_context for cgraph. -- csym->ScontextDecl = DECL_CONTEXT (fndecl); -- DECL_CONTEXT (fndecl) = decl_function_context (fndecl); -- } -+ // Save mangle/debug names for making thunks. -+ csym->Sident = mangleExact(); -+ csym->prettyIdent = toPrettyChars(); - -+ tree id = get_identifier (this->isMain() -+ ? csym->prettyIdent : ident->string); -+ tree fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, id, NULL_TREE); -+ DECL_CONTEXT (fndecl) = d_decl_context (this); - -- /* Nested functions may not have its toObjFile called before the outer -- function is finished. GCC requires that nested functions be finished -- first so we need to arrange for toObjFile to be called earlier. */ -- Dsymbol *outer = toParent2(); -- if (outer && outer->isFuncDeclaration()) -- { -- Symbol *osym = outer->toSymbol(); -+ csym->Stree = fndecl; - -- if (osym->outputStage != Finished) -- ((FuncDeclaration *) outer)->deferred.push (this); -- } -+ if (needs_static_chain (this)) -+ { -+ D_DECL_STATIC_CHAIN (fndecl) = 1; -+ // Save context and set decl_function_context for cgraph. -+ csym->ScontextDecl = DECL_CONTEXT (fndecl); -+ DECL_CONTEXT (fndecl) = decl_function_context (fndecl); -+ } - -- TREE_TYPE (fndecl) = ftype->toCtype(); -- DECL_LANG_SPECIFIC (fndecl) = build_d_decl_lang_specific (this); -- d_keep (fndecl); -+ TREE_TYPE (fndecl) = ftype->toCtype(); -+ DECL_LANG_SPECIFIC (fndecl) = build_d_decl_lang_specific (this); -+ d_keep (fndecl); - -- if (isNested()) -- { -- /* Even if D-style nested functions are not implemented, add an -- extra argument to be compatible with delegates. */ -- fntype = build_method_type (void_type_node, TREE_TYPE (fndecl)); -- } -- else if (isThis()) -- { -- // Do this even if there is no debug info. It is needed to make -- // sure member functions are not called statically -- AggregateDeclaration *agg_decl = isMember2(); -- tree handle = agg_decl->handle->toCtype(); -- -- // If handle is a pointer type, get record type. -- if (!agg_decl->isStructDeclaration()) -- handle = TREE_TYPE (handle); -+ if (isNested()) -+ { -+ // Even if D-style nested functions are not implemented, add an -+ // extra argument to be compatible with delegates. -+ fntype = build_method_type (void_type_node, TREE_TYPE (fndecl)); -+ } -+ else if (isThis()) -+ { -+ // Do this even if there is no debug info. It is needed to make -+ // sure member functions are not called statically -+ AggregateDeclaration *agg_decl = isMember2(); -+ tree handle = agg_decl->handle->toCtype(); - -- fntype = build_method_type (handle, TREE_TYPE (fndecl)); -+ // If handle is a pointer type, get record type. -+ if (!agg_decl->isStructDeclaration()) -+ handle = TREE_TYPE (handle); - -- if (isVirtual()) -- vindex = size_int (vtblIndex); -- } -- else if (isMain() && ftype->nextOf()->toBasetype()->ty == Tvoid) -- { -- // void main() implicitly converted to int main(). -- fntype = build_function_type (integer_type_node, TYPE_ARG_TYPES (TREE_TYPE (fndecl))); -- } -+ fntype = build_method_type (handle, TREE_TYPE (fndecl)); - -- if (fntype != NULL_TREE) -- { -- TYPE_ATTRIBUTES (fntype) = TYPE_ATTRIBUTES (TREE_TYPE (fndecl)); -- TYPE_LANG_SPECIFIC (fntype) = TYPE_LANG_SPECIFIC (TREE_TYPE (fndecl)); -- TREE_ADDRESSABLE (fntype) = TREE_ADDRESSABLE (TREE_TYPE (fndecl)); -- TREE_TYPE (fndecl) = fntype; -- d_keep (fntype); -- } -+ if (isVirtual() && vtblIndex != -1) -+ vindex = size_int (vtblIndex); -+ } -+ else if (isMain() && ftype->nextOf()->toBasetype()->ty == Tvoid) -+ { -+ // void main() implicitly converted to int main(). -+ fntype = build_function_type (integer_type_node, TYPE_ARG_TYPES (TREE_TYPE (fndecl))); -+ } - -- if (ident) -- { -- csym->Sident = mangle(); // save for making thunks -- csym->prettyIdent = toPrettyChars(); -- tree id = get_identifier (csym->Sident); -- id = targetm.mangle_decl_assembler_name (fndecl, id); -- SET_DECL_ASSEMBLER_NAME (fndecl, id); -- } -+ if (fntype != NULL_TREE) -+ { -+ TYPE_ATTRIBUTES (fntype) = TYPE_ATTRIBUTES (TREE_TYPE (fndecl)); -+ TYPE_LANG_SPECIFIC (fntype) = TYPE_LANG_SPECIFIC (TREE_TYPE (fndecl)); -+ TREE_ADDRESSABLE (fntype) = TREE_ADDRESSABLE (TREE_TYPE (fndecl)); -+ TREE_TYPE (fndecl) = fntype; -+ d_keep (fntype); -+ } - -- if (vindex) -- { -- DECL_VINDEX (fndecl) = vindex; -- DECL_VIRTUAL_P (fndecl) = 1; -- } -+ if (this->mangleOverride) -+ set_user_assembler_name (fndecl, this->mangleOverride); -+ else -+ { -+ tree mangle = get_identifier (csym->Sident); -+ mangle = targetm.mangle_decl_assembler_name (fndecl, mangle); -+ SET_DECL_ASSEMBLER_NAME (fndecl, mangle); -+ } - -- if (isMember2() || isFuncLiteralDeclaration()) -- { -- // See grokmethod in cp/decl.c -- DECL_DECLARED_INLINE_P (fndecl) = 1; -- DECL_NO_INLINE_WARNING_P (fndecl) = 1; -- } -- // Don't know what to do with this. -- else if (flag_inline_functions && canInline (0, 1, 0)) -- { -- DECL_DECLARED_INLINE_P (fndecl) = 1; -- DECL_NO_INLINE_WARNING_P (fndecl) = 1; -- } -+ if (vindex) -+ { -+ DECL_VINDEX (fndecl) = vindex; -+ DECL_VIRTUAL_P (fndecl) = 1; -+ } - -- if (naked) -- { -- DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl) = 1; -- DECL_UNINLINABLE (fndecl) = 1; -- } -+ if (isMember2() || isFuncLiteralDeclaration()) -+ { -+ // See grokmethod in cp/decl.c -+ DECL_DECLARED_INLINE_P (fndecl) = 1; -+ DECL_NO_INLINE_WARNING_P (fndecl) = 1; -+ } -+ // Don't know what to do with this. -+ else if (flag_inline_functions && canInline (0, 1, 0)) -+ { -+ DECL_DECLARED_INLINE_P (fndecl) = 1; -+ DECL_NO_INLINE_WARNING_P (fndecl) = 1; -+ } - -- // These are always compiler generated. -- if (isArrayOp) -- { -- DECL_ARTIFICIAL (fndecl) = 1; -- D_DECL_ONE_ONLY (fndecl) = 1; -- } -- // So are ensure and require contracts. -- if (ident == Id::ensure || ident == Id::require) -- { -- DECL_ARTIFICIAL (fndecl) = 1; -- TREE_PUBLIC (fndecl) = 1; -- } -+ if (naked) -+ { -+ DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl) = 1; -+ DECL_UNINLINABLE (fndecl) = 1; -+ } - -- if (isStatic()) -- TREE_STATIC (fndecl) = 1; -+ // These are always compiler generated. -+ if (isArrayOp) -+ { -+ DECL_ARTIFICIAL (fndecl) = 1; -+ D_DECL_ONE_ONLY (fndecl) = 1; -+ } -+ // So are ensure and require contracts. -+ if (ident == Id::ensure || ident == Id::require) -+ { -+ DECL_ARTIFICIAL (fndecl) = 1; -+ TREE_PUBLIC (fndecl) = 1; -+ } - -- // Assert contracts in functions cause implicit side effects that could -- // cause wrong codegen if pure/nothrow is thrown in the equation. -- if (!global.params.useAssert) -- { -- // Cannot mark as pure as in 'no side effects' if the function either -- // returns by ref, or has an internal state 'this'. -- // Note, pure D functions don't imply nothrow. -- if (isPure() == PUREstrong && vthis == NULL -- && ftype->isnothrow && ftype->retStyle() == RETstack) -- DECL_PURE_P (fndecl) = 1; -+ // Storage class attributes -+ if (storage_class & STCstatic) -+ TREE_STATIC (fndecl) = 1; - -- if (ftype->isnothrow) -- TREE_NOTHROW (fndecl) = 1; -- } -+ // Assert contracts in functions cause implicit side effects that could -+ // cause wrong codegen if pure/nothrow is thrown in the equation. -+ if (!global.params.useAssert) -+ { -+ // Cannot mark as pure as in 'no side effects' if the function either -+ // returns by ref, or has an internal state 'this'. -+ // Note, pure D functions don't imply nothrow. -+ if (isPure() == PUREstrong && vthis == NULL -+ && ftype->isnothrow && ftype->retStyle() == RETstack) -+ DECL_PURE_P (fndecl) = 1; -+ } - - #if TARGET_DLLIMPORT_DECL_ATTRIBUTES -- // Have to test for import first -- if (isImportedSymbol()) -- { -- insert_decl_attributes (fndecl, "dllimport"); -- DECL_DLLIMPORT_P (fndecl) = 1; -- } -- else if (isExport()) -- insert_decl_attributes (fndecl, "dllexport"); -+ // Have to test for import first -+ if (isImportedSymbol()) -+ { -+ insert_decl_attribute (fndecl, "dllimport"); -+ DECL_DLLIMPORT_P (fndecl) = 1; -+ } -+ else if (isExport()) -+ insert_decl_attribute (fndecl, "dllexport"); - #endif -- object_file->setDeclLoc (fndecl, this); -- object_file->setupSymbolStorage (this, fndecl); -- if (!ident) -- TREE_PUBLIC (fndecl) = 0; -+ set_decl_location (fndecl, this); -+ setup_symbol_storage (this, fndecl, false); - -- TREE_USED (fndecl) = 1; // %% Probably should be a little more intelligent about this -+ if (!ident) -+ TREE_PUBLIC (fndecl) = 0; - -- maybe_set_builtin_frontend (this); -- } -- else -- { -- csym->Stree = isym->Stree; -- } -+ TREE_USED (fndecl) = 1; // %% Probably should be a little more intelligent about this -+ -+ maybe_set_builtin_frontend (this); - } -+ - return csym; - } - -@@ -511,7 +475,7 @@ FuncDeclaration::toThunkSymbol (int offs - is a list of all thunks for a given function. */ - bool found = false; - -- for (size_t i = 0; i < csym->thunks.dim; i++) -+ for (size_t i = 0; i < csym->thunks.length(); i++) - { - thunk = csym->thunks[i]; - if (thunk->offset == offset) -@@ -525,7 +489,7 @@ FuncDeclaration::toThunkSymbol (int offs - { - thunk = new Thunk(); - thunk->offset = offset; -- csym->thunks.push (thunk); -+ csym->thunks.safe_push (thunk); - } - - if (!thunk->symbol) -@@ -540,14 +504,14 @@ FuncDeclaration::toThunkSymbol (int offs - tree thunk_decl = build_decl (DECL_SOURCE_LOCATION (target_func_decl), - FUNCTION_DECL, NULL_TREE, TREE_TYPE (target_func_decl)); - DECL_LANG_SPECIFIC (thunk_decl) = DECL_LANG_SPECIFIC (target_func_decl); -- DECL_CONTEXT (thunk_decl) = d_decl_context (this); // from c++... - TREE_READONLY (thunk_decl) = TREE_READONLY (target_func_decl); - TREE_THIS_VOLATILE (thunk_decl) = TREE_THIS_VOLATILE (target_func_decl); - TREE_NOTHROW (thunk_decl) = TREE_NOTHROW (target_func_decl); - -- /* Thunks inherit the public/private access of the function they are targetting. */ -+ DECL_CONTEXT (thunk_decl) = d_decl_context (this); -+ -+ /* Thunks inherit the public access of the function they are targetting. */ - TREE_PUBLIC (thunk_decl) = TREE_PUBLIC (target_func_decl); -- TREE_PRIVATE (thunk_decl) = TREE_PRIVATE (target_func_decl); - DECL_EXTERNAL (thunk_decl) = 0; - - /* Thunks are always addressable. */ -@@ -569,10 +533,11 @@ FuncDeclaration::toThunkSymbol (int offs - d_keep (thunk_decl); - sthunk->Stree = thunk_decl; - -- object_file->doThunk (thunk_decl, target_func_decl, offset); -+ use_thunk (thunk_decl, target_func_decl, offset); - - thunk->symbol = sthunk; - } -+ - return thunk->symbol; - } - -@@ -587,16 +552,19 @@ ClassDeclaration::toSymbol (void) - csym = toSymbolX ("__Class", 0, 0, "Z"); - - tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL, -- get_identifier (csym->Sident), d_unknown_type_node); -+ get_identifier (csym->prettyIdent), d_unknown_type_node); -+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (csym->Sident)); - csym->Stree = decl; - d_keep (decl); - -- object_file->setupStaticStorage (this, decl); -- object_file->setDeclLoc (decl, this); -+ setup_symbol_storage (this, decl, true); -+ set_decl_location (decl, this); - -+ DECL_ARTIFICIAL (decl) = 1; - // ClassInfo cannot be const data, because we use the monitor on it. - TREE_CONSTANT (decl) = 0; - } -+ - return csym; - } - -@@ -610,19 +578,22 @@ InterfaceDeclaration::toSymbol (void) - csym = toSymbolX ("__Interface", 0, 0, "Z"); - - tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL, -- get_identifier (csym->Sident), d_unknown_type_node); -+ get_identifier (csym->prettyIdent), d_unknown_type_node); -+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (csym->Sident)); - csym->Stree = decl; - d_keep (decl); - -- object_file->setupStaticStorage (this, decl); -- object_file->setDeclLoc (decl, this); -+ setup_symbol_storage (this, decl, true); -+ set_decl_location (decl, this); - -+ DECL_ARTIFICIAL (decl) = 1; - TREE_CONSTANT (decl) = 1; - } -+ - return csym; - } - --// Create the "ModuleInfo" symbol for given module. -+// Create the "ModuleInfo" symbol for a given module. - - Symbol * - Module::toSymbol (void) -@@ -632,20 +603,85 @@ Module::toSymbol (void) - csym = toSymbolX ("__ModuleInfo", 0, 0, "Z"); - - tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL, -- get_identifier (csym->Sident), d_unknown_type_node); -+ get_identifier (csym->prettyIdent), d_unknown_type_node); -+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (csym->Sident)); - csym->Stree = decl; - d_keep (decl); - -- object_file->setupStaticStorage (this, decl); -- object_file->setDeclLoc (decl, this); -+ setup_symbol_storage (this, decl, true); -+ set_decl_location (decl, this); - -+ DECL_ARTIFICIAL (decl) = 1; - // Not readonly, moduleinit depends on this. - TREE_CONSTANT (decl) = 0; - TREE_READONLY (decl) = 0; - } -+ - return csym; - } - -+Symbol * -+StructLiteralExp::toSymbol (void) -+{ -+ if (!sym) -+ { -+ sym = new Symbol(); -+ -+ // Build reference symbol. -+ tree ctype = type->toCtype(); -+ tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, ctype); -+ get_unique_name (decl, "*"); -+ set_decl_location (decl, loc); -+ -+ TREE_PUBLIC (decl) = 0; -+ TREE_STATIC (decl) = 1; -+ TREE_READONLY (decl) = 1; -+ TREE_USED (decl) = 1; -+ DECL_ARTIFICIAL (decl) = 1; -+ -+ sym->Stree = decl; -+ this->sinit = sym; -+ -+ toDt (&sym->Sdt); -+ d_finish_symbol (sym); -+ } -+ -+ return sym; -+} -+ -+Symbol * -+ClassReferenceExp::toSymbol (void) -+{ -+ if (!value->sym) -+ { -+ value->sym = new Symbol(); -+ -+ // Build reference symbol. -+ tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, d_unknown_type_node); -+ char *ident; -+ -+ ASM_FORMAT_PRIVATE_NAME (ident, "*", DECL_UID (decl)); -+ DECL_NAME (decl) = get_identifier (ident); -+ set_decl_location (decl, loc); -+ -+ TREE_PUBLIC (decl) = 0; -+ TREE_STATIC (decl) = 1; -+ TREE_READONLY (decl) = 1; -+ TREE_USED (decl) = 1; -+ DECL_ARTIFICIAL (decl) = 1; -+ -+ value->sym->Stree = decl; -+ value->sym->Sident = ident; -+ -+ toInstanceDt (&value->sym->Sdt); -+ d_finish_symbol (value->sym); -+ -+ value->sinit = value->sym; -+ } -+ -+ return value->sym; -+} -+ - // Create the "vtbl" symbol for ClassDeclaration. - // This is accessible via the ClassData, but since it is frequently - // needed directly (like for rtti comparisons), make it directly accessible. -@@ -655,30 +691,26 @@ ClassDeclaration::toVtblSymbol (void) - { - if (!vtblsym) - { -- tree decl; -- - vtblsym = toSymbolX ("__vtbl", 0, 0, "Z"); - - /* The DECL_INITIAL value will have a different type object from the - VAR_DECL. The back end seems to accept this. */ -- TypeSArray *vtbl_type = new TypeSArray (Type::tvoidptr, -- new IntegerExp (loc, vtbl.dim, Type::tindex)); -- -- decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, -- get_identifier (vtblsym->Sident), vtbl_type->toCtype()); -+ Type *vtbltype = TypeSArray::makeType (loc, Type::tvoidptr, vtbl.dim); -+ tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, -+ get_identifier (vtblsym->prettyIdent), vtbltype->toCtype()); -+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (vtblsym->Sident)); - vtblsym->Stree = decl; - d_keep (decl); - -- object_file->setupStaticStorage (this, decl); -- object_file->setDeclLoc (decl, this); -+ setup_symbol_storage (this, decl, true); -+ set_decl_location (decl, this); - - TREE_READONLY (decl) = 1; - TREE_CONSTANT (decl) = 1; - TREE_ADDRESSABLE (decl) = 1; -- // from cp/class.c -- DECL_CONTEXT (decl) = d_decl_context (this); - DECL_ARTIFICIAL (decl) = 1; -- DECL_VIRTUAL_P (decl) = 1; -+ -+ DECL_CONTEXT (decl) = d_decl_context (this); - DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN; - } - return vtblsym; -@@ -700,31 +732,37 @@ AggregateDeclaration::toInitializer (voi - { - if (!sinit) - { -+ StructDeclaration *sd = isStructDeclaration(); - sinit = toSymbolX ("__init", 0, 0, "Z"); - -- StructDeclaration *sd = isStructDeclaration(); - if (sd) - sinit->Salignment = sd->alignment; - } - -- if (!sinit->Stree && object_file != NULL) -+ if (!sinit->Stree && current_module_decl) - { -- tree struct_type = type->toCtype(); -- if (POINTER_TYPE_P (struct_type)) -- struct_type = TREE_TYPE (struct_type); // for TypeClass, want the RECORD_TYPE, not the REFERENCE_TYPE -- tree t = build_decl (UNKNOWN_LOCATION, VAR_DECL, -- get_identifier (sinit->Sident), struct_type); -- sinit->Stree = t; -- d_keep (t); -- -- object_file->setupStaticStorage (this, t); -- object_file->setDeclLoc (t, this); -- -- TREE_ADDRESSABLE (t) = 1; -- TREE_READONLY (t) = 1; -- TREE_CONSTANT (t) = 1; -- DECL_CONTEXT (t) = 0; // These are always global -+ tree stype; -+ if (isStructDeclaration()) -+ stype = type->toCtype(); -+ else -+ stype = TREE_TYPE (type->toCtype()); -+ -+ sinit->Stree = build_decl (UNKNOWN_LOCATION, VAR_DECL, -+ get_identifier (sinit->prettyIdent), stype); -+ SET_DECL_ASSEMBLER_NAME (sinit->Stree, get_identifier (sinit->Sident)); -+ d_keep (sinit->Stree); -+ -+ setup_symbol_storage (this, sinit->Stree, true); -+ set_decl_location (sinit->Stree, this); -+ -+ TREE_ADDRESSABLE (sinit->Stree) = 1; -+ TREE_READONLY (sinit->Stree) = 1; -+ TREE_CONSTANT (sinit->Stree) = 1; -+ DECL_ARTIFICIAL (sinit->Stree) = 1; -+ // These initialisers are always global. -+ DECL_CONTEXT (sinit->Stree) = NULL_TREE; - } -+ - return sinit; - } - -@@ -733,28 +771,25 @@ AggregateDeclaration::toInitializer (voi - Symbol * - TypedefDeclaration::toInitializer (void) - { -- Symbol *s; -- - if (!sinit) -+ sinit = toSymbolX ("__init", 0, 0, "Z"); -+ -+ if (!sinit->Stree && current_module_decl) - { -- s = toSymbolX ("__init", 0, 0, "Z"); -- sinit = s; -- sinit->Sdt = ((TypeTypedef *) type)->sym->init->toDt(); -- } -- -- if (!sinit->Stree && object_file != NULL) -- { -- tree t = build_decl (UNKNOWN_LOCATION, VAR_DECL, -- get_identifier (sinit->Sident), type->toCtype()); -- sinit->Stree = t; -- d_keep (t); -- -- object_file->setupStaticStorage (this, t); -- object_file->setDeclLoc (t, this); -- TREE_CONSTANT (t) = 1; -- TREE_READONLY (t) = 1; -- DECL_CONTEXT (t) = 0; -+ sinit->Stree = build_decl (UNKNOWN_LOCATION, VAR_DECL, -+ get_identifier (sinit->prettyIdent), type->toCtype()); -+ SET_DECL_ASSEMBLER_NAME (sinit->Stree, get_identifier (sinit->Sident)); -+ d_keep (sinit->Stree); -+ -+ setup_symbol_storage (this, sinit->Stree, true); -+ set_decl_location (sinit->Stree, this); -+ -+ TREE_CONSTANT (sinit->Stree) = 1; -+ TREE_READONLY (sinit->Stree) = 1; -+ DECL_ARTIFICIAL (sinit->Stree) = 1; -+ DECL_CONTEXT (sinit->Stree) = NULL_TREE; - } -+ - return sinit; - } - -@@ -763,92 +798,43 @@ TypedefDeclaration::toInitializer (void) - Symbol * - EnumDeclaration::toInitializer (void) - { -- Symbol *s; -- - if (!sinit) - { - Identifier *ident_save = ident; - if (!ident) - ident = Lexer::uniqueId("__enum"); -- s = toSymbolX ("__init", 0, 0, "Z"); -+ sinit = toSymbolX ("__init", 0, 0, "Z"); - ident = ident_save; -- sinit = s; - } - -- if (!sinit->Stree && object_file != NULL) -+ if (!sinit->Stree && current_module_decl) - { -- tree t = build_decl (UNKNOWN_LOCATION, VAR_DECL, -- get_identifier (sinit->Sident), type->toCtype()); -- sinit->Stree = t; -- d_keep (t); -- -- object_file->setupStaticStorage (this, t); -- object_file->setDeclLoc (t, this); -- TREE_CONSTANT (t) = 1; -- TREE_READONLY (t) = 1; -- DECL_CONTEXT (t) = 0; -+ sinit->Stree = build_decl (UNKNOWN_LOCATION, VAR_DECL, -+ get_identifier (sinit->prettyIdent), type->toCtype()); -+ SET_DECL_ASSEMBLER_NAME (sinit->Stree, get_identifier (sinit->Sident)); -+ d_keep (sinit->Stree); -+ -+ setup_symbol_storage (this, sinit->Stree, true); -+ set_decl_location (sinit->Stree, this); -+ -+ TREE_CONSTANT (sinit->Stree) = 1; -+ TREE_READONLY (sinit->Stree) = 1; -+ DECL_ARTIFICIAL (sinit->Stree) = 1; -+ DECL_CONTEXT (sinit->Stree) = NULL_TREE; - } -+ - return sinit; - } - - --/* Create debug information for a ClassDeclaration's inheritance tree. -- Interfaces are not included. */ --static tree --binfo_for (tree tgt_binfo, ClassDeclaration *cls) --{ -- tree binfo = make_tree_binfo (1); -- // Want RECORD_TYPE, not REFERENCE_TYPE -- TREE_TYPE (binfo) = TREE_TYPE (cls->type->toCtype()); -- BINFO_INHERITANCE_CHAIN (binfo) = tgt_binfo; -- BINFO_OFFSET (binfo) = integer_zero_node; -- -- if (cls->baseClass) -- BINFO_BASE_APPEND (binfo, binfo_for (binfo, cls->baseClass)); -- -- return binfo; --} -- --/* Create debug information for an InterfaceDeclaration's inheritance -- tree. In order to access all inherited methods in the debugger, -- the entire tree must be described. -- -- This function makes assumptions about inherface layout. */ --static tree --intfc_binfo_for (tree tgt_binfo, ClassDeclaration *iface, unsigned& inout_offset) --{ -- tree binfo = make_tree_binfo (iface->baseclasses->dim); -- -- // Want RECORD_TYPE, not REFERENCE_TYPE -- TREE_TYPE (binfo) = TREE_TYPE (iface->type->toCtype()); -- BINFO_INHERITANCE_CHAIN (binfo) = tgt_binfo; -- BINFO_OFFSET (binfo) = size_int (inout_offset * Target::ptrsize); -- -- for (size_t i = 0; i < iface->baseclasses->dim; i++, inout_offset++) -- { -- BaseClass *bc = iface->baseclasses->tdata()[i]; -- BINFO_BASE_APPEND (binfo, intfc_binfo_for (binfo, bc->base, inout_offset)); -- } -- -- return binfo; --} -+// - - void - ClassDeclaration::toDebug (void) - { -- /* Used to create BINFO even if debugging was off. This was needed to keep -- references to inherited types. */ - tree rec_type = TREE_TYPE (type->toCtype()); -- -- if (!isInterfaceDeclaration()) -- TYPE_BINFO (rec_type) = binfo_for (NULL_TREE, this); -- else -- { -- unsigned offset = 0; -- TYPE_BINFO (rec_type) = intfc_binfo_for (NULL_TREE, this, offset); -- } -- -- object_file->declareType (rec_type, this); -+ build_type_decl (rec_type, this); -+ rest_of_type_compilation (rec_type, 1); - } - - void -@@ -860,9 +846,12 @@ EnumDeclaration::toDebug (void) - - tree ctype = type->toCtype(); - -+ if (TREE_CODE (ctype) == ENUMERAL_TYPE) -+ build_type_decl (ctype, this); -+ - // The ctype is not necessarily enum, which doesn't sit well with - // rest_of_type_compilation. Can call this on structs though. -- if (AGGREGATE_TYPE_P (ctype) || TREE_CODE (ctype) == ENUMERAL_TYPE) -+ if (RECORD_OR_UNION_TYPE_P (ctype) || TREE_CODE (ctype) == ENUMERAL_TYPE) - rest_of_type_compilation (ctype, 1); - } - -@@ -875,7 +864,7 @@ void - StructDeclaration::toDebug (void) - { - tree ctype = type->toCtype(); -- object_file->declareType (ctype, this); -+ build_type_decl (ctype, this); - rest_of_type_compilation (ctype, 1); - } - ---- a/src/gcc/d/d-dmd-gcc.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-dmd-gcc.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - /* d-dmd-gcc.h -- D frontend for GCC. -- Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+ Copyright (C) 2011-2013 Free Software Foundation, Inc. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free -@@ -30,10 +30,6 @@ - /* used in module.c */ - extern void d_gcc_magic_module (Module *); - --/* used in template.c */ --extern bool d_gcc_force_templates (void); --extern Module *d_gcc_get_output_module (void); -- - /* used in interpret.c */ - extern Expression *d_gcc_eval_builtin (Loc, FuncDeclaration *, Expressions *); - ---- a/src/gcc/d/d-elem.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-elem.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-elem.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -17,17 +17,18 @@ - - #include "d-system.h" - --#include "id.h" --#include "module.h" - #include "d-lang.h" - #include "d-codegen.h" - -+#include "id.h" -+#include "module.h" -+#include "ctfe.h" - - elem * - Expression::toElem (IRState *) - { - error ("abstract Expression::toElem called"); -- return error_mark (type); -+ return error_mark_node; - } - - elem * -@@ -45,47 +46,64 @@ IdentityExp::toElem (IRState *irs) - Type *tb1 = e1->type->toBasetype(); - Type *tb2 = e2->type->toBasetype(); - -- tree_code code = op == TOKidentity ? EQ_EXPR : NE_EXPR; -+ tree_code code = (op == TOKidentity) ? EQ_EXPR : NE_EXPR; - -- if (tb1->ty == Tstruct || tb1->isfloating()) -+ if ((tb1->ty == Tsarray || tb1->ty == Tarray) -+ && (tb2->ty == Tsarray || tb2->ty == Tarray)) - { -- tree size; -- if (tb1->isfloating()) -- { -- // Assume all padding is at the end of the type. -- size = build_integer_cst (TYPE_PRECISION (e1->type->toCtype()) / BITS_PER_UNIT); -- } -- else -- size = build_integer_cst (e1->type->size()); -+ // Convert arrays to D array types. -+ return build2 (code, type->toCtype(), -+ d_array_convert (e1), d_array_convert (e2)); -+ } -+ else if (tb1->isfloating()) -+ { -+ tree t1 = e1->toElem (irs); -+ tree t2 = e2->toElem (irs); -+ // Assume all padding is at the end of the type. -+ tree size = build_integer_cst (TYPE_PRECISION (e1->type->toCtype()) / BITS_PER_UNIT); - -- // Do bit compare. -- tree t_memcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -- build_address (e1->toElem (irs)), -- build_address (e2->toElem (irs)), -- size); -+ // Do bit compare of floats. -+ tree tmemcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -+ build_address (t1), build_address (t2), size); - -- return build_boolop (code, t_memcmp, integer_zero_node); -+ return build_boolop (code, tmemcmp, integer_zero_node); - } -- else if ((tb1->ty == Tsarray || tb1->ty == Tarray) -- && (tb2->ty == Tsarray || tb2->ty == Tarray)) -+ else if (tb1->ty == Tstruct) - { -- return build2 (code, type->toCtype(), -- irs->toDArray (e1), irs->toDArray (e2)); -- } -- else -- { -- // For operands of other types, identity is defined as being the same as equality. - tree t1 = e1->toElem (irs); - tree t2 = e2->toElem (irs); - -- if (type->iscomplex()) -+ if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode) - { -+ // Bitwise comparison of small structs not returned in memory may -+ // not work due to data holes loosing its zero padding upon return. -+ // Instead do field-by-field comparison of the two structs. -+ StructDeclaration *sd = ((TypeStruct *) tb1)->sym; -+ gcc_assert (d_types_same (tb1, tb2)); -+ -+ // Make temporaries to prevent multiple evaluations. - t1 = maybe_make_temp (t1); - t2 = maybe_make_temp (t2); -+ -+ return build_struct_memcmp (code, sd, t1, t2); - } -+ else -+ { -+ // Do bit compare of structs. -+ tree size = build_integer_cst (e1->type->size()); -+ -+ tree tmemcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -+ build_address (t1), build_address (t2), size); - -- tree t_cmp = build_boolop (code, t1, t2); -- return d_convert (type->toCtype(), t_cmp); -+ return build_boolop (code, tmemcmp, integer_zero_node); -+ } -+ } -+ else -+ { -+ // For operands of other types, identity is defined as being the same as equality. -+ tree tcmp = build_boolop (code, e1->toElem (irs), e2->toElem (irs)); -+ -+ return d_convert (type->toCtype(), tcmp); - } - } - -@@ -95,35 +113,110 @@ EqualExp::toElem (IRState *irs) - Type *tb1 = e1->type->toBasetype(); - Type *tb2 = e2->type->toBasetype(); - -- tree_code code = op == TOKequal ? EQ_EXPR : NE_EXPR; -+ tree_code code = (op == TOKequal) ? EQ_EXPR : NE_EXPR; - - if (tb1->ty == Tstruct) - { -- // Do bit compare of struct's -- tree t_memcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -- build_address (e1->toElem (irs)), -- build_address (e2->toElem (irs)), -- build_integer_cst (e1->type->size())); -+ // Do bit compare of structs -+ tree tmemcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -+ build_address (e1->toElem (irs)), -+ build_address (e2->toElem (irs)), -+ build_integer_cst (e1->type->size())); - -- return build2 (code, type->toCtype(), t_memcmp, integer_zero_node); -+ return build2 (code, type->toCtype(), tmemcmp, integer_zero_node); - } - else if ((tb1->ty == Tsarray || tb1->ty == Tarray) - && (tb2->ty == Tsarray || tb2->ty == Tarray)) - { -- // _adEq2 compares each element. -- Type *telem = tb1->nextOf()->toBasetype(); -- tree args[3]; -- tree result; -+ Type *t1elem = tb1->nextOf()->toBasetype(); -+ Type *t2elem = tb1->nextOf()->toBasetype(); - -- args[0] = irs->toDArray (e1); -- args[1] = irs->toDArray (e2); -- args[2] = irs->typeinfoReference (telem->arrayOf()); -- result = d_convert (type->toCtype(), build_libcall (LIBCALL_ADEQ2, 3, args)); -+ if ((t1elem->isintegral() || t1elem->ty == Tvoid) && t1elem->ty == t2elem->ty) -+ { -+ // Optimise comparisons of arrays of basic types. -+ // For arrays of integers/characters, and void[], replace _adEq2 call with: -+ // e1 == e2 => e1.length == e2.length && memcmp (e1.ptr, e2.ptr, size) == 0; -+ // e1 != e2 => e1.length != e2.length || memcmp (e1.ptr, e2.ptr, size) != 0; -+ // 'size' is e1.length * sizeof(e1[0]) for dynamic arrays, or sizeof(e1) for static arrays. -+ tree t1 = e1->toElem (irs); -+ tree t2 = e2->toElem (irs); -+ // Length, for comparison. -+ tree t1len, t2len; -+ // Pointer to data and data size, to pass to memcmp. -+ tree t1ptr, t2ptr; -+ tree t1size, t2size; -+ -+ // Make temporaries to prevent multiple evaluations. -+ tree t1saved = maybe_make_temp (t1); -+ tree t2saved = maybe_make_temp (t2); -+ -+ if (tb1->ty == Tarray) -+ { -+ t1len = d_array_length (t1saved); -+ t1ptr = d_array_ptr (t1saved); -+ t1size = build2 (MULT_EXPR, size_type_node, t1len, size_int (t1elem->size())); -+ } -+ else -+ { -+ t1len = size_int (((TypeSArray *) tb1)->dim->toInteger()); -+ t1ptr = build_address (t1saved); -+ t1size = size_int (tb1->size()); -+ } - -- if (op == TOKnotequal) -- return build1 (TRUTH_NOT_EXPR, type->toCtype(), result); -+ if (tb2->ty == Tarray) -+ { -+ t2len = d_array_length (t2saved); -+ t2ptr = d_array_ptr (t2saved); -+ t2size = build2 (MULT_EXPR, size_type_node, t2len, size_int (t2elem->size())); -+ } -+ else -+ { -+ t2len = size_int (((TypeSArray *) tb2)->dim->toInteger()); -+ t2ptr = build_address (t2saved); -+ t2size = size_int (tb2->size()); -+ } - -- return result; -+ tree tmemcmp = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, -+ t1ptr, t2ptr, (tb2->ty == Tsarray) ? t2size : t1size); -+ -+ tree result = build2 (code, type->toCtype(), tmemcmp, integer_zero_node); -+ -+ if (tb1->ty == Tsarray && tb2->ty == Tsarray) -+ gcc_assert (tb1->size() == tb2->size()); -+ else -+ { -+ tree_code tcode = (op == TOKequal) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; -+ tree tlencmp = build2 (code, size_type_node, t1len, t2len); -+ -+ result = build_boolop (tcode, tlencmp, result); -+ } -+ -+ // Ensure left-to-right order of evaluation. -+ if (t2 != t2saved) -+ result = compound_expr (t2saved, result); -+ -+ if (t1 != t1saved) -+ result = compound_expr (t1saved, result); -+ -+ return result; -+ } -+ else -+ { -+ // _adEq2 compares each element. -+ tree args[3]; -+ tree result; -+ -+ args[0] = d_array_convert (e1); -+ args[1] = d_array_convert (e2); -+ args[2] = build_typeinfo (t1elem->arrayOf()); -+ -+ result = d_convert (type->toCtype(), build_libcall (LIBCALL_ADEQ2, 3, args)); -+ -+ if (op == TOKnotequal) -+ return build1 (TRUTH_NOT_EXPR, type->toCtype(), result); -+ -+ return result; -+ } - } - else if (tb1->ty == Taarray && tb2->ty == Taarray) - { -@@ -131,7 +224,7 @@ EqualExp::toElem (IRState *irs) - tree args[3]; - tree result; - -- args[0] = irs->typeinfoReference (taa1); -+ args[0] = build_typeinfo (taa1); - args[1] = e1->toElem (irs); - args[2] = e2->toElem (irs); - result = d_convert (type->toCtype(), build_libcall (LIBCALL_AAEQUAL, 3, args)); -@@ -143,33 +236,25 @@ EqualExp::toElem (IRState *irs) - } - else - { -- tree t1 = e1->toElem (irs); -- tree t2 = e2->toElem (irs); -+ tree tcmp = build_boolop (code, e1->toElem (irs), e2->toElem (irs)); - -- if (type->iscomplex()) -- { -- t1 = maybe_make_temp (t1); -- t2 = maybe_make_temp (t2); -- } -- -- tree t_cmp = build_boolop (code, t1, t2); -- return d_convert (type->toCtype(), t_cmp); -+ return d_convert (type->toCtype(), tcmp); - } - } - - elem * - InExp::toElem (IRState *irs) - { -- Type *e2_base_type = e2->type->toBasetype(); -+ Type *tb2 = e2->type->toBasetype(); - AddrOfExpr aoe; -- gcc_assert (e2_base_type->ty == Taarray); -+ gcc_assert (tb2->ty == Taarray); - -- Type *key_type = ((TypeAArray *) e2_base_type)->index->toBasetype(); -+ Type *tkey = ((TypeAArray *) tb2)->index->toBasetype(); - tree args[3]; - - args[0] = e2->toElem (irs); -- args[1] = irs->typeinfoReference (key_type); -- args[2] = aoe.set (convert_expr (e1->toElem (irs), e1->type, key_type)); -+ args[1] = build_typeinfo (tkey); -+ args[2] = aoe.set (convert_expr (e1->toElem (irs), e1->type, tkey)); - - return convert (type->toCtype(), - aoe.finish (build_libcall (LIBCALL_AAINX, 3, args))); -@@ -250,9 +335,9 @@ CmpExp::toElem (IRState *irs) - Type *telem = tb1->nextOf()->toBasetype(); - tree args[3]; - -- args[0] = irs->toDArray (e1); -- args[1] = irs->toDArray (e2); -- args[2] = irs->typeinfoReference (telem->arrayOf()); -+ args[0] = d_array_convert (e1); -+ args[1] = d_array_convert (e2); -+ args[2] = build_typeinfo (telem->arrayOf()); - result = build_libcall (LIBCALL_ADCMP2, 3, args); - - // %% For float element types, warn that NaN is not taken into account? -@@ -294,14 +379,7 @@ AndAndExp::toElem (IRState *irs) - tree t1 = convert_for_condition (e1->toElem (irs), e1->type); - tree t2 = convert_for_condition (e2->toElem (irs), e2->type); - -- if (type->iscomplex()) -- { -- t1 = maybe_make_temp (t1); -- t2 = maybe_make_temp (t2); -- } -- -- tree t = build_boolop (TRUTH_ANDIF_EXPR, t1, t2); -- return d_convert (type->toCtype(), t); -+ return d_convert (type->toCtype(), build_boolop (TRUTH_ANDIF_EXPR, t1, t2)); - } - else - { -@@ -319,14 +397,7 @@ OrOrExp::toElem (IRState *irs) - tree t1 = convert_for_condition (e1->toElem (irs), e1->type); - tree t2 = convert_for_condition (e2->toElem (irs), e2->type); - -- if (type->iscomplex()) -- { -- t1 = maybe_make_temp (t1); -- t2 = maybe_make_temp (t2); -- } -- -- tree t = build_boolop (TRUTH_ORIF_EXPR, t1, t2); -- return d_convert (type->toCtype(), t); -+ return d_convert (type->toCtype(), build_boolop (TRUTH_ORIF_EXPR, t1, t2)); - } - else - { -@@ -341,90 +412,90 @@ elem * - XorExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (BIT_XOR_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (BIT_XOR_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * - OrExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (BIT_IOR_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (BIT_IOR_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * - AndExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (BIT_AND_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (BIT_AND_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * - UshrExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (UNSIGNED_RSHIFT_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (UNSIGNED_RSHIFT_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * - ShrExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (RSHIFT_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (RSHIFT_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * - ShlExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (LSHIFT_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (LSHIFT_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * - ModExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (e1->type->isfloating() ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR, -- type->toCtype(), e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (e1->type->isfloating() ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR, -+ type->toCtype(), e1->toElem (irs), e2->toElem (irs)); - } - - elem * - DivExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (e1->type->isintegral() ? TRUNC_DIV_EXPR : RDIV_EXPR, -- type->toCtype(), e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (e1->type->isintegral() ? TRUNC_DIV_EXPR : RDIV_EXPR, -+ type->toCtype(), e1->toElem (irs), e2->toElem (irs)); - } - - elem * - MulExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildOp (MULT_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (MULT_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * -@@ -455,7 +526,7 @@ PowExp::toElem (IRState *irs) - error ("Array operation %s not implemented", toChars()); - else - error ("%s ^^ %s is not supported", e1->type->toChars(), e2->type->toChars()); -- return error_mark (type); -+ return error_mark_node; - } - - e1_t = d_convert (powtype, e1->toElem (irs)); -@@ -481,31 +552,26 @@ CatExp::toElem (IRState *irs) - - // Flatten multiple concatenations - unsigned n_operands = 2; -- unsigned n_args; -- tree *args; -- Array elem_vars; -- tree result; -- -- { -- Expression *e = e1; -- while (e->op == TOKcat) -- { -- e = ((CatExp *) e)->e1; -- n_operands += 1; -- } -- } -+ { -+ Expression *e = e1; -+ while (e->op == TOKcat) -+ { -+ e = ((CatExp *) e)->e1; -+ n_operands += 1; -+ } -+ } - -- n_args = (1 + (n_operands > 2 ? 1 : 0) + -- n_operands * (n_operands > 2 && flag_split_darrays ? 2 : 1)); -+ unsigned n_args = (1 + (n_operands > 2 ? 1 : 0) + n_operands); - -- args = new tree[n_args]; -- args[0] = irs->typeinfoReference (type); -+ tree *args = new tree[n_args]; -+ args[0] = build_typeinfo (type); - - if (n_operands > 2) - args[1] = build_integer_cst (n_operands, Type::tuns32->toCtype()); - - unsigned ai = n_args - 1; - CatExp *ce = this; -+ vec *elem_vars = NULL; - - while (ce) - { -@@ -521,32 +587,26 @@ CatExp::toElem (IRState *irs) - size_int (1), build_address (expr)); - - if (elem_var) -- elem_vars.push (elem_var); -+ vec_safe_push (elem_vars, elem_var); - } - else -- array_exp = irs->toDArray (oe); -+ array_exp = d_array_convert (oe); - -- if (n_operands > 2 && flag_split_darrays) -- { -- array_exp = maybe_make_temp (array_exp); -- args[ai--] = d_array_ptr (array_exp); // note: filling array -- args[ai--] = d_array_length (array_exp); // backwards, so ptr 1st -- } -- else -- args[ai--] = array_exp; -+ args[ai--] = array_exp; - -- if (ce) -+ if (ce != NULL) - { - if (ce->e1->op != TOKcat) - { -+ // Finish with atomtic lhs - oe = ce->e1; - ce = NULL; -- // finish with atomtic lhs - } - else - { -+ // Continue with lhs CatExp - ce = (CatExp *) ce->e1; -- break; // continue with lhs CatExp -+ break; - } - } - else -@@ -555,14 +615,11 @@ CatExp::toElem (IRState *irs) - } - all_done: - -- result = build_libcall (n_operands > 2 ? LIBCALL_ARRAYCATNT : LIBCALL_ARRAYCATT, -- n_args, args, type->toCtype()); -+ tree result = build_libcall (n_operands > 2 ? LIBCALL_ARRAYCATNT : LIBCALL_ARRAYCATT, -+ n_args, args, type->toCtype()); - -- for (size_t i = 0; i < elem_vars.dim; ++i) -- { -- tree elem_var = (tree) elem_vars.data[i]; -- result = bind_expr (elem_var, result); -- } -+ for (size_t i = 0; i < vec_safe_length (elem_vars); ++i) -+ result = bind_expr ((*elem_vars)[i], result); - - return result; - } -@@ -571,7 +628,7 @@ elem * - MinExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - - // %% faster: check if result is complex - if ((e1->type->isreal() && e2->type->isimaginary()) -@@ -590,15 +647,15 @@ MinExp::toElem (IRState *irs) - } - - // The front end has already taken care of pointer-int and pointer-pointer -- return irs->buildOp (MINUS_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (MINUS_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); - } - - elem * - AddExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - - // %% faster: check if result is complex - if ((e1->type->isreal() && e2->type->isimaginary()) -@@ -615,116 +672,168 @@ AddExp::toElem (IRState *irs) - } - - // The front end has already taken care of (pointer + integer) -- return irs->buildOp (PLUS_EXPR, type->toCtype(), -- e1->toElem (irs), e2->toElem (irs)); -+ return build_binary_op (PLUS_EXPR, type->toCtype(), -+ e1->toElem (irs), e2->toElem (irs)); -+} -+ -+elem * -+BinExp::toElemBin (IRState *irs, int op) -+{ -+ tree_code code = (tree_code) op; -+ -+ // Skip casts for lhs assignment. -+ Expression *e1b = e1; -+ while (e1b->op == TOKcast) -+ { -+ CastExp *ce = (CastExp *) e1b; -+ gcc_assert (d_types_compatible (ce->type, ce->to)); -+ e1b = ce->e1; -+ } -+ -+ // Prevent multiple evaluations of LHS, but watch out! -+ // The LHS expression could be an assignment, to which -+ // it's operation gets lost during gimplification. -+ tree lexpr = NULL_TREE; -+ tree lhs; -+ -+ if (e1b->op == TOKcomma) -+ { -+ CommaExp *ce = (CommaExp *) e1b; -+ lexpr = ce->e1->toElem (irs); -+ lhs = ce->e2->toElem (irs); -+ } -+ else -+ lhs = e1b->toElem (irs); -+ -+ // Build assignment expression. Stabilize lhs for assignment. -+ lhs = stabilize_reference (lhs); -+ -+ tree rhs = build_binary_op (code, e1->type->toCtype(), -+ convert_expr (lhs, e1b->type, e1->type), e2->toElem (irs)); -+ -+ tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type)); -+ -+ if (lexpr) -+ expr = compound_expr (lexpr, expr); -+ -+ return expr; - } - - elem * - XorAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (BIT_XOR_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, BIT_XOR_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - OrAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (BIT_IOR_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, BIT_IOR_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - AndAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (BIT_AND_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, BIT_AND_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - UshrAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (UNSIGNED_RSHIFT_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, UNSIGNED_RSHIFT_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - ShrAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (RSHIFT_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, RSHIFT_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - ShlAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (LSHIFT_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, LSHIFT_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - ModAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (e1->type->isfloating() ? -- FLOAT_MOD_EXPR : TRUNC_MOD_EXPR, -- type, e1, e2); -+ tree exp = toElemBin (irs, e1->type->isfloating() ? -+ FLOAT_MOD_EXPR : TRUNC_MOD_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - DivAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (e1->type->isintegral() ? -- TRUNC_DIV_EXPR : RDIV_EXPR, -- type, e1, e2); -+ tree exp = toElemBin (irs, e1->type->isintegral() ? -+ TRUNC_DIV_EXPR : RDIV_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - MulAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (MULT_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, MULT_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - PowAssignExp::toElem (IRState *) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - - gcc_unreachable(); - } - - // Determine if type is an array of structs that need a postblit. -+ - static StructDeclaration * - needsPostblit (Type *t) - { -- t = t->toBasetype(); -- while (t->ty == Tsarray) -- t = t->nextOf()->toBasetype(); -+ t = t->baseElemOf(); -+ - if (t->ty == Tstruct) -- { StructDeclaration *sd = ((TypeStruct *) t)->sym; -+ { -+ StructDeclaration *sd = ((TypeStruct *) t)->sym; - if (sd->postblit) - return sd; - } -+ - return NULL; - } - -@@ -760,9 +869,9 @@ CatAssignExp::toElem (IRState *irs) - // Append an array - tree args[3]; - -- args[0] = irs->typeinfoReference (type); -+ args[0] = build_typeinfo (type); - args[1] = build_address (e1->toElem (irs)); -- args[2] = irs->toDArray (e2); -+ args[2] = d_array_convert (e2); - - result = build_libcall (LIBCALL_ARRAYAPPENDT, 3, args, type->toCtype()); - } -@@ -771,12 +880,12 @@ CatAssignExp::toElem (IRState *irs) - // Append an element - tree args[3]; - -- args[0] = irs->typeinfoReference (type); -+ args[0] = build_typeinfo (type); - args[1] = build_address (e1->toElem (irs)); - args[2] = size_one_node; - - result = build_libcall (LIBCALL_ARRAYAPPENDCTX, 3, args, type->toCtype()); -- result = save_expr (result); -+ result = make_temp (result); - - // Assign e2 to last element - tree off_exp = d_array_length (result); -@@ -789,17 +898,8 @@ CatAssignExp::toElem (IRState *irs) - - // Evaluate expression before appending - tree e2e = e2->toElem (irs); -- e2e = save_expr (e2e); -+ e2e = maybe_make_temp (e2e); - result = modify_expr (etype->toCtype(), build_deref (ptr_exp), e2e); -- -- // Maybe call postblit on e2. -- StructDeclaration *sd = needsPostblit (tb2); -- if (sd != NULL) -- { -- Expressions args; -- tree callexp = irs->call (sd->postblit, build_address (e2e), &args); -- result = compound_expr (callexp, result); -- } - result = compound_expr (e2e, result); - } - } -@@ -811,18 +911,20 @@ elem * - MinAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (MINUS_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, MINUS_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * - AddAssignExp::toElem (IRState *irs) - { - if (unhandled_arrayop_p (this)) -- return error_mark (type); -+ return error_mark_node; - -- return irs->buildAssignOp (PLUS_EXPR, type, e1, e2); -+ tree exp = toElemBin (irs, PLUS_EXPR); -+ return convert_expr (exp, e1->type, type); - } - - elem * -@@ -840,7 +942,7 @@ AssignExp::toElem (IRState *irs) - tree args[3]; - LibCall libcall; - -- args[0] = irs->typeinfoReference (ale->e1->type); -+ args[0] = build_typeinfo (ale->e1->type); - args[1] = convert_expr (e2->toElem (irs), e2->type, Type::tsize_t); - args[2] = build_address (ale->e1->toElem (irs)); - libcall = etype->isZeroInit() ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT; -@@ -852,7 +954,30 @@ AssignExp::toElem (IRState *irs) - // Look for array[] = n; - if (e1->op == TOKslice) - { -- Type *etype = e1->type->toBasetype()->nextOf()->toBasetype(); -+ SliceExp *se = (SliceExp *) e1; -+ Type *stype = se->e1->type->toBasetype(); -+ Type *tb2 = e2->type->toBasetype(); -+ Type *etype = stype->nextOf()->toBasetype(); -+ -+ // Optimize static array assignment with array literal. -+ // Front-end writes these as an assignment of a dynamic -+ // array literal with a slice. -+ if (se->lwr == NULL && stype->ty == Tsarray -+ && e2->op == TOKarrayliteral -+ && tb2->nextOf()->mutableOf()->implicitConvTo(stype->nextOf())) -+ { -+ Expression *e1 = se->e1; -+ Type *t2save = e2->type; -+ -+ // Treat [e2] as a static array literal. -+ e2->type = stype; -+ tree t1 = e1->toElem (irs); -+ tree t2 = convert_for_assignment (e2->toElem (irs), e2->type, e1->type); -+ tree result = modify_expr (e1->type->toCtype(), t1, t2); -+ e2->type = t2save; -+ -+ return convert_expr (result, e1->type, type); -+ } - - // Determine if we need to do postblit. - int postblit = 0; -@@ -863,7 +988,7 @@ AssignExp::toElem (IRState *irs) - || (e2->op == TOKcast && ((UnaExp *) e2)->e1->isLvalue()))) - postblit = 1; - -- if (d_types_compatible (etype, e2->type->toBasetype())) -+ if (d_types_compatible (etype, tb2)) - { - // Set a range of elements to one value. - tree t1 = maybe_make_temp (e1->toElem (irs)); -@@ -879,7 +1004,7 @@ AssignExp::toElem (IRState *irs) - args[0] = d_array_ptr (t1); - args[1] = aoe.set (e2->toElem (irs)); - args[2] = d_array_length (t1); -- args[3] = irs->typeinfoReference (etype); -+ args[3] = build_typeinfo (etype); - libcall = (op == TOKconstruct) ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN; - - tree call = build_libcall (libcall, 4, args); -@@ -887,8 +1012,7 @@ AssignExp::toElem (IRState *irs) - } - } - -- tree set_exp = irs->arraySetExpr (d_array_ptr (t1), -- e2->toElem (irs), d_array_length (t1)); -+ tree set_exp = irs->doArraySet (d_array_ptr (t1), e2->toElem (irs), d_array_length (t1)); - return compound_expr (set_exp, t1); - } - -@@ -898,9 +1022,9 @@ AssignExp::toElem (IRState *irs) - tree args[3]; - LibCall libcall; - -- args[0] = irs->typeinfoReference (etype); -- args[1] = irs->toDArray (e1); -- args[2] = irs->toDArray (e2); -+ args[0] = build_typeinfo (etype); -+ args[1] = d_array_convert (e1); -+ args[2] = d_array_convert (e2); - libcall = (op == TOKconstruct) ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN; - - return build_libcall (libcall, 3, args, type->toCtype()); -@@ -911,15 +1035,15 @@ AssignExp::toElem (IRState *irs) - tree args[3]; - - args[0] = build_integer_cst (etype->size(), Type::tsize_t->toCtype()); -- args[1] = irs->toDArray (e2); -- args[2] = irs->toDArray (e1); -+ args[1] = d_array_convert (e2); -+ args[2] = d_array_convert (e1); - - return build_libcall (LIBCALL_ARRAYCOPY, 3, args, type->toCtype()); - } - else - { -- tree t1 = maybe_make_temp (irs->toDArray (e1)); -- tree t2 = irs->toDArray (e2); -+ tree t1 = maybe_make_temp (d_array_convert (e1)); -+ tree t2 = d_array_convert (e2); - tree size = fold_build2 (MULT_EXPR, size_type_node, - d_convert (size_type_node, d_array_length (t1)), - size_int (etype->size())); -@@ -960,7 +1084,7 @@ AssignExp::toElem (IRState *irs) - if (sd->isNested()) - { - tree vthis_field = sd->vthis->toSymbol()->Stree; -- tree vthis_value = irs->getVThis (sd, this); -+ tree vthis_value = build_vthis (sd, irs->func, this); - - tree vthis_exp = modify_expr (component_ref (lhs, vthis_field), vthis_value); - result = compound_expr (result, vthis_exp); -@@ -1004,7 +1128,7 @@ IndexExp::toElem (IRState *irs) - - if (tb1->ty == Taarray) - { -- Type *key_type = ((TypeAArray *) tb1)->index->toBasetype(); -+ Type *tkey = ((TypeAArray *) tb1)->index->toBasetype(); - AddrOfExpr aoe; - tree args[4]; - LibCall libcall; -@@ -1021,15 +1145,15 @@ IndexExp::toElem (IRState *irs) - args[0] = e1->toElem (irs); - } - -- args[1] = irs->typeinfoReference (key_type); -+ args[1] = build_typeinfo (tkey); - args[2] = build_integer_cst (tb1->nextOf()->size(), Type::tsize_t->toCtype()); -- args[3] = aoe.set (convert_expr (e2->toElem (irs), e2->type, key_type)); -+ args[3] = aoe.set (convert_expr (e2->toElem (irs), e2->type, tkey)); - - index = aoe.finish (build_libcall (libcall, 4, args, type->pointerTo()->toCtype())); - -- if (array_bounds_check()) -+ if (array_bounds_check() && !skipboundscheck) - { -- index = save_expr (index); -+ index = make_temp (index); - index = build3 (COND_EXPR, TREE_TYPE (index), d_truthvalue_conversion (index), - index, d_assert_call (loc, LIBCALL_ARRAY_BOUNDS)); - } -@@ -1038,11 +1162,69 @@ IndexExp::toElem (IRState *irs) - } - else - { -- /* arrayElemRef will call aryscp.finish. This result -- of this function may be used as an lvalue and we -- do not want it to be a BIND_EXPR. */ -- ArrayScope aryscp (lengthVar, loc); -- return irs->arrayElemRef (this, &aryscp); -+ // Build an array index expression. ArrayScope may build a BIND_EXPR -+ // if temporaries were created for bounds checking. -+ ArrayScope arrscope (lengthVar, loc); -+ -+ // The expression that holds the array data. -+ tree t1 = e1->toElem (irs); -+ // The expression that indexes the array data. -+ tree t2 = e2->toElem (irs); -+ // The base pointer to the elements. -+ tree ptrexp; -+ -+ switch (tb1->ty) -+ { -+ case Tarray: -+ case Tsarray: -+ t1 = arrscope.setArrayExp (t1, e1->type); -+ -+ // If it's a static array and the index is constant, -+ // the front end has already checked the bounds. -+ if (array_bounds_check() && !(tb1->ty == Tsarray && e2->isConst())) -+ { -+ // Implement bounds check as a conditional expression: -+ // array [inbounds(index) ? index : { throw ArrayBoundsError}] -+ tree length; -+ -+ // First, set up the index expression to only be evaluated once. -+ tree index = maybe_make_temp (t2); -+ -+ if (tb1->ty == Tarray) -+ { -+ t1 = maybe_make_temp (t1); -+ length = d_array_length (t1); -+ } -+ else -+ length = ((TypeSArray *) tb1)->dim->toElem (irs); -+ -+ t2 = d_checked_index (loc, index, length, false); -+ } -+ -+ if (tb1->ty == Tarray) -+ ptrexp = d_array_ptr (t1); -+ else -+ ptrexp = build_address (t1); -+ -+ // This conversion is required for static arrays and is -+ // just-to-be-safe for dynamic arrays. -+ ptrexp = convert (tb1->nextOf()->pointerTo()->toCtype(), ptrexp); -+ break; -+ -+ case Tpointer: -+ // Ignores ArrayScope. -+ ptrexp = t1; -+ break; -+ -+ default: -+ gcc_unreachable(); -+ } -+ -+ ptrexp = void_okay_p (ptrexp); -+ t2 = arrscope.finish (t2); -+ -+ return indirect_ref (TREE_TYPE (TREE_TYPE (ptrexp)), -+ build_array_index (ptrexp, t2)); - } - } - -@@ -1065,24 +1247,24 @@ ArrayLengthExp::toElem (IRState *irs) - { - // Tsarray case seems to be handled by front-end - error ("unexpected type for array length: %s", type->toChars()); -- return error_mark (type); -+ return error_mark_node; - } - } - - elem * - SliceExp::toElem (IRState *irs) - { -- // This function assumes that the front end casts the result to a dynamic array. -- gcc_assert (type->toBasetype()->ty == Tarray); -+ Type *tb = type->toBasetype(); -+ gcc_assert (tb->ty == Tarray || tb->ty == Tsarray); - - // Use convert-to-dynamic-array code if possible - if (e1->type->toBasetype()->ty == Tsarray && !upr && !lwr) - return convert_expr (e1->toElem (irs), e1->type, type); - -- Type *orig_array_type = e1->type->toBasetype(); -+ Type *tb1 = e1->type->toBasetype(); - - tree orig_array_expr, orig_pointer_expr; -- tree final_len_expr, final_ptr_expr; -+ tree len_expr, ptr_expr; - tree array_len_expr = NULL_TREE; - tree lwr_tree = NULL_TREE; - tree upr_tree = NULL_TREE; -@@ -1094,18 +1276,18 @@ SliceExp::toElem (IRState *irs) - // specs don't say bounds if are checked for error or clipped to current size - - // Get the data pointer for static and dynamic arrays -- orig_pointer_expr = convert_expr (orig_array_expr, orig_array_type, -- orig_array_type->nextOf()->pointerTo()); -+ orig_pointer_expr = convert_expr (orig_array_expr, tb1, -+ tb1->nextOf()->pointerTo()); - -- final_ptr_expr = orig_pointer_expr; -+ ptr_expr = orig_pointer_expr; - -- // orig_array_expr is already a save_expr if necessary, so -- // we don't make array_len_expr a save_expr which is, at most, -+ // orig_array_expr is already a SAVE_EXPR if necessary, so -+ // we don't make array_len_expr a SAVE_EXPR which is, at most, - // a COMPONENT_REF on top of orig_array_expr. -- if (orig_array_type->ty == Tarray) -+ if (tb1->ty == Tarray) - array_len_expr = d_array_length (orig_array_expr); -- else if (orig_array_type->ty == Tsarray) -- array_len_expr = ((TypeSArray *) orig_array_type)->dim->toElem (irs); -+ else if (tb1->ty == Tsarray) -+ array_len_expr = ((TypeSArray *) tb1)->dim->toElem (irs); - - if (lwr) - { -@@ -1115,8 +1297,8 @@ SliceExp::toElem (IRState *irs) - { - lwr_tree = maybe_make_temp (lwr_tree); - // Adjust .ptr offset -- final_ptr_expr = build_array_index (void_okay_p (final_ptr_expr), lwr_tree); -- final_ptr_expr = build_nop (TREE_TYPE (orig_pointer_expr), final_ptr_expr); -+ ptr_expr = build_array_index (void_okay_p (ptr_expr), lwr_tree); -+ ptr_expr = build_nop (TREE_TYPE (orig_pointer_expr), ptr_expr); - } - else - lwr_tree = NULL_TREE; -@@ -1132,58 +1314,66 @@ SliceExp::toElem (IRState *irs) - // %% && ! is zero - if (array_len_expr) - { -- final_len_expr = d_checked_index (loc, upr_tree, array_len_expr, true); -+ len_expr = d_checked_index (loc, upr_tree, array_len_expr, true); - } - else - { - // Still need to check bounds lwr <= upr for pointers. -- gcc_assert (orig_array_type->ty == Tpointer); -- final_len_expr = upr_tree; -+ gcc_assert (tb1->ty == Tpointer); -+ len_expr = upr_tree; - } - if (lwr_tree) - { - // Enforces lwr <= upr. No need to check lwr <= length as - // we've already ensured that upr <= length. - tree lwr_bounds_check = d_checked_index (loc, lwr_tree, upr_tree, true); -- final_len_expr = compound_expr (lwr_bounds_check, final_len_expr); -+ len_expr = compound_expr (lwr_bounds_check, len_expr); - } - } - else - { -- final_len_expr = upr_tree; -+ len_expr = upr_tree; - } - - if (lwr_tree) - { - // %% Need to ensure lwr always gets evaluated first, as it may be a function call. - // Does (-lwr + upr) rather than (upr - lwr) -- final_len_expr = build2 (PLUS_EXPR, TREE_TYPE (final_len_expr), -- build1 (NEGATE_EXPR, TREE_TYPE (lwr_tree), lwr_tree), -- final_len_expr); -+ len_expr = build2 (PLUS_EXPR, TREE_TYPE (len_expr), -+ build1 (NEGATE_EXPR, TREE_TYPE (lwr_tree), lwr_tree), len_expr); - } - } - else - { - // If this is the case, than there is no lower bound specified and - // there is no need to subtract. -- switch (orig_array_type->ty) -+ switch (tb1->ty) - { - case Tarray: -- final_len_expr = d_array_length (orig_array_expr); -+ len_expr = d_array_length (orig_array_expr); - break; - - case Tsarray: -- final_len_expr = ((TypeSArray *) orig_array_type)->dim->toElem (irs); -+ len_expr = ((TypeSArray *) tb1)->dim->toElem (irs); - break; - - default: -- ::error ("Attempt to take length of something that was not an array"); -- return error_mark (type); -+ error ("Attempt to take length of something that was not an array"); -+ return error_mark_node; - } - } - -- tree result = d_array_value (type->toCtype(), final_len_expr, final_ptr_expr); -- return aryscp.finish (result); -+ tree exp; -+ -+ if (tb->ty == Tarray) -+ exp = d_array_value (type->toCtype(), len_expr, ptr_expr); -+ else -+ { -+ gcc_assert (lwr && tb->ty == Tsarray); -+ exp = indirect_ref (type->toCtype(), ptr_expr); -+ } -+ -+ return aryscp.finish (exp); - } - - elem * -@@ -1193,11 +1383,9 @@ CastExp::toElem (IRState *irs) - Type *tbtype = to->toBasetype(); - tree t = e1->toElem (irs); - -+ // Just evaluate e1 if it has any side effects - if (tbtype->ty == Tvoid) -- { -- // Just evaluate e1 if it has any side effects -- return build1 (NOP_EXPR, tbtype->toCtype(), t); -- } -+ return build1 (NOP_EXPR, tbtype->toCtype(), t); - - return convert_expr (t, ebtype, tbtype); - } -@@ -1231,15 +1419,13 @@ DeleteExp::toElem (IRState *irs) - else if (tb1->ty == Tarray) - { - // Might need to run destructor on array contents -- Type *next_type = tb1->nextOf()->toBasetype(); -+ Type *telem = tb1->nextOf()->baseElemOf(); - tree ti = d_null_pointer; - tree args[2]; - -- while (next_type->ty == Tsarray) -- next_type = next_type->nextOf()->toBasetype(); -- if (next_type->ty == Tstruct) -+ if (telem->ty == Tstruct) - { -- TypeStruct *ts = (TypeStruct *) next_type; -+ TypeStruct *ts = (TypeStruct *) telem; - if (ts->sym->dtor) - ti = tb1->nextOf()->getTypeInfo (NULL)->toElem (irs); - } -@@ -1258,7 +1444,7 @@ DeleteExp::toElem (IRState *irs) - else - { - error ("don't know how to delete %s", e1->toChars()); -- return error_mark (type); -+ return error_mark_node; - } - } - -@@ -1271,20 +1457,20 @@ RemoveExp::toElem (IRState *irs) - if (array->type->toBasetype()->ty == Taarray) - { - Type *a_type = array->type->toBasetype(); -- Type *key_type = ((TypeAArray *) a_type)->index->toBasetype(); -+ Type *tkey = ((TypeAArray *) a_type)->index->toBasetype(); - AddrOfExpr aoe; - tree args[3]; - - args[0] = array->toElem (irs); -- args[1] = irs->typeinfoReference (key_type); -- args[2] = aoe.set (convert_expr (index->toElem (irs), index->type, key_type)); -+ args[1] = build_typeinfo (tkey); -+ args[2] = aoe.set (convert_expr (index->toElem (irs), index->type, tkey)); - - return aoe.finish (build_libcall (LIBCALL_AADELX, 3, args)); - } - else - { - error ("%s is not an associative array", array->toChars()); -- return error_mark (type); -+ return error_mark_node; - } - } - -@@ -1326,7 +1512,7 @@ NegExp::toElem (IRState *irs) - if (ty1 == Tarray || ty1 == Tsarray) - { - error ("Array operation %s not implemented", toChars()); -- return error_mark (type); -+ return error_mark_node; - } - - return build1 (NEGATE_EXPR, type->toCtype(), e1->toElem (irs)); -@@ -1360,7 +1546,7 @@ PtrExp::toElem (IRState *irs) - if (!decl_reference_p (sym_exp->var)) - { - rec_type = sym_exp->var->type->toBasetype(); -- rec_tree = irs->var (sym_exp->var); -+ rec_tree = get_decl_tree (sym_exp->var, irs->func); - the_offset = sym_exp->offset; - } - } -@@ -1374,8 +1560,10 @@ PtrExp::toElem (IRState *irs) - if (field->offset == the_offset - && d_types_same (field->type, this->type)) - { -- if (error_mark_p (rec_tree)) -- return rec_tree; // backend will ICE otherwise -+ // Catch errors, backend will ICE otherwise. -+ if (error_operand_p (rec_tree)) -+ return rec_tree; -+ - return component_ref (rec_tree, field->toSymbol()->Stree); - } - else if (field->offset > the_offset) -@@ -1389,25 +1577,104 @@ PtrExp::toElem (IRState *irs) - elem * - AddrExp::toElem (IRState *irs) - { -- tree addrexp = build_address (e1->toElem (irs)); -- return build_nop (type->toCtype(), addrexp); -+ tree exp; -+ -+ if (e1->op == TOKstructliteral) -+ { -+ StructLiteralExp *sle = ((StructLiteralExp *) e1)->origin; -+ exp = build_address (sle->toElem (irs)); -+ } -+ else -+ exp = build_address (e1->toElem (irs)); -+ -+ return build_nop (type->toCtype(), exp); - } - - elem * - CallExp::toElem (IRState *irs) - { -- tree call_exp = irs->call (e1, arguments); -+ Type *tb = e1->type->toBasetype(); -+ Expression *e1b = e1; -+ tree object = NULL_TREE; -+ -+ // Calls to delegates can sometimes look like this: -+ if (e1b->op == TOKcomma) -+ { -+ e1b = ((CommaExp *) e1b)->e2; -+ gcc_assert (e1b->op == TOKvar); -+ -+ Declaration *var = ((VarExp *) e1b)->var; -+ gcc_assert (var->isFuncDeclaration() && !var->needThis()); -+ } -+ -+ tree callee = e1b->toElem (irs); -+ TypeFunction *tf = NULL; -+ -+ if (D_METHOD_CALL_EXPR (callee)) -+ { -+ // This could be a delegate expression (TY == Tdelegate), but not -+ // actually a delegate variable. -+ if (e1b->op == TOKdotvar) -+ { -+ // This gets the true function type, getting the function type from -+ // e1->type can sometimes be incorrect, eg: ref return functions. -+ tf = get_function_type (((DotVarExp *) e1b)->var->type); -+ } -+ else -+ tf = get_function_type (tb); -+ -+ extract_from_method_call (callee, callee, object); -+ } -+ else if (tb->ty == Tdelegate) -+ { -+ // Delegate call, extract .object and .funcptr from var. -+ callee = maybe_make_temp (callee); -+ tf = get_function_type (tb); -+ object = delegate_object (callee); -+ callee = delegate_method (callee); -+ } -+ else if (e1b->op == TOKvar) -+ { -+ FuncDeclaration *fd = ((VarExp *) e1b)->var->isFuncDeclaration(); -+ gcc_assert (fd); -+ tf = get_function_type (fd->type); -+ -+ if (fd->isNested()) -+ { -+ // Maybe re-evaluate symbol storage treating 'fd' as public. -+ if (call_by_alias_p (irs->func, fd)) -+ setup_symbol_storage (fd, callee, true); -+ -+ object = get_frame_for_symbol (irs->func, fd); -+ } -+ else if (fd->needThis()) -+ { -+ e1b->error ("need 'this' to access member %s", fd->toChars()); -+ // Continue processing... -+ object = d_null_pointer; -+ } -+ } -+ else -+ { -+ // Normal direct function call. -+ tf = get_function_type (tb); -+ } -+ -+ gcc_assert (tf != NULL); -+ -+ // Now we have the type, callee and maybe object reference, -+ // build the call expression. -+ tree exp = d_build_call (tf, callee, object, arguments); - -- TypeFunction *tf = get_function_type (e1->type->toBasetype()); - if (tf->isref) -- call_exp = build_deref (call_exp); -+ exp = build_deref (exp); - - // Some library calls are defined to return a generic type. -- // this->type is the real type. (See crash2.d) -+ // this->type is the real type we want to return. - if (type->isTypeBasic()) -- call_exp = d_convert (type->toCtype(), call_exp); -+ exp = d_convert (type->toCtype(), exp); - -- return call_exp; -+ return exp; - } - - /******************************************* -@@ -1417,9 +1684,9 @@ CallExp::toElem (IRState *irs) - elem * - Expression::toElemDtor (IRState *irs) - { -- size_t starti = irs->varsInScope ? irs->varsInScope->dim : 0; -- tree t = toElem (irs); -- size_t endi = irs->varsInScope ? irs->varsInScope->dim : 0; -+ size_t starti = irs->varsInScope.length(); -+ tree exp = toElem (irs); -+ size_t endi = irs->varsInScope.length(); - - // Codegen can be improved by determining if no exceptions can be thrown - // between the ctor and dtor, and eliminating the ctor and dtor. -@@ -1429,10 +1696,10 @@ Expression::toElemDtor (IRState *irs) - tree tdtors = NULL_TREE; - for (size_t i = starti; i != endi; ++i) - { -- VarDeclaration *vd = irs->varsInScope->tdata()[i]; -+ VarDeclaration *vd = irs->varsInScope[i]; - if (vd) - { -- irs->varsInScope->tdata()[i] = NULL; -+ irs->varsInScope[i] = NULL; - tree td = vd->edtor->toElem (irs); - // Execute in reverse order. - tdtors = maybe_compound_expr (tdtors, td); -@@ -1441,11 +1708,35 @@ Expression::toElemDtor (IRState *irs) - - if (tdtors != NULL_TREE) - { -- t = save_expr (t); -- t = compound_expr (compound_expr (t, tdtors), t); -+ if (op == TOKcall) -+ { -+ // Wrap expression and dtors in a try/finally expression. -+ tree body = exp; -+ -+ if (type->ty == Tvoid) -+ exp = build2 (TRY_FINALLY_EXPR, void_type_node, body, tdtors); -+ else -+ { -+ body = maybe_make_temp (body); -+ tree tfexp = build2 (TRY_FINALLY_EXPR, void_type_node, body, tdtors); -+ exp = compound_expr (tfexp, body); -+ } -+ } -+ else if (op == TOKcomma && ((CommaExp *) this)->e2->op == TOKvar) -+ { -+ // Split comma expressions, so as don't require a save_expr. -+ tree lexp = TREE_OPERAND (exp, 0); -+ tree rvalue = TREE_OPERAND (exp, 1); -+ exp = compound_expr (compound_expr (lexp, tdtors), rvalue); -+ } -+ else -+ { -+ exp = maybe_make_temp (exp); -+ exp = compound_expr (compound_expr (exp, tdtors), exp); -+ } - } - -- return t; -+ return exp; - } - - -@@ -1453,8 +1744,7 @@ elem * - DotTypeExp::toElem (IRState *irs) - { - // Just a pass through to e1. -- tree t = e1->toElem (irs); -- return t; -+ return e1->toElem (irs); - } - - // The result will probably just be converted to a CONSTRUCTOR for a Tdelegate struct -@@ -1479,7 +1769,7 @@ DelegateExp::toElem (IRState *irs) - if (!func->isThis()) - { - error ("delegates are only for non-static functions"); -- return error_mark (type); -+ return error_mark_node; - } - - return get_object_method (e1->toElem (irs), e1, func, type); -@@ -1492,7 +1782,7 @@ DelegateExp::toElem (IRState *irs) - if (e1->op == TOKnull) - this_tree = e1->toElem (irs); - else -- this_tree = irs->getFrameForSymbol (func); -+ this_tree = get_frame_for_symbol (irs->func, func); - } - else - { -@@ -1536,8 +1826,8 @@ DotVarExp::toElem (IRState *irs) - } - else if (var_decl) - { -- if (!(var_decl->storage_class & STCfield)) -- return irs->var (var_decl); -+ if (!var_decl->isField()) -+ return get_decl_tree (var_decl, irs->func); - else - { - tree this_tree = e1->toElem (irs); -@@ -1553,38 +1843,51 @@ DotVarExp::toElem (IRState *irs) - default: - break; - } -- ::error ("Don't know how to handle %s", toChars()); -- return error_mark (type); -+ -+ error ("Don't know how to handle %s", toChars()); -+ return error_mark_node; - } - - elem * - AssertExp::toElem (IRState *irs) - { -- // %% todo: Do we call a Tstruct's invariant if -- // e1 is a pointer to the struct? - if (global.params.useAssert) - { - Type *tb1 = e1->type->toBasetype(); -- TY ty = tb1->ty; -- tree assert_call; -+ tree tmsg = NULL_TREE; -+ LibCall libcall; - -+ // Build _d_assert call. - if (irs->func->isUnitTestDeclaration()) - { -- assert_call = (msg != NULL) -- ? d_assert_call (loc, LIBCALL_UNITTEST_MSG, msg->toElem (irs)) -- : d_assert_call (loc, LIBCALL_UNITTEST, NULL_TREE); -+ if (msg) -+ { -+ tmsg = msg->toElemDtor (irs); -+ libcall = LIBCALL_UNITTEST_MSG; -+ } -+ else -+ libcall = LIBCALL_UNITTEST; - } - else - { -- assert_call = (msg != NULL) -- ? d_assert_call (loc, LIBCALL_ASSERT_MSG, msg->toElem (irs)) -- : d_assert_call (loc, LIBCALL_ASSERT, NULL_TREE); -+ if (msg) -+ { -+ tmsg = msg->toElemDtor (irs); -+ libcall = LIBCALL_ASSERT_MSG; -+ } -+ else -+ libcall = LIBCALL_ASSERT; - } - -- if (ty == Tclass) -+ tree assert_call = d_assert_call (loc, libcall, tmsg); -+ -+ // Build condition that we are asserting in this contract. -+ if (tb1->ty == Tclass) - { - ClassDeclaration *cd = tb1->isClassHandle(); - tree arg = e1->toElem (irs); -+ tree invc = NULL_TREE; -+ - if (cd->isCOMclass()) - { - return build3 (COND_EXPR, void_type_node, -@@ -1592,13 +1895,15 @@ AssertExp::toElem (IRState *irs) - d_void_zero_node, assert_call); - } - else if (cd->isInterfaceDeclaration()) -- { -- arg = convert_expr (arg, tb1, build_object_type()); -- } -- // this does a null pointer check before calling _d_invariant -+ arg = convert_expr (arg, tb1, build_object_type()); -+ -+ if (global.params.useInvariants && !cd->isCPPclass()) -+ invc = build_libcall (LIBCALL_INVARIANT, 1, &arg); -+ -+ // This does a null pointer check before calling _d_invariant - return build3 (COND_EXPR, void_type_node, - build_boolop (NE_EXPR, arg, d_null_pointer), -- build_libcall (LIBCALL_INVARIANT, 1, &arg), assert_call); -+ invc ? invc : d_void_zero_node, assert_call); - } - else - { -@@ -1608,18 +1913,15 @@ AssertExp::toElem (IRState *irs) - tree invc = NULL_TREE; - tree e1_t = e1->toElem (irs); - -- if (ty == Tpointer) -+ if (global.params.useInvariants -+ && tb1->ty == Tpointer && tb1->nextOf()->ty == Tstruct) - { -- Type *sub_type = tb1->nextOf()->toBasetype(); -- if (sub_type->ty == Tstruct) -+ FuncDeclaration *inv = ((TypeStruct *) tb1->nextOf())->sym->inv; -+ if (inv != NULL) - { -- AggregateDeclaration *agg_decl = ((TypeStruct *) sub_type)->sym; -- if (agg_decl->inv) -- { -- Expressions args; -- e1_t = maybe_make_temp (e1_t); -- invc = irs->call (agg_decl->inv, e1_t, &args); -- } -+ Expressions args; -+ e1_t = maybe_make_temp (e1_t); -+ invc = d_build_call (inv, e1_t, &args); - } - } - result = build3 (COND_EXPR, void_type_node, -@@ -1636,6 +1938,7 @@ elem * - DeclarationExp::toElem (IRState *irs) - { - VarDeclaration *vd = declaration->isVarDeclaration(); -+ - if (vd != NULL) - { - if (!vd->isStatic() && !(vd->storage_class & STCmanifest) -@@ -1643,16 +1946,10 @@ DeclarationExp::toElem (IRState *irs) - { - // Put variable on list of things needing destruction - if (vd->edtor && !vd->noscope) -- { -- if (!irs->varsInScope) -- irs->varsInScope = new VarDeclarations(); -- irs->varsInScope->push (vd); -- } -+ irs->varsInScope.safe_push (vd); - } - } - -- // VarDeclaration::toObjFile was modified to call d_gcc_emit_local_variable -- // if needed. This assumes irs == cirstate - irs->pushStatementList(); - declaration->toObjFile (0); - tree t = irs->popStatementList(); -@@ -1670,37 +1967,27 @@ DeclarationExp::toElem (IRState *irs) - elem * - FuncExp::toElem (IRState *irs) - { -- Type *func_type = type->toBasetype(); -+ Type *ftype = type->toBasetype(); - -- if (func_type->ty == Tpointer) -+ // This check is for lambda's, remove 'vthis' as function isn't nested. -+ if (fd->tok == TOKreserved && ftype->ty == Tpointer) - { -- // This check is for lambda's, remove 'vthis' as function isn't nested. -- if (fd->tok == TOKreserved && fd->vthis) -- { -- fd->tok = TOKfunction; -- fd->vthis = NULL; -- } -- -- func_type = func_type->nextOf()->toBasetype(); -+ fd->tok = TOKfunction; -+ fd->vthis = NULL; - } - - // Emit after current function body has finished. -- irs->func->deferred.push (fd); -+ if (irs->func) -+ irs->func->deferred.push (fd); - - // If nested, this will be a trampoline... -- switch (func_type->ty) -+ if (fd->isNested()) - { -- case Tfunction: -- return build_nop (type->toCtype(), build_address (fd->toSymbol()->Stree)); -- -- case Tdelegate: - return build_method_call (build_address (fd->toSymbol()->Stree), -- irs->getFrameForSymbol (fd), type); -- -- default: -- ::error ("Unexpected FuncExp type"); -- return error_mark (type); -+ get_frame_for_symbol (irs->func, fd), type); - } -+ -+ return build_nop (type->toCtype(), build_address (fd->toSymbol()->Stree)); - } - - elem * -@@ -1720,14 +2007,14 @@ SymbolExp::toElem (IRState *irs) - if (var->needThis()) - { - error ("need 'this' to access member %s", var->ident->string); -- return error_mark (type); -+ return error_mark_node; - } - - // __ctfe is always false at runtime - if (var->ident == Id::ctfe) - return integer_zero_node; - -- exp = irs->var (var); -+ exp = get_decl_tree (var, irs->func); - TREE_USED (exp) = 1; - - // For variables that are references (currently only out/inout arguments; -@@ -1741,7 +2028,7 @@ SymbolExp::toElem (IRState *irs) - { - size_t offset = ((SymOffExp *) this)->offset; - -- exp = irs->var (var); -+ exp = get_decl_tree (var, irs->func); - TREE_USED (exp) = 1; - - if (decl_reference_p (var)) -@@ -1786,15 +2073,15 @@ NewExp::toElem (IRState *irs) - // Call allocator (custom allocator or _d_newclass). - if (onstack) - { -- tree stack_var = build_local_var (rec_type); -- irs->expandDecl (stack_var); -+ tree stack_var = build_local_temp (rec_type); -+ expand_decl (stack_var); - new_call = build_address (stack_var); - setup_exp = modify_expr (indirect_ref (rec_type, new_call), - class_decl->toInitializer()->Stree); - } - else if (allocator) - { -- new_call = irs->call (allocator, newargs); -+ new_call = d_build_call (allocator, NULL_TREE, newargs); - new_call = maybe_make_temp (new_call); - // copy memory... - setup_exp = modify_expr (indirect_ref (rec_type, new_call), -@@ -1829,7 +2116,7 @@ NewExp::toElem (IRState *irs) - } - else - { -- vthis_value = irs->getVThis (class_decl, this); -+ vthis_value = build_vthis (class_decl, irs->func, this); - } - - if (vthis_value) -@@ -1843,55 +2130,57 @@ NewExp::toElem (IRState *irs) - - // Call constructor. - if (member) -- result = irs->call (member, new_call, arguments); -+ result = d_build_call (member, new_call, arguments); - else - result = new_call; - } - // New'ing a struct. - else if (tb->ty == Tpointer && tb->nextOf()->toBasetype()->ty == Tstruct) - { -+ Type *htype = newtype->toBasetype(); -+ gcc_assert (htype->ty == Tstruct); - gcc_assert (!onstack); - -- Type * handle_type = newtype->toBasetype(); -- gcc_assert (handle_type->ty == Tstruct); -- TypeStruct *struct_type = (TypeStruct *) handle_type; -- StructDeclaration *sd = struct_type->sym; -- Expression *init = struct_type->defaultInit (loc); -- -+ TypeStruct *stype = (TypeStruct *) htype; -+ StructDeclaration *sd = stype->sym; -+ Expression *init = stype->defaultInit (loc); - tree new_call; -- tree setup_exp; -- tree init_exp; -+ -+ // Struct size is unknown. -+ if (sd->size (loc) == 0) -+ return d_convert (type->toCtype(), integer_zero_node); - - if (allocator) -- new_call = irs->call (allocator, newargs); -+ new_call = d_build_call (allocator, NULL_TREE, newargs); - else - { -- libcall = struct_type->isZeroInit (loc) ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; -+ libcall = stype->isZeroInit (loc) ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - tree arg = type->getTypeInfo(NULL)->toElem (irs); - new_call = build_libcall (libcall, 1, &arg); - } - new_call = build_nop (tb->toCtype(), new_call); - - // Save the result allocation call. -- init_exp = convert_for_assignment (init->toElem (irs), init->type, struct_type); -+ tree init_exp = convert_for_assignment (init->toElem (irs), init->type, stype); - new_call = maybe_make_temp (new_call); -- setup_exp = modify_expr (build_deref (new_call), init_exp); -+ -+ tree setup_exp = modify_expr (build_deref (new_call), init_exp); - new_call = compound_expr (setup_exp, new_call); - - // Set vthis for nested structs/classes. - if (sd->isNested()) - { -- tree vthis_value = irs->getVThis (sd, this); -+ tree vthis_value = build_vthis (sd, irs->func, this); - tree vthis_field; - new_call = maybe_make_temp (new_call); -- vthis_field = component_ref (indirect_ref (struct_type->toCtype(), new_call), -+ vthis_field = component_ref (indirect_ref (stype->toCtype(), new_call), - sd->vthis->toSymbol()->Stree); - new_call = compound_expr (modify_expr (vthis_field, vthis_value), new_call); - } - - // Call constructor. - if (member) -- result = irs->call (member, new_call, arguments); -+ result = d_build_call (member, new_call, arguments); - else - result = new_call; - } -@@ -1908,8 +2197,13 @@ NewExp::toElem (IRState *irs) - { - // Single dimension array allocations. - Expression *arg = (*arguments)[0]; -- libcall = tarray->next->isZeroInit() ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT; - tree args[2]; -+ -+ // Elem size is unknown. -+ if (tarray->next->size() == 0) -+ return d_array_value (type->toCtype(), size_int (0), d_null_pointer); -+ -+ libcall = tarray->next->isZeroInit() ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT; - args[0] = type->getTypeInfo(NULL)->toElem (irs); - args[1] = arg->toElem (irs); - result = build_libcall (libcall, 2, args, tb->toCtype()); -@@ -1933,6 +2227,7 @@ NewExp::toElem (IRState *irs) - telem = telem->toBasetype()->nextOf(); - gcc_assert (telem); - } -+ - CONSTRUCTOR_ELTS (dims_init) = elms; - DECL_INITIAL (dims_var) = dims_init; - -@@ -1947,9 +2242,14 @@ NewExp::toElem (IRState *irs) - // New'ing a pointer - else if (tb->ty == Tpointer) - { -- TypePointer *pointer_type = (TypePointer *) tb; -+ TypePointer *tpointer = (TypePointer *) tb; -+ -+ // Elem size is unknown. -+ if (tpointer->next->size() == 0) -+ return d_convert (type->toCtype(), integer_zero_node); -+ -+ libcall = tpointer->next->isZeroInit (loc) ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - -- libcall = pointer_type->next->isZeroInit (loc) ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - tree arg = type->getTypeInfo(NULL)->toElem (irs); - result = build_libcall (libcall, 1, &arg, tb->toCtype()); - } -@@ -1962,15 +2262,15 @@ NewExp::toElem (IRState *irs) - elem * - ScopeExp::toElem (IRState *) - { -- ::error ("%s is not an expression", toChars()); -- return error_mark (type); -+ error ("%s is not an expression", toChars()); -+ return error_mark_node; - } - - elem * - TypeExp::toElem (IRState *) - { -- ::error ("type %s is not an expression", toChars()); -- return error_mark (type); -+ error ("type %s is not an expression", toChars()); -+ return error_mark_node; - } - - elem * -@@ -2043,7 +2343,7 @@ StringExp::toElem (IRState *) - - default: - error ("Invalid type for string constant: %s", type->toChars()); -- return error_mark (type); -+ return error_mark_node; - } - - return value; -@@ -2052,45 +2352,76 @@ StringExp::toElem (IRState *) - elem * - TupleExp::toElem (IRState *irs) - { -- tree result = NULL_TREE; -- if (exps && exps->dim) -+ tree exp = NULL_TREE; -+ -+ if (e0) -+ exp = e0->toElem (irs); -+ -+ for (size_t i = 0; i < exps->dim; ++i) - { -- for (size_t i = 0; i < exps->dim; ++i) -- { -- Expression *e = (*exps)[i]; -- result = maybe_vcompound_expr (result, e->toElem (irs)); -- } -+ Expression *e = (*exps)[i]; -+ exp = maybe_vcompound_expr (exp, e->toElem (irs)); - } -- else -- result = d_void_zero_node; - -- return result; -+ if (exp == NULL_TREE) -+ exp = d_void_zero_node; -+ -+ return exp; - } - - elem * - ArrayLiteralExp::toElem (IRState *irs) - { -- Type *typeb = type->toBasetype(); -- gcc_assert (typeb->ty == Tarray || typeb->ty == Tsarray || typeb->ty == Tpointer); -- Type *etype = typeb->nextOf(); -- tree sa_type = d_array_type (etype, elements->dim); -+ Type *tb = type->toBasetype(); -+ gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer); -+ -+ // Convert void[n] to ubyte[n] -+ if (tb->ty == Tsarray && tb->nextOf()->toBasetype()->ty == Tvoid) -+ tb = TypeSArray::makeType(loc, Type::tuns8, ((TypeSArray *)tb)->dim->toUInteger()); -+ -+ Type *etype = tb->nextOf(); -+ tree tsa = d_array_type (etype, elements->dim); - tree result = NULL_TREE; -+ bool constant_p = tb->isImmutable(); -+ -+ // Handle empty array literals. -+ if (elements->dim == 0) -+ { -+ if (tb->ty == Tarray) -+ return d_array_value (type->toCtype(), size_int (0), d_null_pointer); -+ else -+ return build_constructor (tsa, NULL); -+ } - -- /* Build an expression that assigns the expressions in ELEMENTS to a constructor. */ -+ // Build an expression that assigns the expressions in ELEMENTS to a constructor. - vec *elms = NULL; - vec_safe_reserve (elms, elements->dim); - - for (size_t i = 0; i < elements->dim; i++) - { - Expression *e = (*elements)[i]; -+ tree elem = e->toElem (irs); -+ -+ elem = maybe_make_temp (elem); - CONSTRUCTOR_APPEND_ELT (elms, build_integer_cst (i, size_type_node), -- convert_expr (e->toElem (irs), e->type, etype)); -+ convert_expr (elem, e->type, etype)); -+ -+ if (constant_p && !e->isConst()) -+ constant_p = false; - } - -- tree ctor = build_constructor (sa_type, elms); -+ tree ctor = build_constructor (tsa, elms); - tree args[2]; - -- args[0] = irs->typeinfoReference (etype->arrayOf()); -+ // Nothing else to do for static arrays. -+ if (tb->ty == Tsarray) -+ return d_convert (type->toCtype(), ctor); -+ -+ // Don't allocate immutable arrays on the heap. -+ if (tb->ty == Tarray && constant_p) -+ return d_array_value (type->toCtype(), size_int (elements->dim), build_address (ctor)); -+ -+ args[0] = build_typeinfo (etype->arrayOf()); - args[1] = build_integer_cst (elements->dim, size_type_node); - - // Call _d_arrayliteralTX (ti, dim); -@@ -2099,7 +2430,7 @@ ArrayLiteralExp::toElem (IRState *irs) - - // memcpy (mem, &ctor, size) - tree size = fold_build2 (MULT_EXPR, size_type_node, -- size_int (elements->dim), size_int (typeb->nextOf()->size())); -+ size_int (elements->dim), size_int (tb->nextOf()->size())); - - result = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMCPY), 3, - mem, build_address (ctor), size); -@@ -2107,10 +2438,8 @@ ArrayLiteralExp::toElem (IRState *irs) - // Returns array pointed to by MEM. - result = maybe_compound_expr (result, mem); - -- if (typeb->ty == Tarray) -+ if (tb->ty == Tarray) - result = d_array_value (type->toCtype(), size_int (elements->dim), result); -- else if (typeb->ty == Tsarray) -- result = indirect_ref (sa_type, result); - - return result; - } -@@ -2171,7 +2500,7 @@ AssocArrayLiteralExp::toElem (IRState *i - - tree args[3]; - -- args[0] = irs->typeinfoReference (aa_type); -+ args[0] = build_typeinfo (aa_type); - args[1] = d_array_value (index->arrayOf()->toCtype(), size_int (keys->dim), keys_ptr); - args[2] = d_array_value (next->arrayOf()->toCtype(), size_int (keys->dim), vals_ptr); - result = maybe_compound_expr (result, build_libcall (LIBCALL_ASSOCARRAYLITERALTX, 3, args)); -@@ -2196,100 +2525,69 @@ StructLiteralExp::toElem (IRState *irs) - if (sinit && sinit->Stree) - return sinit->Stree; - -- if (elements) -- { -- size_t dim = elements->dim; -- gcc_assert (dim <= sd->fields.dim - sd->isnested); -+ // CTFE may fill the hidden pointer by NullExp. -+ size_t dim = elements ? elements->dim : 0; -+ gcc_assert (dim <= sd->fields.dim); - -- for (size_t i = 0; i < dim; i++) -- { -- if (!(*elements)[i]) -- continue; -+ for (size_t i = 0; i < dim; i++) -+ { -+ if (!(*elements)[i]) -+ continue; - -- Expression *exp = (*elements)[i]; -- Type *exp_type = exp->type->toBasetype(); -- tree exp_tree = NULL_TREE; -- tree call_exp = NULL_TREE; -+ Expression *exp = (*elements)[i]; -+ Type *exp_type = exp->type->toBasetype(); -+ tree exp_tree = NULL_TREE; - -- VarDeclaration *fld = sd->fields[i]; -- Type *fld_type = fld->type->toBasetype(); -+ VarDeclaration *fld = sd->fields[i]; -+ Type *fld_type = fld->type->toBasetype(); - -- if (fld_type->ty == Tsarray) -+ if (fld_type->ty == Tsarray) -+ { -+ if (d_types_compatible (exp_type, fld_type)) - { -- if (d_types_compatible (exp_type, fld_type)) -- { -- StructDeclaration *sd = needsPostblit (fld_type); -- if (sd != NULL) -- { -- // Generate _d_arrayctor (ti, from = exp, to = exp_tree) -- Type *ti = fld_type->nextOf(); -- tree args[3]; -- -- exp_tree = build_local_var (exp_type->toCtype()); -- args[0] = irs->typeinfoReference (ti); -- args[1] = irs->toDArray (exp); -- args[2] = convert_expr (exp_tree, exp_type, ti->arrayOf()); -- call_exp = build_libcall (LIBCALL_ARRAYCTOR, 3, args); -- } -- else -- { -- // %% This would call _d_newarrayT ... use memcpy? -- exp_tree = convert_expr (exp->toElem (irs), exp->type, fld->type); -- } -- } -- else -- { -- // %% Could use memset if is zero init... -- exp_tree = build_local_var (fld_type->toCtype()); -- Type *etype = fld_type; -- -- while (etype->ty == Tsarray) -- etype = etype->nextOf(); -- -- gcc_assert (fld_type->size() % etype->size() == 0); -- tree size = fold_build2 (TRUNC_DIV_EXPR, size_type_node, -- size_int (fld_type->size()), size_int (etype->size())); -- -- tree ptr_tree = build_nop (etype->pointerTo()->toCtype(), -- build_address (exp_tree)); -- tree set_exp = irs->arraySetExpr (ptr_tree, exp->toElem (irs), size); -- exp_tree = compound_expr (set_exp, exp_tree); -- } -+ // %% This would call _d_newarrayT ... use memcpy? -+ exp_tree = convert_expr (exp->toElem (irs), exp->type, fld->type); - } - else - { -- exp_tree = convert_expr (exp->toElem (irs), exp->type, fld->type); -- StructDeclaration *sd = needsPostblit (fld_type); -- if (sd && exp->isLvalue()) -- { -- // Call __postblit (&exp_tree) -- Expressions args; -- call_exp = irs->call (sd->postblit, build_address (exp_tree), &args); -- } -+ // %% Could use memset if is zero init... -+ exp_tree = build_local_temp (fld_type->toCtype()); -+ Type *etype = fld_type; -+ -+ while (etype->ty == Tsarray) -+ etype = etype->nextOf(); -+ -+ gcc_assert (fld_type->size() % etype->size() == 0); -+ tree size = fold_build2 (TRUNC_DIV_EXPR, size_type_node, -+ size_int (fld_type->size()), size_int (etype->size())); -+ -+ tree ptr_tree = build_nop (etype->pointerTo()->toCtype(), -+ build_address (exp_tree)); -+ tree set_exp = irs->doArraySet (ptr_tree, exp->toElem (irs), size); -+ exp_tree = compound_expr (set_exp, exp_tree); - } -+ } -+ else -+ exp_tree = convert_expr (exp->toElem (irs), exp->type, fld->type); - -- if (call_exp) -- irs->addExp (call_exp); -- -- CONSTRUCTOR_APPEND_ELT (ce, fld->toSymbol()->Stree, exp_tree); -+ CONSTRUCTOR_APPEND_ELT (ce, fld->toSymbol()->Stree, exp_tree); - -- // Unions only have one field that gets assigned. -- if (sd->isUnionDeclaration()) -- break; -- } -+ // Unions only have one field that gets assigned. -+ if (sd->isUnionDeclaration()) -+ break; - } - -- if (sd->isNested()) -+ if (sd->isNested() && dim != sd->fields.dim) - { - // Maybe setup hidden pointer to outer scope context. - tree vthis_field = sd->vthis->toSymbol()->Stree; -- tree vthis_value = irs->getVThis (sd, this); -+ tree vthis_value = build_vthis (sd, irs->func, this); - CONSTRUCTOR_APPEND_ELT (ce, vthis_field, vthis_value); - gcc_assert (sinit == NULL); - } - - tree ctor = build_constructor (type->toCtype(), ce); -- tree var = build_local_var (TREE_TYPE (ctor)); -+ tree var = build_local_temp (TREE_TYPE (ctor)); - tree init = NULL_TREE; - - if (fillHoles) -@@ -2347,16 +2645,17 @@ elem * - ThisExp::toElem (IRState *irs) - { - tree this_tree = NULL_TREE; -+ FuncDeclaration *fd = irs->func; - - if (var) - { - gcc_assert(var->isVarDeclaration()); -- this_tree = irs->var (var); -+ this_tree = get_decl_tree (var, fd); - } - else - { -- gcc_assert (irs->func && irs->func->vthis); -- this_tree = irs->var (irs->func->vthis); -+ gcc_assert (fd && fd->vthis); -+ this_tree = get_decl_tree (fd->vthis, fd); - } - - if (type->ty == Tstruct) -@@ -2404,3 +2703,13 @@ VectorExp::toElem (IRState *irs) - } - } - -+elem * -+ClassReferenceExp::toElem (IRState *) -+{ -+ // ClassReferenceExp builds the RECORD_TYPE, -+ // we want to return a reference to it. -+ tree exp = toSymbol()->Stree; -+ -+ return build_address (exp); -+} -+ ---- a/src/gcc/d/dfrontend/aav.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/aav.c 2014-04-01 16:32:51.000000000 +0100 -@@ -14,20 +14,17 @@ - - #include - #include -+#include - #include - - #include "aav.h" - --static const size_t prime_list[] = { -- 31UL, -- 97UL, 389UL, -- 1543UL, 6151UL, -- 24593UL, 98317UL, -- 393241UL, 1572869UL, -- 6291469UL, 25165843UL, -- 100663319UL, 402653189UL, -- 1610612741UL, 4294967291UL, --}; -+ -+inline size_t hash(size_t a) -+{ -+ a ^= (a >> 20) ^ (a >> 12); -+ return a ^ (a >> 7) ^ (a >> 4); -+} - - struct aaA - { -@@ -42,9 +39,9 @@ struct AA - size_t b_length; - size_t nodes; // total number of aaA nodes - aaA* binit[4]; // initial value of b[] --}; - --static const AA bbinit = { NULL, }; -+ aaA aafirst; // a lot of these AA's have only one entry -+}; - - /**************************************************** - * Determine number of entries in associative array. -@@ -67,16 +64,20 @@ Value* _aaGet(AA** paa, Key key) - - if (!*paa) - { AA *a = new AA(); -- *a = bbinit; - a->b = a->binit; - a->b_length = sizeof(a->binit) / sizeof(a->binit[0]); -+ a->nodes = 0; -+ a->binit[0] = NULL; -+ a->binit[1] = NULL; -+ a->binit[2] = NULL; -+ a->binit[3] = NULL; - *paa = a; - assert((*paa)->b_length == 4); - } - //printf("paa = %p, *paa = %p\n", paa, *paa); - - assert((*paa)->b_length); -- size_t i = (size_t)key % (*paa)->b_length; -+ size_t i = hash((size_t)key) & ((*paa)->b_length - 1); - aaA** pe = &(*paa)->b[i]; - aaA *e; - while ((e = *pe) != NULL) -@@ -88,15 +89,17 @@ Value* _aaGet(AA** paa, Key key) - - // Not found, create new elem - //printf("create new one\n"); -- e = new aaA(); -+ -+ size_t nodes = ++(*paa)->nodes; -+ e = (nodes != 1) ? new aaA() : &(*paa)->aafirst; -+ //e = new aaA(); - e->next = NULL; - e->key = key; - e->value = NULL; - *pe = e; - -- size_t nodes = ++(*paa)->nodes; -- //printf("length = %d, nodes = %d\n", paa.a.b.length, nodes); -- if (nodes > (*paa)->b_length * 4) -+ //printf("length = %d, nodes = %d\n", (*paa)->b_length, nodes); -+ if (nodes > (*paa)->b_length * 2) - { - //printf("rehash\n"); - _aaRehash(paa); -@@ -114,14 +117,11 @@ Value* _aaGet(AA** paa, Key key) - Value _aaGetRvalue(AA* aa, Key key) - { - //printf("_aaGetRvalue(key = %p)\n", key); -- if (!aa) -- return NULL; -- -- size_t len = aa->b_length; -- -- if (len) -+ if (aa) - { -- size_t i = (size_t)key % len; -+ size_t i; -+ size_t len = aa->b_length; -+ i = hash((size_t)key) & (len-1); - aaA* e = aa->b[i]; - while (e) - { -@@ -143,39 +143,33 @@ void _aaRehash(AA** paa) - //printf("Rehash\n"); - if (*paa) - { -- AA newb = bbinit; - AA *aa = *paa; -- size_t len = _aaLen(*paa); -- if (len) -- { size_t i; -- -- for (i = 0; i < sizeof(prime_list)/sizeof(prime_list[0]) - 1; i++) -- { -- if (len <= prime_list[i]) -- break; -- } -- len = prime_list[i]; -- newb.b = new aaA*[len]; -- memset(newb.b, 0, len * sizeof(aaA*)); -- newb.b_length = len; -+ if (aa) -+ { -+ size_t len = aa->b_length; -+ if (len == 4) -+ len = 32; -+ else -+ len *= 4; -+ aaA** newb = new aaA*[len]; -+ memset(newb, 0, len * sizeof(aaA*)); - - for (size_t k = 0; k < aa->b_length; k++) - { aaA *e = aa->b[k]; - while (e) - { aaA* enext = e->next; -- size_t j = (size_t)e->key % len; -- e->next = newb.b[j]; -- newb.b[j] = e; -+ size_t j = hash((size_t)e->key) & (len-1); -+ e->next = newb[j]; -+ newb[j] = e; - e = enext; - } - } - if (aa->b != aa->binit) - delete[] aa->b; - -- newb.nodes = aa->nodes; -+ aa->b = newb; -+ aa->b_length = len; - } -- -- **paa = newb; - } - } - ---- a/src/gcc/d/dfrontend/access.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/access.c 2014-04-01 16:32:51.000000000 +0100 -@@ -38,14 +38,14 @@ int hasPackageAccess(Scope *sc, Dsymbol - * Return PROT access for Dsymbol smember in this declaration. - */ - --enum PROT AggregateDeclaration::getAccess(Dsymbol *smember) -+PROT AggregateDeclaration::getAccess(Dsymbol *smember) - { - return PROTpublic; - } - --enum PROT StructDeclaration::getAccess(Dsymbol *smember) -+PROT StructDeclaration::getAccess(Dsymbol *smember) - { -- enum PROT access_ret = PROTnone; -+ PROT access_ret = PROTnone; - - #if LOG - printf("+StructDeclaration::getAccess(this = '%s', smember = '%s')\n", -@@ -62,9 +62,9 @@ enum PROT StructDeclaration::getAccess(D - return access_ret; - } - --enum PROT ClassDeclaration::getAccess(Dsymbol *smember) -+PROT ClassDeclaration::getAccess(Dsymbol *smember) - { -- enum PROT access_ret = PROTnone; -+ PROT access_ret = PROTnone; - - #if LOG - printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n", -@@ -84,7 +84,7 @@ enum PROT ClassDeclaration::getAccess(Ds - for (size_t i = 0; i < baseclasses->dim; i++) - { BaseClass *b = (*baseclasses)[i]; - -- enum PROT access = b->base->getAccess(smember); -+ PROT access = b->base->getAccess(smember); - switch (access) - { - case PROTnone: -@@ -152,7 +152,7 @@ static int accessCheckX( - { - for (size_t i = 0; i < cdthis->baseclasses->dim; i++) - { BaseClass *b = (*cdthis->baseclasses)[i]; -- enum PROT access = b->base->getAccess(smember); -+ PROT access = b->base->getAccess(smember); - if (access >= PROTprotected || - accessCheckX(smember, sfunc, b->base, cdscope) - ) -@@ -192,7 +192,7 @@ void AggregateDeclaration::accessCheck(L - - FuncDeclaration *f = sc->func; - AggregateDeclaration *cdscope = sc->getStructClassScope(); -- enum PROT access; -+ PROT access; - - #if LOG - printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n", -@@ -214,7 +214,7 @@ void AggregateDeclaration::accessCheck(L - //assert(smember->parent->isBaseOf(this, NULL)); - - if (smemberparent == this) -- { enum PROT access2 = smember->prot(); -+ { PROT access2 = smember->prot(); - - result = access2 >= PROTpublic || - hasPrivateAccess(f) || -@@ -290,25 +290,60 @@ int hasPackageAccess(Scope *sc, Dsymbol - printf("hasPackageAccess(s = '%s', sc = '%p')\n", s->toChars(), sc); - #endif - -+ Package *pkg = NULL; - for (; s; s = s->parent) - { -- if (s->isPackage() && !s->isModule()) -+ if (Module *m = s->isModule()) -+ { -+ DsymbolTable *dst = Package::resolve(m->md ? m->md->packages : NULL, NULL, NULL); -+ assert(dst); -+ Dsymbol *s2 = dst->lookup(m->ident); -+ assert(s2); -+ Package *p = s2->isPackage(); -+ if (p && p->isPkgMod == PKGmodule) -+ { -+ assert(p->mod == m); -+ pkg = p; -+ break; -+ } -+ } -+ else if ((pkg = s->isPackage()) != NULL) - break; - } - #if LOG -- if (s) -- printf("\tthis is in package '%s'\n", s->toChars()); -+ if (pkg) -+ printf("\tthis is in package '%s'\n", pkg->toChars()); - #endif - -- if (s && s == sc->module->parent) -+ if (pkg) - { -+ if (pkg == sc->module->parent) -+ { - #if LOG -- printf("\ts is in same package as sc\n"); -+ printf("\ts is in same package as sc\n"); - #endif -- return 1; -+ return 1; -+ } -+ if (pkg->isPkgMod == PKGmodule && pkg->mod == sc->module) -+ { -+#if LOG -+ printf("\ts is in same package.d module as sc\n"); -+#endif -+ return 1; -+ } -+ s = sc->module->parent; -+ for (; s; s = s->parent) -+ { -+ if (s == pkg) -+ { -+#if LOG -+ printf("\ts is in ancestor package of sc\n"); -+#endif -+ return 1; -+ } -+ } - } - -- - #if LOG - printf("\tno package access\n"); - #endif -@@ -375,6 +410,9 @@ int AggregateDeclaration::hasPrivateAcce - - void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d) - { -+ if (sc->flags & SCOPEnoaccesscheck) -+ return; -+ - #if LOG - if (e) - { printf("accessCheck(%s . %s)\n", e->toChars(), d->toChars()); -@@ -395,7 +433,8 @@ void accessCheck(Loc loc, Scope *sc, Exp - } - } - else if (e->type->ty == Tclass) -- { // Do access check -+ { -+ // Do access check - ClassDeclaration *cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym); - if (e->op == TOKsuper) - { -@@ -406,7 +445,8 @@ void accessCheck(Loc loc, Scope *sc, Exp - cd->accessCheck(loc, sc, d); - } - else if (e->type->ty == Tstruct) -- { // Do access check -+ { -+ // Do access check - StructDeclaration *cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym); - cd->accessCheck(loc, sc, d); - } ---- a/src/gcc/d/dfrontend/aggregate.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/aggregate.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -18,21 +18,21 @@ - #include "root.h" - - #include "dsymbol.h" -+#include "declaration.h" - --struct Identifier; --struct Type; --struct TypeFunction; --struct Expression; --struct FuncDeclaration; --struct CtorDeclaration; --struct DtorDeclaration; --struct InvariantDeclaration; --struct NewDeclaration; --struct DeleteDeclaration; --struct InterfaceDeclaration; --struct TypeInfoClassDeclaration; --struct VarDeclaration; -- -+class Identifier; -+class Type; -+class TypeFunction; -+class Expression; -+class FuncDeclaration; -+class CtorDeclaration; -+class DtorDeclaration; -+class InvariantDeclaration; -+class NewDeclaration; -+class DeleteDeclaration; -+class InterfaceDeclaration; -+class TypeInfoClassDeclaration; -+class VarDeclaration; - #ifdef IN_GCC - typedef union tree_node dt_t; - #else -@@ -46,33 +46,41 @@ enum Sizeok - SIZEOKfwd, // error in computing size of aggregate - }; - --struct AggregateDeclaration : ScopeDsymbol -+class AggregateDeclaration : public ScopeDsymbol - { -+public: - Type *type; - StorageClass storage_class; -- enum PROT protection; -+ PROT protection; - Type *handle; // 'this' type - unsigned structsize; // size of struct - unsigned alignsize; // size of struct for alignment purposes - int hasUnions; // set if aggregate has overlapping fields - VarDeclarations fields; // VarDeclaration fields -- enum Sizeok sizeok; // set when structsize contains valid data -+ Sizeok sizeok; // set when structsize contains valid data - Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol - bool isdeprecated; // !=0 if deprecated - - #if DMDV2 -- bool isnested; // !=0 if is nested -+ Dsymbol *enclosing; /* !=NULL if is nested -+ * pointing to the dsymbol that directly enclosing it. -+ * 1. The function that enclosing it (nested struct and class) -+ * 2. The class that enclosing it (nested class only) -+ * 3. If enclosing aggregate is template, its enclosing dsymbol. -+ * See AggregateDeclaraton::makeNested for the details. -+ */ - VarDeclaration *vthis; // 'this' parameter if this aggregate is nested - #endif - // Special member functions -- InvariantDeclaration *inv; // invariant -+ FuncDeclarations invs; // Array of invariants -+ FuncDeclaration *inv; // invariant - NewDeclaration *aggNew; // allocator - DeleteDeclaration *aggDelete; // deallocator - - #if DMDV2 -- //CtorDeclaration *ctor; - Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration -- CtorDeclaration *defaultCtor; // default constructor -+ CtorDeclaration *defaultCtor; // default constructor - should have no arguments, because -+ // it would be stored in TypeInfo_Class.defaultConstructor - Dsymbol *aliasthis; // forward unresolved lookups to aliasthis - bool noDefaultCtor; // no default construction - #endif -@@ -95,18 +103,22 @@ struct AggregateDeclaration : ScopeDsymb - Type *getType(); - int firstFieldInUnion(int indx); // first field in union that includes indx - int numFieldsInUnion(int firstIndex); // #fields in union starting at index -- int isDeprecated(); // is aggregate deprecated? -+ bool isDeprecated(); // is aggregate deprecated? - FuncDeclaration *buildDtor(Scope *sc); -- int isNested(); -- int isExport(); -+ FuncDeclaration *buildInv(Scope *sc); -+ bool isNested(); -+ void makeNested(); -+ bool isExport(); -+ void searchCtor(); - - void emitComment(Scope *sc); - void toJson(JsonOut *json); - void toDocBuffer(OutBuffer *buf, Scope *sc); - -- FuncDeclaration *hasIdentityOpAssign(Scope *sc, Dsymbol *assign); -+ FuncDeclaration *hasIdentityOpAssign(Scope *sc); -+ FuncDeclaration *hasIdentityOpEquals(Scope *sc); - -- char *mangle(bool isv = false); -+ const char *mangle(bool isv = false); - - // For access checking - virtual PROT getAccess(Dsymbol *smember); // determine access to smember -@@ -114,7 +126,7 @@ struct AggregateDeclaration : ScopeDsymb - int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class? - void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); - -- enum PROT prot(); -+ PROT prot(); - - // Back end - Symbol *stag; // tag symbol for debug data -@@ -124,8 +136,18 @@ struct AggregateDeclaration : ScopeDsymb - AggregateDeclaration *isAggregateDeclaration() { return this; } - }; - --struct StructDeclaration : AggregateDeclaration -+struct StructFlags -+{ -+ typedef unsigned Type; -+ enum Enum -+ { -+ hasPointers = 0x1, // NB: should use noPointers as in ClassFlags -+ }; -+}; -+ -+class StructDeclaration : public AggregateDeclaration - { -+public: - int zeroInit; // !=0 if initialize with 0 fill - #if DMDV2 - int hasIdentityAssign; // !=0 if has identity opAssign -@@ -135,7 +157,9 @@ struct StructDeclaration : AggregateDecl - FuncDeclaration *postblit; // aggregate postblit - - FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals -+ FuncDeclaration *xcmp; // TypeInfo_Struct.xopCmp - static FuncDeclaration *xerreq; // object.xopEquals -+ static FuncDeclaration *xerrcmp; // object.xopCmp - - structalign_t alignment; // alignment applied outside of the struct - #endif -@@ -149,7 +173,7 @@ struct StructDeclaration : AggregateDecl - void semantic(Scope *sc); - Dsymbol *search(Loc, Identifier *ident, int flags); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- char *mangle(bool isv = false); -+ const char *mangle(bool isv = false); - const char *kind(); - void finalizeSize(Scope *sc); - bool isPOD(); -@@ -160,12 +184,11 @@ struct StructDeclaration : AggregateDecl - int needOpAssign(); - int needOpEquals(); - FuncDeclaration *buildOpAssign(Scope *sc); -- FuncDeclaration *buildOpEquals(Scope *sc); - FuncDeclaration *buildPostBlit(Scope *sc); - FuncDeclaration *buildCpCtor(Scope *sc); -- -+ FuncDeclaration *buildOpEquals(Scope *sc); - FuncDeclaration *buildXopEquals(Scope *sc); -- void makeNested(); -+ FuncDeclaration *buildXopCmp(Scope *sc); - #endif - void toDocBuffer(OutBuffer *buf, Scope *sc); - -@@ -178,8 +201,9 @@ struct StructDeclaration : AggregateDecl - StructDeclaration *isStructDeclaration() { return this; } - }; - --struct UnionDeclaration : StructDeclaration -+class UnionDeclaration : public StructDeclaration - { -+public: - UnionDeclaration(Loc loc, Identifier *id); - Dsymbol *syntaxCopy(Dsymbol *s); - const char *kind(); -@@ -190,10 +214,10 @@ struct UnionDeclaration : StructDeclarat - struct BaseClass - { - Type *type; // (before semantic processing) -- enum PROT protection; // protection for the base interface -+ PROT protection; // protection for the base interface - - ClassDeclaration *base; -- int offset; // 'this' pointer offset -+ unsigned offset; // 'this' pointer offset - FuncDeclarations vtbl; // for interfaces: Array of FuncDeclaration's - // making up the vtbl[] - -@@ -202,7 +226,7 @@ struct BaseClass - // are a copy of the InterfaceDeclaration::interfaces - - BaseClass(); -- BaseClass(Type *type, enum PROT protection); -+ BaseClass(Type *type, PROT protection); - - int fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance); - void copyBaseInterfaces(BaseClasses *); -@@ -211,10 +235,26 @@ struct BaseClass - extern int CLASSINFO_SIZE; // value of ClassInfo.size - extern int CLASSINFO_SIZE_64; // value of ClassInfo.size - --struct ClassDeclaration : AggregateDeclaration -+struct ClassFlags - { -+ typedef unsigned Type; -+ enum Enum -+ { -+ isCOMclass = 0x1, -+ noPointers = 0x2, -+ hasOffTi = 0x4, -+ hasCtor = 0x8, -+ hasGetMembers = 0x10, -+ hasTypeInfo = 0x20, -+ isAbstract = 0x40, -+ isCPPclass = 0x80, -+ }; -+}; -+ -+class ClassDeclaration : public AggregateDeclaration -+{ -+public: - static ClassDeclaration *object; -- static ClassDeclaration *classinfo; - static ClassDeclaration *throwable; - static ClassDeclaration *exception; - static ClassDeclaration *errorException; -@@ -242,15 +282,17 @@ struct ClassDeclaration : AggregateDecla - TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration - int com; // !=0 if this is a COM class (meaning - // it derives from IUnknown) -- int isscope; // !=0 if this is an auto class -- int isabstract; // !=0 if abstract class --#if DMDV1 -- bool isnested; // !=0 if is nested -- VarDeclaration *vthis; // 'this' parameter if this class is nested -+#if DMDV2 -+ int cpp; // !=0 if this is a C++ interface - #endif -+ int isscope; // !=0 if this is an auto class -+ int isabstract; // !=0 if abstract class - int inuse; // to prevent recursive attempts -+ Semantic doAncestorsSemantic; // Before searching symbol, whole ancestors should finish -+ // calling semantic() at least once, due to fill symtab -+ // and do addMember(). [== Semantic(Start,In,Done)] - -- ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); -+ ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, bool inObject = false); - Dsymbol *syntaxCopy(Dsymbol *s); - void semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -267,18 +309,16 @@ struct ClassDeclaration : AggregateDecla - #endif - FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); - void interfaceSemantic(Scope *sc); --#if DMDV1 -- int isNested(); --#endif - int isCOMclass(); - virtual int isCOMinterface(); - #if DMDV2 -+ int isCPPclass(); - virtual int isCPPinterface(); - #endif -- int isAbstract(); -+ bool isAbstract(); - virtual int vtblOffset(); - const char *kind(); -- char *mangle(bool isv = false); -+ const char *mangle(bool isv = false); - void toDocBuffer(OutBuffer *buf, Scope *sc); - - PROT getAccess(Dsymbol *smember); // determine access to smember -@@ -299,11 +339,9 @@ struct ClassDeclaration : AggregateDecla - ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } - }; - --struct InterfaceDeclaration : ClassDeclaration -+class InterfaceDeclaration : public ClassDeclaration - { --#if DMDV2 -- int cpp; // !=0 if this is a C++ interface --#endif -+public: - InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); - Dsymbol *syntaxCopy(Dsymbol *s); - void semantic(Scope *sc); ---- a/src/gcc/d/dfrontend/aliasthis.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/aliasthis.c 2014-04-01 16:32:51.000000000 +0100 -@@ -36,8 +36,22 @@ Expression *resolveAliasThis(Scope *sc, - L1: - if (ad && ad->aliasthis) - { -+ bool isstatic = (e->op == TOKtype); - e = new DotIdExp(e->loc, e, ad->aliasthis->ident); - e = e->semantic(sc); -+ if (isstatic && ad->aliasthis->needThis()) -+ { -+ /* non-@property function is not called inside typeof(), -+ * so resolve it ahead. -+ */ -+ int save = sc->intypeof; -+ sc->intypeof = 1; // bypass "need this" error check -+ e = resolveProperties(sc, e); -+ sc->intypeof = save; -+ -+ e = new TypeExp(e->loc, new TypeTypeof(e->loc, e)); -+ e = e->semantic(sc); -+ } - e = resolveProperties(sc, e); - } - } -@@ -74,7 +88,7 @@ void AliasThis::semantic(Scope *sc) - assert(ad->members); - Dsymbol *s = ad->search(loc, ident, 0); - if (!s) -- { s = sc->search(loc, ident, 0); -+ { s = sc->search(loc, ident, NULL); - if (s) - ::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars()); - else ---- a/src/gcc/d/dfrontend/aliasthis.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/aliasthis.h 2014-04-01 16:32:51.000000000 +0100 -@@ -22,8 +22,9 @@ - - #if DMDV2 - --struct AliasThis : Dsymbol -+class AliasThis : public Dsymbol - { -+public: - // alias Identifier this; - Identifier *ident; - ---- a/src/gcc/d/dfrontend/apply.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/apply.c 2014-04-01 16:32:51.000000000 +0100 -@@ -26,9 +26,7 @@ - * Creating an iterator for this would be much more complex. - */ - --typedef int (*fp_t)(Expression *, void *); -- --int Expression::apply(fp_t fp, void *param) -+int Expression::apply(apply_fp_t fp, void *param) - { - return (*fp)(this, param); - } -@@ -36,14 +34,9 @@ int Expression::apply(fp_t fp, void *par - /****************************** - * Perform apply() on an t if not null - */ --template --int condApply(T* t, fp_t fp, void* param) --{ -- return t ? t->apply(fp, param) : 0; --} -+#define condApply(t, fp, param) (t ? t->apply(fp, param) : 0) - -- --int NewExp::apply(int (*fp)(Expression *, void *), void *param) -+int NewExp::apply(apply_fp_t fp, void *param) - { - //printf("NewExp::apply(): %s\n", toChars()); - -@@ -53,7 +46,7 @@ int NewExp::apply(int (*fp)(Expression * - (*fp)(this, param); - } - --int NewAnonClassExp::apply(int (*fp)(Expression *, void *), void *param) -+int NewAnonClassExp::apply(apply_fp_t fp, void *param) - { - //printf("NewAnonClassExp::apply(): %s\n", toChars()); - -@@ -63,47 +56,47 @@ int NewAnonClassExp::apply(int (*fp)(Exp - (*fp)(this, param); - } - --int UnaExp::apply(fp_t fp, void *param) -+int UnaExp::apply(apply_fp_t fp, void *param) - { - return e1->apply(fp, param) || - (*fp)(this, param); - } - --int BinExp::apply(fp_t fp, void *param) -+int BinExp::apply(apply_fp_t fp, void *param) - { - return e1->apply(fp, param) || - e2->apply(fp, param) || - (*fp)(this, param); - } - --int AssertExp::apply(fp_t fp, void *param) -+int AssertExp::apply(apply_fp_t fp, void *param) - { -- //printf("CallExp::apply(fp_t fp, void *param): %s\n", toChars()); -+ //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); - return e1->apply(fp, param) || - condApply(msg, fp, param) || - (*fp)(this, param); - } - - --int CallExp::apply(fp_t fp, void *param) -+int CallExp::apply(apply_fp_t fp, void *param) - { -- //printf("CallExp::apply(fp_t fp, void *param): %s\n", toChars()); -+ //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); - return e1->apply(fp, param) || - condApply(arguments, fp, param) || - (*fp)(this, param); - } - - --int ArrayExp::apply(fp_t fp, void *param) -+int ArrayExp::apply(apply_fp_t fp, void *param) - { -- //printf("ArrayExp::apply(fp_t fp, void *param): %s\n", toChars()); -+ //printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); - return e1->apply(fp, param) || - condApply(arguments, fp, param) || - (*fp)(this, param); - } - - --int SliceExp::apply(fp_t fp, void *param) -+int SliceExp::apply(apply_fp_t fp, void *param) - { - return e1->apply(fp, param) || - condApply(lwr, fp, param) || -@@ -112,14 +105,14 @@ int SliceExp::apply(fp_t fp, void *param - } - - --int ArrayLiteralExp::apply(fp_t fp, void *param) -+int ArrayLiteralExp::apply(apply_fp_t fp, void *param) - { - return condApply(elements, fp, param) || - (*fp)(this, param); - } - - --int AssocArrayLiteralExp::apply(fp_t fp, void *param) -+int AssocArrayLiteralExp::apply(apply_fp_t fp, void *param) - { - return condApply(keys, fp, param) || - condApply(values, fp, param) || -@@ -127,21 +120,27 @@ int AssocArrayLiteralExp::apply(fp_t fp, - } - - --int StructLiteralExp::apply(fp_t fp, void *param) -+int StructLiteralExp::apply(apply_fp_t fp, void *param) - { -- return condApply(elements, fp, param) || -+ if(stageflags & stageApply) return 0; -+ int old = stageflags; -+ stageflags |= stageApply; -+ int ret = condApply(elements, fp, param) || - (*fp)(this, param); -+ stageflags = old; -+ return ret; - } - - --int TupleExp::apply(fp_t fp, void *param) -+int TupleExp::apply(apply_fp_t fp, void *param) - { -- return condApply(exps, fp, param) || -+ return (e0 ? (*fp)(e0, param) : 0) || -+ condApply(exps, fp, param) || - (*fp)(this, param); - } - - --int CondExp::apply(fp_t fp, void *param) -+int CondExp::apply(apply_fp_t fp, void *param) - { - return econd->apply(fp, param) || - e1->apply(fp, param) || ---- a/src/gcc/d/dfrontend/argtypes.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/argtypes.c 2014-04-01 16:32:51.000000000 +0100 -@@ -26,9 +26,6 @@ - #include "aggregate.h" - #include "hdrgen.h" - --#define tfloat2 tfloat64 --//#define tfloat2 tcomplex32 -- - /**************************************************** - * This breaks a type down into 'simpler' types that can be passed to a function - * in registers, and returned in registers. -@@ -84,7 +81,7 @@ TypeTuple *TypeBasic::toArgTypes() - - case Tcomplex32: - if (global.params.is64bit) -- t1 = Type::tfloat2; -+ t1 = Type::tfloat64; - else - { - t1 = Type::tfloat64; -@@ -157,14 +154,6 @@ TypeTuple *TypeSArray::toArgTypes() - #endif - } - --TypeTuple *TypeDArray::toArgTypes() --{ -- /* Should be done as if it were: -- * struct S { size_t length; void* ptr; } -- */ -- return new TypeTuple(Type::tsize_t, Type::tvoidptr); --} -- - TypeTuple *TypeAArray::toArgTypes() - { - return new TypeTuple(Type::tvoidptr); -@@ -175,14 +164,6 @@ TypeTuple *TypePointer::toArgTypes() - return new TypeTuple(Type::tvoidptr); - } - --TypeTuple *TypeDelegate::toArgTypes() --{ -- /* Should be done as if it were: -- * struct S { void* ptr; void* funcptr; } -- */ -- return new TypeTuple(Type::tvoidptr, Type::tvoidptr); --} -- - /************************************* - * Convert a floating point type into the equivalent integral type. - */ -@@ -223,8 +204,8 @@ Type *argtypemerge(Type *t1, Type *t2, u - if (!t2) - return t1; - -- unsigned sz1 = t1->size(0); -- unsigned sz2 = t2->size(0); -+ unsigned sz1 = t1->size(Loc()); -+ unsigned sz2 = t2->size(Loc()); - - if (t1->ty != t2->ty && - (t1->ty == Tfloat80 || t2->ty == Tfloat80)) -@@ -232,7 +213,7 @@ Type *argtypemerge(Type *t1, Type *t2, u - - // [float,float] => [cfloat] - if (t1->ty == Tfloat32 && t2->ty == Tfloat32 && offset2 == 4) -- return Type::tfloat2; -+ return Type::tfloat64; - - // Merging floating and non-floating types produces the non-floating type - if (t1->isfloating()) -@@ -276,6 +257,38 @@ Type *argtypemerge(Type *t1, Type *t2, u - return t; - } - -+TypeTuple *TypeDArray::toArgTypes() -+{ -+ /* Should be done as if it were: -+ * struct S { size_t length; void* ptr; } -+ */ -+ if (global.params.is64bit && !global.params.isLP64) -+ { -+ // For AMD64 ILP32 ABI, D arrays fit into a single integer register. -+ unsigned offset = Type::tsize_t->size(Loc()); -+ Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset); -+ if (t) -+ return new TypeTuple(t); -+ } -+ return new TypeTuple(Type::tsize_t, Type::tvoidptr); -+} -+ -+TypeTuple *TypeDelegate::toArgTypes() -+{ -+ /* Should be done as if it were: -+ * struct S { size_t length; void* ptr; } -+ */ -+ if (global.params.is64bit && !global.params.isLP64) -+ { -+ // For AMD64 ILP32 ABI, delegates fit into a single integer register. -+ unsigned offset = Type::tsize_t->size(Loc()); -+ Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset); -+ if (t) -+ return new TypeTuple(t); -+ } -+ return new TypeTuple(Type::tvoidptr, Type::tvoidptr); -+} -+ - TypeTuple *TypeStruct::toArgTypes() - { - //printf("TypeStruct::toArgTypes() %s\n", toChars()); -@@ -287,7 +300,7 @@ TypeTuple *TypeStruct::toArgTypes() - } - Type *t1 = NULL; - Type *t2 = NULL; -- d_uns64 sz = size(0); -+ d_uns64 sz = size(Loc()); - assert(sz < 0xFFFFFFFF); - switch ((unsigned)sz) - { -@@ -312,8 +325,6 @@ TypeTuple *TypeStruct::toArgTypes() - if (global.params.is64bit && sym->fields.dim) - { - #if 1 -- unsigned sz1 = 0; -- unsigned sz2 = 0; - t1 = NULL; - for (size_t i = 0; i < sym->fields.dim; i++) - { VarDeclaration *f = sym->fields[i]; -@@ -349,7 +360,7 @@ TypeTuple *TypeStruct::toArgTypes() - goto Lmemory; - - // Fields that overlap the 8byte boundary goto Lmemory -- unsigned fieldsz = f->type->size(0); -+ unsigned fieldsz = f->type->size(Loc()); - if (f->offset < 8 && (f->offset + fieldsz) > 8) - goto Lmemory; - } ---- a/src/gcc/d/dfrontend/array.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/array.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,222 +0,0 @@ -- --// Copyright (c) 1999-2013 by Digital Mars --// All Rights Reserved --// written by Walter Bright --// http://www.digitalmars.com --// License for redistribution is by either the Artistic License --// in artistic.txt, or the GNU General Public License in gnu.txt. --// See the included readme.txt for details. -- --#include --#include --#include --#include -- --#include "port.h" --#include "root.h" --#include "rmem.h" -- -- --/********************************* Array ****************************/ -- --Array::Array() --{ -- data = SMALLARRAYCAP ? &smallarray[0] : NULL; -- dim = 0; -- allocdim = SMALLARRAYCAP; --} -- --Array::~Array() --{ -- if (data != &smallarray[0]) -- mem.free(data); --} -- --void Array::mark() --{ -- mem.mark(data); -- for (size_t u = 0; u < dim; u++) -- mem.mark(data[u]); // BUG: what if arrays of Object's? --} -- --void Array::reserve(size_t nentries) --{ -- //printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", (int)dim, (int)allocdim, (int)nentries); -- if (allocdim - dim < nentries) -- { -- if (allocdim == 0) -- { // Not properly initialized, someone memset it to zero -- if (nentries <= SMALLARRAYCAP) -- { allocdim = SMALLARRAYCAP; -- data = SMALLARRAYCAP ? &smallarray[0] : NULL; -- } -- else -- { allocdim = nentries; -- data = (void **)mem.malloc(allocdim * sizeof(*data)); -- } -- } -- else if (allocdim == SMALLARRAYCAP) -- { -- allocdim = dim + nentries; -- data = (void **)mem.malloc(allocdim * sizeof(*data)); -- memcpy(data, &smallarray[0], dim * sizeof(*data)); -- } -- else -- { allocdim = dim + nentries; -- data = (void **)mem.realloc(data, allocdim * sizeof(*data)); -- } -- } --} -- --void Array::setDim(size_t newdim) --{ -- if (dim < newdim) -- { -- reserve(newdim - dim); -- } -- dim = newdim; --} -- --void Array::fixDim() --{ -- if (dim != allocdim) -- { -- if (allocdim >= SMALLARRAYCAP) -- { -- if (dim <= SMALLARRAYCAP) -- { -- memcpy(&smallarray[0], data, dim * sizeof(*data)); -- mem.free(data); -- } -- else -- data = (void **)mem.realloc(data, dim * sizeof(*data)); -- } -- allocdim = dim; -- } --} -- --void Array::push(void *ptr) --{ -- reserve(1); -- data[dim++] = ptr; --} -- --void *Array::pop() --{ -- return data[--dim]; --} -- --void Array::shift(void *ptr) --{ -- reserve(1); -- memmove(data + 1, data, dim * sizeof(*data)); -- data[0] = ptr; -- dim++; --} -- --void Array::insert(size_t index, void *ptr) --{ -- reserve(1); -- memmove(data + index + 1, data + index, (dim - index) * sizeof(*data)); -- data[index] = ptr; -- dim++; --} -- -- --void Array::insert(size_t index, Array *a) --{ -- if (a) -- { -- size_t d = a->dim; -- reserve(d); -- if (dim != index) -- memmove(data + index + d, data + index, (dim - index) * sizeof(*data)); -- memcpy(data + index, a->data, d * sizeof(*data)); -- dim += d; -- } --} -- -- --/*********************************** -- * Append array a to this array. -- */ -- --void Array::append(Array *a) --{ -- insert(dim, a); --} -- --void Array::remove(size_t i) --{ -- if (dim - i - 1) -- memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0])); -- dim--; --} -- --char *Array::toChars() --{ -- char **buf = (char **)malloc(dim * sizeof(char *)); -- assert(buf); -- size_t len = 2; -- for (size_t u = 0; u < dim; u++) -- { -- buf[u] = ((Object *)data[u])->toChars(); -- len += strlen(buf[u]) + 1; -- } -- char *str = (char *)mem.malloc(len); -- -- str[0] = '['; -- char *p = str + 1; -- for (size_t u = 0; u < dim; u++) -- { -- if (u) -- *p++ = ','; -- len = strlen(buf[u]); -- memcpy(p,buf[u],len); -- p += len; -- } -- *p++ = ']'; -- *p = 0; -- free(buf); -- return str; --} -- --void Array::zero() --{ -- memset(data,0,dim * sizeof(data[0])); --} -- --void *Array::tos() --{ -- return dim ? data[dim - 1] : NULL; --} -- --int --#if _WIN32 -- __cdecl --#endif -- Array_sort_compare(const void *x, const void *y) --{ -- Object *ox = *(Object **)x; -- Object *oy = *(Object **)y; -- -- return ox->compare(oy); --} -- --void Array::sort() --{ -- if (dim) -- { -- qsort(data, dim, sizeof(Object *), Array_sort_compare); -- } --} -- --Array *Array::copy() --{ -- Array *a = new Array(); -- -- a->setDim(dim); -- memcpy(a->data, data, dim * sizeof(void *)); -- return a; --} -- ---- a/src/gcc/d/dfrontend/array.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/array.h 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,296 @@ -+ -+// Copyright (c) 1999-2011 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#ifndef ARRAY_H -+#define ARRAY_H -+ -+#if __DMC__ -+#pragma once -+#endif -+ -+#include -+#include -+#include -+#include -+ -+#include "object.h" -+#ifdef IN_GCC -+// rmem uses functions poisoned by GCC. -+void *mem_malloc(size_t size); -+void *mem_realloc(void *p, size_t size); -+void mem_free(void *p); -+#else -+#include "rmem.h" -+#endif -+ -+template -+struct Array -+{ -+ size_t dim; -+ TYPE **data; -+ -+ private: -+ size_t allocdim; -+ #define SMALLARRAYCAP 1 -+ TYPE *smallarray[SMALLARRAYCAP]; // inline storage for small arrays -+ -+ public: -+ Array() -+ { -+ data = SMALLARRAYCAP ? &smallarray[0] : NULL; -+ dim = 0; -+ allocdim = SMALLARRAYCAP; -+ } -+ -+ ~Array() -+ { -+ if (data != &smallarray[0]) -+#ifdef IN_GCC -+ mem_free(data); -+#else -+ mem.free(data); -+#endif -+ } -+ -+ char *toChars() -+ { -+#ifdef IN_GCC -+ char **buf = (char **)mem_malloc(dim * sizeof(char *)); -+#else -+ char **buf = (char **)mem.malloc(dim * sizeof(char *)); -+#endif -+ assert(buf); -+ size_t len = 2; -+ for (size_t u = 0; u < dim; u++) -+ { -+ buf[u] = ((RootObject *)data[u])->toChars(); -+ len += strlen(buf[u]) + 1; -+ } -+#ifdef IN_GCC -+ char *str = (char *)mem_malloc(len); -+#else -+ char *str = (char *)mem.malloc(len); -+#endif -+ -+ str[0] = '['; -+ char *p = str + 1; -+ for (size_t u = 0; u < dim; u++) -+ { -+ if (u) -+ *p++ = ','; -+ len = strlen(buf[u]); -+ memcpy(p,buf[u],len); -+ p += len; -+ } -+ *p++ = ']'; -+ *p = 0; -+#ifdef IN_GCC -+ mem_free(buf); -+#else -+ mem.free(buf); -+#endif -+ return str; -+ } -+ -+ void reserve(size_t nentries) -+ { -+ //printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", (int)dim, (int)allocdim, (int)nentries); -+ if (allocdim - dim < nentries) -+ { -+ if (allocdim == 0) -+ { // Not properly initialized, someone memset it to zero -+ if (nentries <= SMALLARRAYCAP) -+ { allocdim = SMALLARRAYCAP; -+ data = SMALLARRAYCAP ? &smallarray[0] : NULL; -+ } -+ else -+ { allocdim = nentries; -+#ifdef IN_GCC -+ data = (TYPE **)mem_malloc(allocdim * sizeof(*data)); -+#else -+ data = (TYPE **)mem.malloc(allocdim * sizeof(*data)); -+#endif -+ } -+ } -+ else if (allocdim == SMALLARRAYCAP) -+ { -+ allocdim = dim + nentries; -+#ifdef IN_GCC -+ data = (TYPE **)mem_malloc(allocdim * sizeof(*data)); -+#else -+ data = (TYPE **)mem.malloc(allocdim * sizeof(*data)); -+#endif -+ memcpy(data, &smallarray[0], dim * sizeof(*data)); -+ } -+ else -+ { allocdim = dim + nentries; -+#ifdef IN_GCC -+ data = (TYPE **)mem_realloc(data, allocdim * sizeof(*data)); -+#else -+ data = (TYPE **)mem.realloc(data, allocdim * sizeof(*data)); -+#endif -+ } -+ } -+ } -+ -+ void setDim(size_t newdim) -+ { -+ if (dim < newdim) -+ { -+ reserve(newdim - dim); -+ } -+ dim = newdim; -+ } -+ -+ void fixDim() -+ { -+ if (dim != allocdim) -+ { -+ if (allocdim >= SMALLARRAYCAP) -+ { -+ if (dim <= SMALLARRAYCAP) -+ { -+ memcpy(&smallarray[0], data, dim * sizeof(*data)); -+#ifdef IN_GCC -+ mem_free(data); -+#else -+ mem.free(data); -+#endif -+ } -+ else -+#ifdef IN_GCC -+ data = (TYPE **)mem_realloc(data, dim * sizeof(*data)); -+#else -+ data = (TYPE **)mem.realloc(data, dim * sizeof(*data)); -+#endif -+ } -+ allocdim = dim; -+ } -+ } -+ -+ TYPE *pop() -+ { -+ return data[--dim]; -+ } -+ -+ void shift(TYPE *ptr) -+ { -+ reserve(1); -+ memmove(data + 1, data, dim * sizeof(*data)); -+ data[0] = ptr; -+ dim++; -+ } -+ -+ void remove(size_t i) -+ { -+ if (dim - i - 1) -+ memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0])); -+ dim--; -+ } -+ -+ void zero() -+ { -+ memset(data,0,dim * sizeof(data[0])); -+ } -+ -+ TYPE *tos() -+ { -+ return dim ? data[dim - 1] : NULL; -+ } -+ -+ void sort() -+ { -+ struct ArraySort -+ { -+ static int Array_sort_compare(const void *x, const void *y) -+ { -+ RootObject *ox = *(RootObject **)const_cast(x); -+ RootObject *oy = *(RootObject **)const_cast(y); -+ -+ return ox->compare(oy); -+ } -+ }; -+ -+ if (dim) -+ { -+ qsort(data, dim, sizeof(RootObject *), &ArraySort::Array_sort_compare); -+ } -+ } -+ -+ TYPE **tdata() -+ { -+ return data; -+ } -+ -+ TYPE*& operator[] (size_t index) -+ { -+#ifdef DEBUG -+ assert(index < dim); -+#endif -+ return data[index]; -+ } -+ -+ void insert(size_t index, TYPE *v) -+ { -+ reserve(1); -+ memmove(data + index + 1, data + index, (dim - index) * sizeof(*data)); -+ data[index] = v; -+ dim++; -+ } -+ -+ void insert(size_t index, Array *a) -+ { -+ if (a) -+ { -+ size_t d = a->dim; -+ reserve(d); -+ if (dim != index) -+ memmove(data + index + d, data + index, (dim - index) * sizeof(*data)); -+ memcpy(data + index, a->data, d * sizeof(*data)); -+ dim += d; -+ } -+ } -+ -+ void append(Array *a) -+ { -+ insert(dim, a); -+ } -+ -+ void push(TYPE *a) -+ { -+ reserve(1); -+ data[dim++] = a; -+ } -+ -+ Array *copy() -+ { -+ Array *a = new Array(); -+ -+ a->setDim(dim); -+ memcpy(a->data, data, dim * sizeof(*data)); -+ return a; -+ } -+ -+ typedef int (*Array_apply_ft_t)(TYPE *, void *); -+ int apply(Array_apply_ft_t fp, void *param) -+ { -+ for (size_t i = 0; i < dim; i++) -+ { TYPE *e = (*this)[i]; -+ -+ if (e) -+ { -+ if (e->apply(fp, param)) -+ return 1; -+ } -+ } -+ return 0; -+ } -+}; -+ -+#endif ---- a/src/gcc/d/dfrontend/arrayop.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/arrayop.c 2014-04-01 16:32:51.000000000 +0100 -@@ -32,6 +32,276 @@ extern int binary(const char *p , const - - AA *arrayfuncs; - -+/************************************** -+ * Structure to contain information needed to insert an array op call -+ */ -+ -+struct ArrayOp -+{ -+ FuncDeclaration *cFunc; // Stub for optimized druntime version -+ FuncDeclaration *dFunc; // Full D version for ctfe -+}; -+ -+/************************************** -+ * Search for a druntime array op -+ */ -+int isDruntimeArrayOp(Identifier *ident) -+{ -+ /* Some of the array op functions are written as library functions, -+ * presumably to optimize them with special CPU vector instructions. -+ * List those library functions here, in alpha order. -+ */ -+ static const char *libArrayopFuncs[] = -+ { -+ "_arrayExpSliceAddass_a", -+ "_arrayExpSliceAddass_d", // T[]+=T -+ "_arrayExpSliceAddass_f", // T[]+=T -+ "_arrayExpSliceAddass_g", -+ "_arrayExpSliceAddass_h", -+ "_arrayExpSliceAddass_i", -+ "_arrayExpSliceAddass_k", -+ "_arrayExpSliceAddass_s", -+ "_arrayExpSliceAddass_t", -+ "_arrayExpSliceAddass_u", -+ "_arrayExpSliceAddass_w", -+ -+ "_arrayExpSliceDivass_d", // T[]/=T -+ "_arrayExpSliceDivass_f", // T[]/=T -+ -+ "_arrayExpSliceMinSliceAssign_a", -+ "_arrayExpSliceMinSliceAssign_d", // T[]=T-T[] -+ "_arrayExpSliceMinSliceAssign_f", // T[]=T-T[] -+ "_arrayExpSliceMinSliceAssign_g", -+ "_arrayExpSliceMinSliceAssign_h", -+ "_arrayExpSliceMinSliceAssign_i", -+ "_arrayExpSliceMinSliceAssign_k", -+ "_arrayExpSliceMinSliceAssign_s", -+ "_arrayExpSliceMinSliceAssign_t", -+ "_arrayExpSliceMinSliceAssign_u", -+ "_arrayExpSliceMinSliceAssign_w", -+ -+ "_arrayExpSliceMinass_a", -+ "_arrayExpSliceMinass_d", // T[]-=T -+ "_arrayExpSliceMinass_f", // T[]-=T -+ "_arrayExpSliceMinass_g", -+ "_arrayExpSliceMinass_h", -+ "_arrayExpSliceMinass_i", -+ "_arrayExpSliceMinass_k", -+ "_arrayExpSliceMinass_s", -+ "_arrayExpSliceMinass_t", -+ "_arrayExpSliceMinass_u", -+ "_arrayExpSliceMinass_w", -+ -+ "_arrayExpSliceMulass_d", // T[]*=T -+ "_arrayExpSliceMulass_f", // T[]*=T -+ "_arrayExpSliceMulass_i", -+ "_arrayExpSliceMulass_k", -+ "_arrayExpSliceMulass_s", -+ "_arrayExpSliceMulass_t", -+ "_arrayExpSliceMulass_u", -+ "_arrayExpSliceMulass_w", -+ -+ "_arraySliceExpAddSliceAssign_a", -+ "_arraySliceExpAddSliceAssign_d", // T[]=T[]+T -+ "_arraySliceExpAddSliceAssign_f", // T[]=T[]+T -+ "_arraySliceExpAddSliceAssign_g", -+ "_arraySliceExpAddSliceAssign_h", -+ "_arraySliceExpAddSliceAssign_i", -+ "_arraySliceExpAddSliceAssign_k", -+ "_arraySliceExpAddSliceAssign_s", -+ "_arraySliceExpAddSliceAssign_t", -+ "_arraySliceExpAddSliceAssign_u", -+ "_arraySliceExpAddSliceAssign_w", -+ -+ "_arraySliceExpDivSliceAssign_d", // T[]=T[]/T -+ "_arraySliceExpDivSliceAssign_f", // T[]=T[]/T -+ -+ "_arraySliceExpMinSliceAssign_a", -+ "_arraySliceExpMinSliceAssign_d", // T[]=T[]-T -+ "_arraySliceExpMinSliceAssign_f", // T[]=T[]-T -+ "_arraySliceExpMinSliceAssign_g", -+ "_arraySliceExpMinSliceAssign_h", -+ "_arraySliceExpMinSliceAssign_i", -+ "_arraySliceExpMinSliceAssign_k", -+ "_arraySliceExpMinSliceAssign_s", -+ "_arraySliceExpMinSliceAssign_t", -+ "_arraySliceExpMinSliceAssign_u", -+ "_arraySliceExpMinSliceAssign_w", -+ -+ "_arraySliceExpMulSliceAddass_d", // T[] += T[]*T -+ "_arraySliceExpMulSliceAddass_f", -+ "_arraySliceExpMulSliceAddass_r", -+ -+ "_arraySliceExpMulSliceAssign_d", // T[]=T[]*T -+ "_arraySliceExpMulSliceAssign_f", // T[]=T[]*T -+ "_arraySliceExpMulSliceAssign_i", -+ "_arraySliceExpMulSliceAssign_k", -+ "_arraySliceExpMulSliceAssign_s", -+ "_arraySliceExpMulSliceAssign_t", -+ "_arraySliceExpMulSliceAssign_u", -+ "_arraySliceExpMulSliceAssign_w", -+ -+ "_arraySliceExpMulSliceMinass_d", // T[] -= T[]*T -+ "_arraySliceExpMulSliceMinass_f", -+ "_arraySliceExpMulSliceMinass_r", -+ -+ "_arraySliceSliceAddSliceAssign_a", -+ "_arraySliceSliceAddSliceAssign_d", // T[]=T[]+T[] -+ "_arraySliceSliceAddSliceAssign_f", // T[]=T[]+T[] -+ "_arraySliceSliceAddSliceAssign_g", -+ "_arraySliceSliceAddSliceAssign_h", -+ "_arraySliceSliceAddSliceAssign_i", -+ "_arraySliceSliceAddSliceAssign_k", -+ "_arraySliceSliceAddSliceAssign_r", // T[]=T[]+T[] -+ "_arraySliceSliceAddSliceAssign_s", -+ "_arraySliceSliceAddSliceAssign_t", -+ "_arraySliceSliceAddSliceAssign_u", -+ "_arraySliceSliceAddSliceAssign_w", -+ -+ "_arraySliceSliceAddass_a", -+ "_arraySliceSliceAddass_d", // T[]+=T[] -+ "_arraySliceSliceAddass_f", // T[]+=T[] -+ "_arraySliceSliceAddass_g", -+ "_arraySliceSliceAddass_h", -+ "_arraySliceSliceAddass_i", -+ "_arraySliceSliceAddass_k", -+ "_arraySliceSliceAddass_s", -+ "_arraySliceSliceAddass_t", -+ "_arraySliceSliceAddass_u", -+ "_arraySliceSliceAddass_w", -+ -+ "_arraySliceSliceMinSliceAssign_a", -+ "_arraySliceSliceMinSliceAssign_d", // T[]=T[]-T[] -+ "_arraySliceSliceMinSliceAssign_f", // T[]=T[]-T[] -+ "_arraySliceSliceMinSliceAssign_g", -+ "_arraySliceSliceMinSliceAssign_h", -+ "_arraySliceSliceMinSliceAssign_i", -+ "_arraySliceSliceMinSliceAssign_k", -+ "_arraySliceSliceMinSliceAssign_r", // T[]=T[]-T[] -+ "_arraySliceSliceMinSliceAssign_s", -+ "_arraySliceSliceMinSliceAssign_t", -+ "_arraySliceSliceMinSliceAssign_u", -+ "_arraySliceSliceMinSliceAssign_w", -+ -+ "_arraySliceSliceMinass_a", -+ "_arraySliceSliceMinass_d", // T[]-=T[] -+ "_arraySliceSliceMinass_f", // T[]-=T[] -+ "_arraySliceSliceMinass_g", -+ "_arraySliceSliceMinass_h", -+ "_arraySliceSliceMinass_i", -+ "_arraySliceSliceMinass_k", -+ "_arraySliceSliceMinass_s", -+ "_arraySliceSliceMinass_t", -+ "_arraySliceSliceMinass_u", -+ "_arraySliceSliceMinass_w", -+ -+ "_arraySliceSliceMulSliceAssign_d", // T[]=T[]*T[] -+ "_arraySliceSliceMulSliceAssign_f", // T[]=T[]*T[] -+ "_arraySliceSliceMulSliceAssign_i", -+ "_arraySliceSliceMulSliceAssign_k", -+ "_arraySliceSliceMulSliceAssign_s", -+ "_arraySliceSliceMulSliceAssign_t", -+ "_arraySliceSliceMulSliceAssign_u", -+ "_arraySliceSliceMulSliceAssign_w", -+ -+ "_arraySliceSliceMulass_d", // T[]*=T[] -+ "_arraySliceSliceMulass_f", // T[]*=T[] -+ "_arraySliceSliceMulass_i", -+ "_arraySliceSliceMulass_k", -+ "_arraySliceSliceMulass_s", -+ "_arraySliceSliceMulass_t", -+ "_arraySliceSliceMulass_u", -+ "_arraySliceSliceMulass_w", -+ }; -+ char *name = ident->toChars(); -+ int i = binary(name, libArrayopFuncs, sizeof(libArrayopFuncs) / sizeof(char *)); -+ if (i != -1) -+ return 1; -+ -+#ifdef DEBUG // Make sure our array is alphabetized -+ for (i = 0; i < sizeof(libArrayopFuncs) / sizeof(char *); i++) -+ { -+ if (strcmp(name, libArrayopFuncs[i]) == 0) -+ assert(0); -+ } -+#endif -+ return 0; -+} -+ -+ArrayOp *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc) -+{ -+ Parameters *fparams = new Parameters(); -+ Expression *loopbody = exp->buildArrayLoop(fparams); -+ -+ ArrayOp *op = new ArrayOp; -+ if (isDruntimeArrayOp(ident)) -+ op->cFunc = FuncDeclaration::genCfunc(fparams, exp->type, ident); -+ else -+ op->cFunc = NULL; -+ -+ /* Construct the function body: -+ * foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++) -+ * loopbody; -+ * return p; -+ */ -+ -+ Parameter *p = (*fparams)[0 /*fparams->dim - 1*/]; -+#if DMDV1 -+ // for (size_t i = 0; i < p.length; i++) -+ Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t)); -+ Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init); -+ Statement *s1 = new ForStatement(0, -+ new ExpStatement(0, d), -+ new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))), -+ new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)), -+ new ExpStatement(0, loopbody)); -+#else -+ // foreach (i; 0 .. p.length) -+ Statement *s1 = new ForeachRangeStatement(Loc(), TOKforeach, -+ new Parameter(0, NULL, Id::p, NULL), -+ new IntegerExp(Loc(), 0, Type::tsize_t), -+ new ArrayLengthExp(Loc(), new IdentifierExp(Loc(), p->ident)), -+ new ExpStatement(Loc(), loopbody)); -+#endif -+ //printf("%s\n", s1->toChars()); -+ Statement *s2 = new ReturnStatement(Loc(), new IdentifierExp(Loc(), p->ident)); -+ //printf("s2: %s\n", s2->toChars()); -+ Statement *fbody = new CompoundStatement(Loc(), s1, s2); -+ -+ // Built-in array ops should be @trusted, pure and nothrow -+ StorageClass stc = STCtrusted | STCpure | STCnothrow; -+ -+ /* Construct the function -+ */ -+ TypeFunction *ftype = new TypeFunction(fparams, exp->type, 0, LINKc, stc); -+ //printf("ftype: %s\n", ftype->toChars()); -+ FuncDeclaration *fd = new FuncDeclaration(Loc(), Loc(), ident, STCundefined, ftype); -+ fd->fbody = fbody; -+ fd->protection = PROTpublic; -+ fd->linkage = LINKc; -+ fd->isArrayOp = 1; -+ -+ if (!op->cFunc) -+ sc->module->importedFrom->members->push(fd); -+ -+ sc = sc->push(); -+ sc->parent = sc->module->importedFrom; -+ sc->stc = 0; -+ sc->linkage = LINKc; -+ fd->semantic(sc); -+ fd->semantic2(sc); -+ fd->semantic3(sc); -+ sc->pop(); -+ -+ if (op->cFunc) -+ { -+ op->cFunc->dArrayOp = fd; -+ op->cFunc->type = fd->type; -+ } -+ op->dFunc = fd; -+ return op; -+} -+ - /********************************************** - * Check that there are no uses of arrays without []. - */ -@@ -39,6 +309,13 @@ bool isArrayOpValid(Expression *e) - { - if (e->op == TOKslice) - return true; -+ if (e->op == TOKarrayliteral) -+ { -+ Type *t = e->type->toBasetype(); -+ while (t->ty == Tarray || t->ty == Tsarray) -+ t = t->nextOf()->toBasetype(); -+ return (t->ty != Tvoid); -+ } - Type *tb = e->type->toBasetype(); - - if ( (tb->ty == Tarray) || (tb->ty == Tsarray) ) -@@ -127,268 +404,19 @@ Expression *BinExp::arrayOp(Scope *sc) - char *name = buf.toChars(); - Identifier *ident = Lexer::idPool(name); - -- /* Look up name in hash table -- */ -- FuncDeclaration **pfd = (FuncDeclaration **)_aaGet(&arrayfuncs, ident); -- FuncDeclaration *fd = (FuncDeclaration *)*pfd; -- if (!fd) -- { -- /* Some of the array op functions are written as library functions, -- * presumably to optimize them with special CPU vector instructions. -- * List those library functions here, in alpha order. -- */ -- static const char *libArrayopFuncs[] = -- { -- "_arrayExpSliceAddass_a", -- "_arrayExpSliceAddass_d", // T[]+=T -- "_arrayExpSliceAddass_f", // T[]+=T -- "_arrayExpSliceAddass_g", -- "_arrayExpSliceAddass_h", -- "_arrayExpSliceAddass_i", -- "_arrayExpSliceAddass_k", -- "_arrayExpSliceAddass_s", -- "_arrayExpSliceAddass_t", -- "_arrayExpSliceAddass_u", -- "_arrayExpSliceAddass_w", -- -- "_arrayExpSliceDivass_d", // T[]/=T -- "_arrayExpSliceDivass_f", // T[]/=T -- -- "_arrayExpSliceMinSliceAssign_a", -- "_arrayExpSliceMinSliceAssign_d", // T[]=T-T[] -- "_arrayExpSliceMinSliceAssign_f", // T[]=T-T[] -- "_arrayExpSliceMinSliceAssign_g", -- "_arrayExpSliceMinSliceAssign_h", -- "_arrayExpSliceMinSliceAssign_i", -- "_arrayExpSliceMinSliceAssign_k", -- "_arrayExpSliceMinSliceAssign_s", -- "_arrayExpSliceMinSliceAssign_t", -- "_arrayExpSliceMinSliceAssign_u", -- "_arrayExpSliceMinSliceAssign_w", -- -- "_arrayExpSliceMinass_a", -- "_arrayExpSliceMinass_d", // T[]-=T -- "_arrayExpSliceMinass_f", // T[]-=T -- "_arrayExpSliceMinass_g", -- "_arrayExpSliceMinass_h", -- "_arrayExpSliceMinass_i", -- "_arrayExpSliceMinass_k", -- "_arrayExpSliceMinass_s", -- "_arrayExpSliceMinass_t", -- "_arrayExpSliceMinass_u", -- "_arrayExpSliceMinass_w", -- -- "_arrayExpSliceMulass_d", // T[]*=T -- "_arrayExpSliceMulass_f", // T[]*=T -- "_arrayExpSliceMulass_i", -- "_arrayExpSliceMulass_k", -- "_arrayExpSliceMulass_s", -- "_arrayExpSliceMulass_t", -- "_arrayExpSliceMulass_u", -- "_arrayExpSliceMulass_w", -- -- "_arraySliceExpAddSliceAssign_a", -- "_arraySliceExpAddSliceAssign_d", // T[]=T[]+T -- "_arraySliceExpAddSliceAssign_f", // T[]=T[]+T -- "_arraySliceExpAddSliceAssign_g", -- "_arraySliceExpAddSliceAssign_h", -- "_arraySliceExpAddSliceAssign_i", -- "_arraySliceExpAddSliceAssign_k", -- "_arraySliceExpAddSliceAssign_s", -- "_arraySliceExpAddSliceAssign_t", -- "_arraySliceExpAddSliceAssign_u", -- "_arraySliceExpAddSliceAssign_w", -- -- "_arraySliceExpDivSliceAssign_d", // T[]=T[]/T -- "_arraySliceExpDivSliceAssign_f", // T[]=T[]/T -- -- "_arraySliceExpMinSliceAssign_a", -- "_arraySliceExpMinSliceAssign_d", // T[]=T[]-T -- "_arraySliceExpMinSliceAssign_f", // T[]=T[]-T -- "_arraySliceExpMinSliceAssign_g", -- "_arraySliceExpMinSliceAssign_h", -- "_arraySliceExpMinSliceAssign_i", -- "_arraySliceExpMinSliceAssign_k", -- "_arraySliceExpMinSliceAssign_s", -- "_arraySliceExpMinSliceAssign_t", -- "_arraySliceExpMinSliceAssign_u", -- "_arraySliceExpMinSliceAssign_w", -- -- "_arraySliceExpMulSliceAddass_d", // T[] += T[]*T -- "_arraySliceExpMulSliceAddass_f", -- "_arraySliceExpMulSliceAddass_r", -- -- "_arraySliceExpMulSliceAssign_d", // T[]=T[]*T -- "_arraySliceExpMulSliceAssign_f", // T[]=T[]*T -- "_arraySliceExpMulSliceAssign_i", -- "_arraySliceExpMulSliceAssign_k", -- "_arraySliceExpMulSliceAssign_s", -- "_arraySliceExpMulSliceAssign_t", -- "_arraySliceExpMulSliceAssign_u", -- "_arraySliceExpMulSliceAssign_w", -- -- "_arraySliceExpMulSliceMinass_d", // T[] -= T[]*T -- "_arraySliceExpMulSliceMinass_f", -- "_arraySliceExpMulSliceMinass_r", -- -- "_arraySliceSliceAddSliceAssign_a", -- "_arraySliceSliceAddSliceAssign_d", // T[]=T[]+T[] -- "_arraySliceSliceAddSliceAssign_f", // T[]=T[]+T[] -- "_arraySliceSliceAddSliceAssign_g", -- "_arraySliceSliceAddSliceAssign_h", -- "_arraySliceSliceAddSliceAssign_i", -- "_arraySliceSliceAddSliceAssign_k", -- "_arraySliceSliceAddSliceAssign_r", // T[]=T[]+T[] -- "_arraySliceSliceAddSliceAssign_s", -- "_arraySliceSliceAddSliceAssign_t", -- "_arraySliceSliceAddSliceAssign_u", -- "_arraySliceSliceAddSliceAssign_w", -- -- "_arraySliceSliceAddass_a", -- "_arraySliceSliceAddass_d", // T[]+=T[] -- "_arraySliceSliceAddass_f", // T[]+=T[] -- "_arraySliceSliceAddass_g", -- "_arraySliceSliceAddass_h", -- "_arraySliceSliceAddass_i", -- "_arraySliceSliceAddass_k", -- "_arraySliceSliceAddass_s", -- "_arraySliceSliceAddass_t", -- "_arraySliceSliceAddass_u", -- "_arraySliceSliceAddass_w", -- -- "_arraySliceSliceMinSliceAssign_a", -- "_arraySliceSliceMinSliceAssign_d", // T[]=T[]-T[] -- "_arraySliceSliceMinSliceAssign_f", // T[]=T[]-T[] -- "_arraySliceSliceMinSliceAssign_g", -- "_arraySliceSliceMinSliceAssign_h", -- "_arraySliceSliceMinSliceAssign_i", -- "_arraySliceSliceMinSliceAssign_k", -- "_arraySliceSliceMinSliceAssign_r", // T[]=T[]-T[] -- "_arraySliceSliceMinSliceAssign_s", -- "_arraySliceSliceMinSliceAssign_t", -- "_arraySliceSliceMinSliceAssign_u", -- "_arraySliceSliceMinSliceAssign_w", -- -- "_arraySliceSliceMinass_a", -- "_arraySliceSliceMinass_d", // T[]-=T[] -- "_arraySliceSliceMinass_f", // T[]-=T[] -- "_arraySliceSliceMinass_g", -- "_arraySliceSliceMinass_h", -- "_arraySliceSliceMinass_i", -- "_arraySliceSliceMinass_k", -- "_arraySliceSliceMinass_s", -- "_arraySliceSliceMinass_t", -- "_arraySliceSliceMinass_u", -- "_arraySliceSliceMinass_w", -- -- "_arraySliceSliceMulSliceAssign_d", // T[]=T[]*T[] -- "_arraySliceSliceMulSliceAssign_f", // T[]=T[]*T[] -- "_arraySliceSliceMulSliceAssign_i", -- "_arraySliceSliceMulSliceAssign_k", -- "_arraySliceSliceMulSliceAssign_s", -- "_arraySliceSliceMulSliceAssign_t", -- "_arraySliceSliceMulSliceAssign_u", -- "_arraySliceSliceMulSliceAssign_w", -- -- "_arraySliceSliceMulass_d", // T[]*=T[] -- "_arraySliceSliceMulass_f", // T[]*=T[] -- "_arraySliceSliceMulass_i", -- "_arraySliceSliceMulass_k", -- "_arraySliceSliceMulass_s", -- "_arraySliceSliceMulass_t", -- "_arraySliceSliceMulass_u", -- "_arraySliceSliceMulass_w", -- }; -+ ArrayOp **pOp = (ArrayOp **)_aaGet(&arrayfuncs, ident); -+ ArrayOp *op = *pOp; - -- int i = binary(name, libArrayopFuncs, sizeof(libArrayopFuncs) / sizeof(char *)); -- if (i == -1) -- { --#ifdef DEBUG // Make sure our array is alphabetized -- for (i = 0; i < sizeof(libArrayopFuncs) / sizeof(char *); i++) -- { -- if (strcmp(name, libArrayopFuncs[i]) == 0) -- assert(0); -- } --#endif -- /* Not in library, so generate it. -- * Construct the function body: -- * foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++) -- * loopbody; -- * return p; -- */ -- -- Parameters *fparams = new Parameters(); -- Expression *loopbody = buildArrayLoop(fparams); -- Parameter *p = (*fparams)[0 /*fparams->dim - 1*/]; --#if DMDV1 -- // for (size_t i = 0; i < p.length; i++) -- Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t)); -- Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init); -- Statement *s1 = new ForStatement(0, -- new ExpStatement(0, d), -- new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))), -- new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)), -- new ExpStatement(0, loopbody)); --#else -- // foreach (i; 0 .. p.length) -- Statement *s1 = new ForeachRangeStatement(0, TOKforeach, -- new Parameter(0, NULL, Id::p, NULL), -- new IntegerExp(0, 0, Type::tsize_t), -- new ArrayLengthExp(0, new IdentifierExp(0, p->ident)), -- new ExpStatement(0, loopbody)); --#endif -- Statement *s2 = new ReturnStatement(0, new IdentifierExp(0, p->ident)); -- //printf("s2: %s\n", s2->toChars()); -- Statement *fbody = new CompoundStatement(0, s1, s2); -- -- /* Construct the function -- */ -- TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc); -- //printf("ftype: %s\n", ftype->toChars()); -- fd = new FuncDeclaration(loc, 0, ident, STCundefined, ftype); -- fd->fbody = fbody; -- fd->protection = PROTpublic; -- fd->linkage = LINKc; -- fd->isArrayOp = 1; -- -- sc->module->importedFrom->members->push(fd); -- -- sc = sc->push(); -- sc->parent = sc->module->importedFrom; -- sc->stc = 0; -- sc->linkage = LINKc; -- fd->semantic(sc); -- fd->semantic2(sc); -- fd->semantic3(sc); -- sc->pop(); -- } -- else -- { /* In library, refer to it. -- */ -- fd = FuncDeclaration::genCfunc(type, ident); --#ifdef IN_GCC -- /* Setup function parameters for GCC backend -- */ -- TypeFunction * tf = (TypeFunction *) fd->type; -- Parameters * targs = new Parameters; -- targs->setDim(arguments->dim); -- for (unsigned i = 0; i < arguments->dim; i++) -- { -- targs->tdata()[i] = new Parameter(STCin, -- ((*arguments)[i])->type, NULL, NULL); -- } -- tf->parameters = targs; --#endif -- } -- *pfd = fd; // cache symbol in hash table -- } -+ if (!op) -+ op = buildArrayOp(ident, this, sc, loc); - -- /* Call the function fd(arguments) -- */ -- Expression *ec = new VarExp(0, fd); -+ *pOp = op; -+ -+ FuncDeclaration *fd = op->cFunc ? op->cFunc : op->dFunc; -+ Expression *ec = new VarExp(loc, fd); - Expression *e = new CallExp(loc, ec, arguments); -- e->type = type; -- return e; -+ -+ return e->semantic(sc); - } - - Expression *BinAssignExp::arrayOp(Scope *sc) -@@ -430,6 +458,12 @@ void CastExp::buildArrayIdent(OutBuffer - Expression::buildArrayIdent(buf, arguments); - } - -+void ArrayLiteralExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) -+{ -+ buf->writestring("Slice"); -+ arguments->shift(this); -+} -+ - void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) - { - buf->writestring("Slice"); -@@ -445,30 +479,30 @@ void AssignExp::buildArrayIdent(OutBuffe - buf->writestring("Assign"); - } - --#define X(Str) \ --void Str##AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) \ --{ \ -- /* Evaluate assign expressions right to left \ -- */ \ -- e2->buildArrayIdent(buf, arguments); \ -- e1->buildArrayIdent(buf, arguments); \ -- buf->writestring(#Str); \ -- buf->writestring("ass"); \ --} -- --X(Add) --X(Min) --X(Mul) --X(Div) --X(Mod) --X(Xor) --X(And) --X(Or) -+void BinAssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) -+{ -+ /* Evaluate assign expressions right to left -+ */ -+ e2->buildArrayIdent(buf, arguments); -+ e1->buildArrayIdent(buf, arguments); -+ const char *s; -+ switch(op) -+ { -+ case TOKaddass: s = "Addass"; break; -+ case TOKminass: s = "Subass"; break; -+ case TOKmulass: s = "Mulass"; break; -+ case TOKdivass: s = "Divass"; break; -+ case TOKmodass: s = "Modass"; break; -+ case TOKxorass: s = "Xorass"; break; -+ case TOKandass: s = "Andass"; break; -+ case TOKorass: s = "Orass"; break; - #if DMDV2 --X(Pow) -+ case TOKpowass: s = "Powass"; break; - #endif -- --#undef X -+ default: assert(0); -+ } -+ buf->writestring(s); -+} - - void NegExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) - { -@@ -482,29 +516,35 @@ void ComExp::buildArrayIdent(OutBuffer * - buf->writestring("Com"); - } - --#define X(Str) \ --void Str##Exp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) \ --{ \ -- /* Evaluate assign expressions left to right \ -- */ \ -- e1->buildArrayIdent(buf, arguments); \ -- e2->buildArrayIdent(buf, arguments); \ -- buf->writestring(#Str); \ --} -- --X(Add) --X(Min) --X(Mul) --X(Div) --X(Mod) --X(Xor) --X(And) --X(Or) -+void BinExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) -+{ -+ /* Evaluate assign expressions left to right -+ */ -+ const char *s = NULL; -+ switch(op) -+ { -+ case TOKadd: s = "Add"; break; -+ case TOKmin: s = "Sub"; break; -+ case TOKmul: s = "Mul"; break; -+ case TOKdiv: s = "Div"; break; -+ case TOKmod: s = "Mod"; break; -+ case TOKxor: s = "Xor"; break; -+ case TOKand: s = "And"; break; -+ case TOKor: s = "Or"; break; - #if DMDV2 --X(Pow) -+ case TOKpow: s = "Pow"; break; - #endif -- --#undef X -+ default: break; -+ } -+ if (s) -+ { -+ e1->buildArrayIdent(buf, arguments); -+ e2->buildArrayIdent(buf, arguments); -+ buf->writestring(s); -+ } -+ else -+ Expression::buildArrayIdent(buf, arguments); -+} - - /****************************************** - * Construct the inner loop for the array operation function, -@@ -516,7 +556,7 @@ Expression *Expression::buildArrayLoop(P - Identifier *id = Identifier::generateId("c", fparams->dim); - Parameter *param = new Parameter(0, type, id, NULL); - fparams->shift(param); -- Expression *e = new IdentifierExp(0, id); -+ Expression *e = new IdentifierExp(Loc(), id); - return e; - } - -@@ -531,16 +571,29 @@ Expression *CastExp::buildArrayLoop(Para - return Expression::buildArrayLoop(fparams); - } - -+Expression *ArrayLiteralExp::buildArrayLoop(Parameters *fparams) -+{ -+ Identifier *id = Identifier::generateId("p", fparams->dim); -+ Parameter *param = new Parameter(STCconst, type, id, NULL); -+ fparams->shift(param); -+ Expression *e = new IdentifierExp(Loc(), id); -+ Expressions *arguments = new Expressions(); -+ Expression *index = new IdentifierExp(Loc(), Id::p); -+ arguments->push(index); -+ e = new ArrayExp(Loc(), e, arguments); -+ return e; -+} -+ - Expression *SliceExp::buildArrayLoop(Parameters *fparams) - { - Identifier *id = Identifier::generateId("p", fparams->dim); - Parameter *param = new Parameter(STCconst, type, id, NULL); - fparams->shift(param); -- Expression *e = new IdentifierExp(0, id); -+ Expression *e = new IdentifierExp(Loc(), id); - Expressions *arguments = new Expressions(); -- Expression *index = new IdentifierExp(0, Id::p); -+ Expression *index = new IdentifierExp(Loc(), Id::p); - arguments->push(index); -- e = new ArrayExp(0, e, arguments); -+ e = new ArrayExp(Loc(), e, arguments); - return e; - } - -@@ -555,81 +608,85 @@ Expression *AssignExp::buildArrayLoop(Pa - * where b is a byte fails because (c + p[i]) is an int - * which cannot be implicitly cast to byte. - */ -- ex2 = new CastExp(0, ex2, e1->type->nextOf()); -+ ex2 = new CastExp(Loc(), ex2, e1->type->nextOf()); - #endif - Expression *ex1 = e1->buildArrayLoop(fparams); - Parameter *param = (*fparams)[0]; - param->storageClass = 0; -- Expression *e = new AssignExp(0, ex1, ex2); -+ Expression *e = new AssignExp(Loc(), ex1, ex2); - return e; - } - --#define X(Str) \ --Expression *Str##AssignExp::buildArrayLoop(Parameters *fparams) \ --{ \ -- /* Evaluate assign expressions right to left \ -- */ \ -- Expression *ex2 = e2->buildArrayLoop(fparams); \ -- Expression *ex1 = e1->buildArrayLoop(fparams); \ -- Parameter *param = (*fparams)[0]; \ -- param->storageClass = 0; \ -- Expression *e = new Str##AssignExp(loc, ex1, ex2); \ -- return e; \ --} -- --X(Add) --X(Min) --X(Mul) --X(Div) --X(Mod) --X(Xor) --X(And) --X(Or) -+Expression *BinAssignExp::buildArrayLoop(Parameters *fparams) -+{ -+ /* Evaluate assign expressions right to left -+ */ -+ Expression *ex2 = e2->buildArrayLoop(fparams); -+ Expression *ex1 = e1->buildArrayLoop(fparams); -+ Parameter *param = (*fparams)[0]; -+ param->storageClass = 0; -+ Expression *e; -+ switch(op) -+ { -+ case TOKaddass: return new AddAssignExp(loc, ex1, ex2); -+ case TOKminass: return new MinAssignExp(loc, ex1, ex2); -+ case TOKmulass: return new MulAssignExp(loc, ex1, ex2); -+ case TOKdivass: return new DivAssignExp(loc, ex1, ex2); -+ case TOKmodass: return new ModAssignExp(loc, ex1, ex2); -+ case TOKxorass: return new XorAssignExp(loc, ex1, ex2); -+ case TOKandass: return new AndAssignExp(loc, ex1, ex2); -+ case TOKorass: return new OrAssignExp(loc, ex1, ex2); - #if DMDV2 --X(Pow) -+ case TOKpowass: return new PowAssignExp(loc, ex1, ex2); - #endif -- --#undef X -+ default: -+ assert(0); -+ return NULL; -+ } -+} - - Expression *NegExp::buildArrayLoop(Parameters *fparams) - { - Expression *ex1 = e1->buildArrayLoop(fparams); -- Expression *e = new NegExp(0, ex1); -+ Expression *e = new NegExp(Loc(), ex1); - return e; - } - - Expression *ComExp::buildArrayLoop(Parameters *fparams) - { - Expression *ex1 = e1->buildArrayLoop(fparams); -- Expression *e = new ComExp(0, ex1); -+ Expression *e = new ComExp(Loc(), ex1); - return e; - } - --#define X(Str) \ --Expression *Str##Exp::buildArrayLoop(Parameters *fparams) \ --{ \ -- /* Evaluate assign expressions left to right \ -- */ \ -- Expression *ex1 = e1->buildArrayLoop(fparams); \ -- Expression *ex2 = e2->buildArrayLoop(fparams); \ -- Expression *e = new Str##Exp(0, ex1, ex2); \ -- return e; \ --} -- --X(Add) --X(Min) --X(Mul) --X(Div) --X(Mod) --X(Xor) --X(And) --X(Or) -+Expression *BinExp::buildArrayLoop(Parameters *fparams) -+{ -+ switch(op) -+ { -+ case TOKadd: -+ case TOKmin: -+ case TOKmul: -+ case TOKdiv: -+ case TOKmod: -+ case TOKxor: -+ case TOKand: -+ case TOKor: - #if DMDV2 --X(Pow) -+ case TOKpow: - #endif -- --#undef X -- -+ { -+ /* Evaluate assign expressions left to right -+ */ -+ BinExp *e = (BinExp *)copy(); -+ e->e1 = e->e1->buildArrayLoop(fparams); -+ e->e2 = e->e2->buildArrayLoop(fparams); -+ e->type = NULL; -+ return e; -+ } -+ default: -+ return Expression::buildArrayLoop(fparams); -+ } -+} - - /*********************************************** - * Test if operand is a valid array op operand. -@@ -640,6 +697,13 @@ int Expression::isArrayOperand() - //printf("Expression::isArrayOperand() %s\n", toChars()); - if (op == TOKslice) - return 1; -+ if (op == TOKarrayliteral) -+ { -+ Type *t = type->toBasetype(); -+ while (t->ty == Tarray || t->ty == Tsarray) -+ t = t->nextOf()->toBasetype(); -+ return (t->ty != Tvoid); -+ } - if (type->toBasetype()->ty == Tarray) - { - switch (op) ---- a/src/gcc/d/dfrontend/arraytypes.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/arraytypes.h 2014-04-01 16:32:51.000000000 +0100 -@@ -18,66 +18,71 @@ - - #include "root.h" - --typedef ArrayBase TemplateParameters; -+typedef Array TemplateParameters; - --typedef ArrayBase Expressions; -+typedef Array Expressions; - --typedef ArrayBase Statements; -+typedef Array Statements; - --typedef ArrayBase BaseClasses; -+typedef Array BaseClasses; - --typedef ArrayBase ClassDeclarations; -+typedef Array ClassDeclarations; - --typedef ArrayBase Dsymbols; -+typedef Array Dsymbols; - --typedef ArrayBase Objects; -+typedef Array Objects; - --typedef ArrayBase FuncDeclarations; -+typedef Array FuncDeclarations; - --typedef ArrayBase Parameters; -+typedef Array Parameters; - --typedef ArrayBase Identifiers; -+typedef Array Identifiers; - --typedef ArrayBase Initializers; -+typedef Array Initializers; - --typedef ArrayBase VarDeclarations; -+typedef Array VarDeclarations; - --typedef ArrayBase Types; -+typedef Array Types; - --typedef ArrayBase ScopeDsymbols; -+typedef Array ScopeDsymbols; - --typedef ArrayBase Catches; -+typedef Array Catches; - --typedef ArrayBase StaticDtorDeclarations; -+typedef Array StaticDtorDeclarations; - --typedef ArrayBase SharedStaticDtorDeclarations; -+typedef Array SharedStaticDtorDeclarations; - --typedef ArrayBase AliasDeclarations; -+typedef Array AliasDeclarations; - --typedef ArrayBase Modules; -+typedef Array Modules; - --typedef ArrayBase Files; -+typedef Array Files; - --typedef ArrayBase CaseStatements; -+typedef Array CaseStatements; - --typedef ArrayBase CompoundStatements; -+typedef Array CompoundStatements; - --typedef ArrayBase GotoCaseStatements; -+typedef Array GotoCaseStatements; - --typedef ArrayBase ReturnStatements; -+typedef Array ReturnStatements; - --typedef ArrayBase TemplateInstances; -+typedef Array TemplateInstances; - --//typedef ArrayBase Strings; -+//typedef Array Strings; - --typedef ArrayBase Voids; -+typedef Array Voids; - - #ifdef IN_GCC --typedef ArrayBase Blocks; -+typedef Array Blocks; - #else --typedef ArrayBase Blocks; -+typedef Array Blocks; - #endif - --typedef ArrayBase Symbols; -+typedef Array Symbols; - -+#ifdef IN_GCC -+typedef Array Dts; -+#else -+typedef Array Dts; -+#endif - #endif ---- a/src/gcc/d/dfrontend/artistic.txt 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/artistic.txt 2014-04-01 16:32:51.000000000 +0100 -@@ -1,117 +1,117 @@ -- -- -- -- -- The "Artistic License" -- -- Preamble -- --The intent of this document is to state the conditions under which a --Package may be copied, such that the Copyright Holder maintains some --semblance of artistic control over the development of the package, --while giving the users of the package the right to use and distribute --the Package in a more-or-less customary fashion, plus the right to make --reasonable modifications. -- --Definitions: -- -- "Package" refers to the collection of files distributed by the -- Copyright Holder, and derivatives of that collection of files -- created through textual modification. -- -- "Standard Version" refers to such a Package if it has not been -- modified, or has been modified in accordance with the wishes -- of the Copyright Holder as specified below. -- -- "Copyright Holder" is whoever is named in the copyright or -- copyrights for the package. -- -- "You" is you, if you're thinking about copying or distributing -- this Package. -- -- "Reasonable copying fee" is whatever you can justify on the -- basis of media cost, duplication charges, time of people involved, -- and so on. (You will not be required to justify it to the -- Copyright Holder, but only to the computing community at large -- as a market that must bear the fee.) -- -- "Freely Available" means that no fee is charged for the item -- itself, though there may be fees involved in handling the item. -- It also means that recipients of the item may redistribute it -- under the same conditions they received it. -- --1. You may make and give away verbatim copies of the source form of the --Standard Version of this Package without restriction, provided that you --duplicate all of the original copyright notices and associated disclaimers. -- --2. You may apply bug fixes, portability fixes and other modifications --derived from the Public Domain or from the Copyright Holder. A Package --modified in such a way shall still be considered the Standard Version. -- --3. You may otherwise modify your copy of this Package in any way, provided --that you insert a prominent notice in each changed file stating how and --when you changed that file, and provided that you do at least ONE of the --following: -- -- a) place your modifications in the Public Domain or otherwise make them -- Freely Available, such as by posting said modifications to Usenet or -- an equivalent medium, or placing the modifications on a major archive -- site such as uunet.uu.net, or by allowing the Copyright Holder to include -- your modifications in the Standard Version of the Package. -- -- b) use the modified Package only within your corporation or organization. -- -- c) rename any non-standard executables so the names do not conflict -- with standard executables, which must also be provided, and provide -- a separate manual page for each non-standard executable that clearly -- documents how it differs from the Standard Version. -- -- d) make other distribution arrangements with the Copyright Holder. -- --4. You may distribute the programs of this Package in object code or --executable form, provided that you do at least ONE of the following: -- -- a) distribute a Standard Version of the executables and library files, -- together with instructions (in the manual page or equivalent) on where -- to get the Standard Version. -- -- b) accompany the distribution with the machine-readable source of -- the Package with your modifications. -- -- c) give non-standard executables non-standard names, and clearly -- document the differences in manual pages (or equivalent), together -- with instructions on where to get the Standard Version. -- -- d) make other distribution arrangements with the Copyright Holder. -- --5. You may charge a reasonable copying fee for any distribution of this --Package. You may charge any fee you choose for support of this --Package. You may not charge a fee for this Package itself. However, --you may distribute this Package in aggregate with other (possibly --commercial) programs as part of a larger (possibly commercial) software --distribution provided that you do not advertise this Package as a --product of your own. You may embed this Package's interpreter within --an executable of yours (by linking); this shall be construed as a mere --form of aggregation, provided that the complete Standard Version of the --interpreter is so embedded. -- --6. The source code and object code supplied as input to or produced as --output from the programs of this Package do not automatically fall --under the copyright of this Package, but belong to whoever generated --them, and may be sold commercially, and may be aggregated with this --Package. -- --7. Aggregation of this Package with a commercial distribution is always --permitted provided that the use of this Package is embedded; that is, --when no overt attempt is made to make this Package's interfaces visible --to the end user of the commercial distribution. Such use shall not be --construed as a distribution of this Package. -- --8. The name of the Copyright Holder may not be used to endorse or promote --products derived from this software without specific prior written permission. -- --9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR --IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED --WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. -- -- The End -+ -+ -+ -+ -+ The "Artistic License" -+ -+ Preamble -+ -+The intent of this document is to state the conditions under which a -+Package may be copied, such that the Copyright Holder maintains some -+semblance of artistic control over the development of the package, -+while giving the users of the package the right to use and distribute -+the Package in a more-or-less customary fashion, plus the right to make -+reasonable modifications. -+ -+Definitions: -+ -+ "Package" refers to the collection of files distributed by the -+ Copyright Holder, and derivatives of that collection of files -+ created through textual modification. -+ -+ "Standard Version" refers to such a Package if it has not been -+ modified, or has been modified in accordance with the wishes -+ of the Copyright Holder as specified below. -+ -+ "Copyright Holder" is whoever is named in the copyright or -+ copyrights for the package. -+ -+ "You" is you, if you're thinking about copying or distributing -+ this Package. -+ -+ "Reasonable copying fee" is whatever you can justify on the -+ basis of media cost, duplication charges, time of people involved, -+ and so on. (You will not be required to justify it to the -+ Copyright Holder, but only to the computing community at large -+ as a market that must bear the fee.) -+ -+ "Freely Available" means that no fee is charged for the item -+ itself, though there may be fees involved in handling the item. -+ It also means that recipients of the item may redistribute it -+ under the same conditions they received it. -+ -+1. You may make and give away verbatim copies of the source form of the -+Standard Version of this Package without restriction, provided that you -+duplicate all of the original copyright notices and associated disclaimers. -+ -+2. You may apply bug fixes, portability fixes and other modifications -+derived from the Public Domain or from the Copyright Holder. A Package -+modified in such a way shall still be considered the Standard Version. -+ -+3. You may otherwise modify your copy of this Package in any way, provided -+that you insert a prominent notice in each changed file stating how and -+when you changed that file, and provided that you do at least ONE of the -+following: -+ -+ a) place your modifications in the Public Domain or otherwise make them -+ Freely Available, such as by posting said modifications to Usenet or -+ an equivalent medium, or placing the modifications on a major archive -+ site such as uunet.uu.net, or by allowing the Copyright Holder to include -+ your modifications in the Standard Version of the Package. -+ -+ b) use the modified Package only within your corporation or organization. -+ -+ c) rename any non-standard executables so the names do not conflict -+ with standard executables, which must also be provided, and provide -+ a separate manual page for each non-standard executable that clearly -+ documents how it differs from the Standard Version. -+ -+ d) make other distribution arrangements with the Copyright Holder. -+ -+4. You may distribute the programs of this Package in object code or -+executable form, provided that you do at least ONE of the following: -+ -+ a) distribute a Standard Version of the executables and library files, -+ together with instructions (in the manual page or equivalent) on where -+ to get the Standard Version. -+ -+ b) accompany the distribution with the machine-readable source of -+ the Package with your modifications. -+ -+ c) give non-standard executables non-standard names, and clearly -+ document the differences in manual pages (or equivalent), together -+ with instructions on where to get the Standard Version. -+ -+ d) make other distribution arrangements with the Copyright Holder. -+ -+5. You may charge a reasonable copying fee for any distribution of this -+Package. You may charge any fee you choose for support of this -+Package. You may not charge a fee for this Package itself. However, -+you may distribute this Package in aggregate with other (possibly -+commercial) programs as part of a larger (possibly commercial) software -+distribution provided that you do not advertise this Package as a -+product of your own. You may embed this Package's interpreter within -+an executable of yours (by linking); this shall be construed as a mere -+form of aggregation, provided that the complete Standard Version of the -+interpreter is so embedded. -+ -+6. The source code and object code supplied as input to or produced as -+output from the programs of this Package do not automatically fall -+under the copyright of this Package, but belong to whoever generated -+them, and may be sold commercially, and may be aggregated with this -+Package. -+ -+7. Aggregation of this Package with a commercial distribution is always -+permitted provided that the use of this Package is embedded; that is, -+when no overt attempt is made to make this Package's interfaces visible -+to the end user of the commercial distribution. Such use shall not be -+construed as a distribution of this Package. -+ -+8. The name of the Copyright Holder may not be used to endorse or promote -+products derived from this software without specific prior written permission. -+ -+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR -+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. -+ -+ The End ---- a/src/gcc/d/dfrontend/async.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/async.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,337 +0,0 @@ -- --// Copyright (c) 2009-2012 by Digital Mars --// All Rights Reserved --// written by Walter Bright --// http://www.digitalmars.com --// License for redistribution is by either the Artistic License --// in artistic.txt, or the GNU General Public License in gnu.txt. --// See the included readme.txt for details. -- --#define _MT 1 -- --#include --#include --#include -- --#ifndef IN_GCC -- --#if _WIN32 -- --#include --#include --#include -- --#include "root.h" -- --static unsigned __stdcall startthread(void *p); -- --struct FileData --{ -- File *file; -- int result; -- HANDLE event; --}; -- --struct AsyncRead --{ -- static AsyncRead *create(size_t nfiles); -- void addFile(File *file); -- void start(); -- int read(size_t i); -- static void dispose(AsyncRead *); -- -- HANDLE hThread; -- -- size_t filesdim; -- size_t filesmax; -- FileData files[1]; --}; -- -- --AsyncRead *AsyncRead::create(size_t nfiles) --{ -- AsyncRead *aw = (AsyncRead *)calloc(1, sizeof(AsyncRead) + -- (nfiles - 1) * sizeof(FileData)); -- aw->filesmax = nfiles; -- return aw; --} -- --void AsyncRead::addFile(File *file) --{ -- //printf("addFile(file = %p)\n", file); -- //printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax); -- assert(filesdim < filesmax); -- files[filesdim].file = file; -- files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL); -- ResetEvent(files[filesdim].event); -- filesdim++; --} -- --void AsyncRead::start() --{ -- //printf("aw->filesdim = %p %d\n", this, filesdim); -- if (filesdim) -- { -- unsigned threadaddr; -- hThread = (HANDLE) _beginthreadex(NULL, -- 0, -- &startthread, -- this, -- 0, -- (unsigned *)&threadaddr); -- -- if (hThread) -- { -- SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); -- } -- else -- { -- assert(0); -- } -- } --} -- --int AsyncRead::read(size_t i) --{ -- FileData *f = &files[i]; -- WaitForSingleObject(f->event, INFINITE); -- Sleep(0); // give up time slice -- return f->result; --} -- --void AsyncRead::dispose(AsyncRead *aw) --{ -- free(aw); --} -- -- -- --unsigned __stdcall startthread(void *p) --{ -- AsyncRead *aw = (AsyncRead *)p; -- -- //printf("aw->filesdim = %p %d\n", aw, aw->filesdim); -- for (size_t i = 0; i < aw->filesdim; i++) -- { FileData *f = &aw->files[i]; -- -- f->result = f->file->read(); -- SetEvent(f->event); -- } -- _endthreadex(EXIT_SUCCESS); -- return EXIT_SUCCESS; // if skidding --} -- --#elif linux // Posix -- --#include --#include --#include -- --#include "root.h" -- --void *startthread(void *arg); -- --void err_abort(int status, const char *msg) --{ -- fprintf(stderr, "fatal error = %d, %s\n", status, msg); -- exit(EXIT_FAILURE); --} -- --struct FileData --{ -- File *file; -- int result; -- -- pthread_mutex_t mutex; -- pthread_cond_t cond; -- int value; --}; -- --struct AsyncRead --{ -- static AsyncRead *create(size_t nfiles); -- void addFile(File *file); -- void start(); -- int read(size_t i); -- static void dispose(AsyncRead *); -- -- size_t filesdim; -- size_t filesmax; -- FileData files[1]; --}; -- -- --AsyncRead *AsyncRead::create(size_t nfiles) --{ -- AsyncRead *aw = (AsyncRead *)calloc(1, sizeof(AsyncRead) + -- (nfiles - 1) * sizeof(FileData)); -- aw->filesmax = nfiles; -- return aw; --} -- --void AsyncRead::addFile(File *file) --{ -- //printf("addFile(file = %p)\n", file); -- //printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax); -- assert(filesdim < filesmax); -- FileData *f = &files[filesdim]; -- f->file = file; -- -- int status = pthread_mutex_init(&f->mutex, NULL); -- if (status != 0) -- err_abort(status, "init mutex"); -- status = pthread_cond_init(&f->cond, NULL); -- if (status != 0) -- err_abort(status, "init cond"); -- -- filesdim++; --} -- --void AsyncRead::start() --{ -- //printf("aw->filesdim = %p %d\n", this, filesdim); -- if (filesdim) -- { -- pthread_t thread_id; -- int status = pthread_create(&thread_id, -- NULL, -- &startthread, -- this); -- if (status != 0) -- err_abort(status, "create thread"); -- } --} -- --int AsyncRead::read(size_t i) --{ -- FileData *f = &files[i]; -- -- // Wait for the event -- int status = pthread_mutex_lock(&f->mutex); -- if (status != 0) -- err_abort(status, "lock mutex"); -- while (f->value == 0) -- { -- status = pthread_cond_wait(&f->cond, &f->mutex); -- if (status != 0) -- err_abort(status, "wait on condition"); -- } -- status = pthread_mutex_unlock(&f->mutex); -- if (status != 0) -- err_abort(status, "unlock mutex"); -- -- return f->result; --} -- --void AsyncRead::dispose(AsyncRead *aw) --{ -- //printf("AsyncRead::dispose()\n"); -- for (int i = 0; i < aw->filesdim; i++) -- { -- FileData *f = &aw->files[i]; -- int status = pthread_cond_destroy(&f->cond); -- if (status != 0) -- err_abort(status, "cond destroy"); -- status = pthread_mutex_destroy(&f->mutex); -- if (status != 0) -- err_abort(status, "mutex destroy"); -- } -- free(aw); --} -- -- --void *startthread(void *p) --{ -- AsyncRead *aw = (AsyncRead *)p; -- -- //printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim); -- size_t dim = aw->filesdim; -- for (size_t i = 0; i < dim; i++) -- { FileData *f = &aw->files[i]; -- -- f->result = f->file->read(); -- -- // Set event -- int status = pthread_mutex_lock(&f->mutex); -- if (status != 0) -- err_abort(status, "lock mutex"); -- f->value = 1; -- status = pthread_cond_signal(&f->cond); -- if (status != 0) -- err_abort(status, "signal condition"); -- status = pthread_mutex_unlock(&f->mutex); -- if (status != 0) -- err_abort(status, "unlock mutex"); -- } -- -- return NULL; // end thread --} -- --#endif -- --#else -- --#include --#include -- --#include "root.h" -- --struct FileData --{ -- File *file; -- int result; -- //HANDLE event; --}; -- --struct AsyncRead --{ -- static AsyncRead *create(size_t nfiles); -- void addFile(File *file); -- void start(); -- int read(size_t i); -- static void dispose(AsyncRead *); -- -- //HANDLE hThread; -- -- size_t filesdim; -- size_t filesmax; -- FileData files[1]; --}; -- -- --AsyncRead *AsyncRead::create(size_t nfiles) --{ -- AsyncRead *aw = (AsyncRead *)calloc(1, sizeof(AsyncRead) + -- (nfiles - 1) * sizeof(FileData)); -- aw->filesmax = nfiles; -- return aw; --} -- --void AsyncRead::addFile(File *file) --{ -- //printf("addFile(file = %p)\n", file); -- //printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax); -- assert(filesdim < filesmax); -- files[filesdim].file = file; -- //files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL); -- //ResetEvent(files[filesdim].event); -- filesdim++; --} -- --void AsyncRead::start() --{ --} -- --int AsyncRead::read(size_t i) --{ -- FileData *f = &files[i]; -- f->result = f->file->read(); -- return f->result; --} -- --void AsyncRead::dispose(AsyncRead *aw) --{ -- free(aw); --} -- --#endif ---- a/src/gcc/d/dfrontend/async.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/async.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,33 +0,0 @@ -- --// Copyright (c) 2009-2009 by Digital Mars --// All Rights Reserved --// written by Walter Bright --// http://www.digitalmars.com --// License for redistribution is by either the Artistic License --// in artistic.txt, or the GNU General Public License in gnu.txt. --// See the included readme.txt for details. -- --#ifndef ASYNC_H --#define ASYNC_H -- --#if __DMC__ --#pragma once --#endif -- -- --/******************* -- * Simple interface to read files asynchronously in another -- * thread. -- */ -- --struct AsyncRead --{ -- static AsyncRead *create(size_t nfiles); -- void addFile(File *file); -- void start(); -- int read(size_t i); -- static void dispose(AsyncRead *); --}; -- -- --#endif ---- a/src/gcc/d/dfrontend/attrib.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/attrib.c 2014-04-01 16:32:51.000000000 +0100 -@@ -27,6 +27,8 @@ - #include "module.h" - #include "parse.h" - #include "template.h" -+#include "hdrgen.h" -+#include "utf.h" - - - /********************************* AttribDeclaration ****************************/ -@@ -77,7 +79,7 @@ int AttribDeclaration::addMember(Scope * - } - - void AttribDeclaration::setScopeNewSc(Scope *sc, -- StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection, -+ StorageClass stc, LINK linkage, PROT protection, int explicitProtection, - structalign_t structalign) - { - if (decl) -@@ -112,7 +114,7 @@ void AttribDeclaration::setScopeNewSc(Sc - } - - void AttribDeclaration::semanticNewSc(Scope *sc, -- StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection, -+ StorageClass stc, LINK linkage, PROT protection, int explicitProtection, - structalign_t structalign) - { - if (decl) -@@ -202,7 +204,7 @@ void AttribDeclaration::inlineScan() - } - } - --void AttribDeclaration::addComment(unsigned char *comment) -+void AttribDeclaration::addComment(utf8_t *comment) - { - //printf("AttribDeclaration::addComment %s\n", comment); - if (comment) -@@ -257,7 +259,7 @@ void AttribDeclaration::setFieldOffset(A - } - } - --int AttribDeclaration::hasPointers() -+bool AttribDeclaration::hasPointers() - { - Dsymbols *d = include(NULL, NULL); - -@@ -267,10 +269,10 @@ int AttribDeclaration::hasPointers() - { - Dsymbol *s = (*d)[i]; - if (s->hasPointers()) -- return 1; -+ return true; - } - } -- return 0; -+ return false; - } - - bool AttribDeclaration::hasStaticCtorOrDtor() -@@ -294,7 +296,7 @@ const char *AttribDeclaration::kind() - return "attribute"; - } - --int AttribDeclaration::oneMember(Dsymbol **ps, Identifier *ident) -+bool AttribDeclaration::oneMember(Dsymbol **ps, Identifier *ident) - { - Dsymbols *d = include(NULL, NULL); - -@@ -337,6 +339,10 @@ void AttribDeclaration::toCBuffer(OutBuf - { - if (decl->dim == 0) - buf->writestring("{}"); -+ else if (hgs->hdrgen && decl->dim == 1 && (*decl)[0]->isUnitTestDeclaration()) -+ { // hack for bugzilla 8081 -+ buf->writestring("{}"); -+ } - else if (decl->dim == 1) - ((*decl)[0])->toCBuffer(buf, hgs); - else -@@ -376,10 +382,10 @@ Dsymbol *StorageClassDeclaration::syntax - return scd; - } - --int StorageClassDeclaration::oneMember(Dsymbol **ps, Identifier *ident) -+bool StorageClassDeclaration::oneMember(Dsymbol **ps, Identifier *ident) - { - -- int t = Dsymbol::oneMembers(decl, ps, ident); -+ bool t = Dsymbol::oneMembers(decl, ps, ident); - if (t && *ps) - { - /* This is to deal with the following case: -@@ -468,8 +474,8 @@ const char *StorageClassDeclaration::stc - struct SCstring - { - StorageClass stc; -- enum TOK tok; -- Identifier *id; -+ TOK tok; -+ const char *id; - }; - - static SCstring table[] = -@@ -495,13 +501,13 @@ const char *StorageClassDeclaration::stc - { STCnothrow, TOKnothrow }, - { STCpure, TOKpure }, - { STCref, TOKref }, -- { STCtls, TOKtls }, -+ { STCtls }, - { STCgshared, TOKgshared }, -- { STCproperty, TOKat, Id::property }, -- { STCsafe, TOKat, Id::safe }, -- { STCtrusted, TOKat, Id::trusted }, -- { STCsystem, TOKat, Id::system }, -- { STCdisable, TOKat, Id::disable }, -+ { STCproperty, TOKat, "property" }, -+ { STCsafe, TOKat, "safe" }, -+ { STCtrusted, TOKat, "trusted" }, -+ { STCsystem, TOKat, "system" }, -+ { STCdisable, TOKat, "disable" }, - #endif - }; - -@@ -512,12 +518,15 @@ const char *StorageClassDeclaration::stc - if (stc & tbl) - { - stc &= ~tbl; -- enum TOK tok = table[i].tok; -+ if (tbl == STCtls) // TOKtls was removed -+ return "__thread"; -+ -+ TOK tok = table[i].tok; - #if DMDV2 - if (tok == TOKat) - { - tmp[0] = '@'; -- strcpy(tmp + 1, table[i].id->toChars()); -+ strcpy(tmp + 1, table[i].id); - return tmp; - } - else -@@ -536,7 +545,7 @@ void StorageClassDeclaration::stcToCBuff - const char *p = stcToChars(tmp, stc); - if (!p) - break; -- assert(strlen(p) < sizeof(tmp)); -+ assert(strlen(p) < sizeof(tmp) / sizeof(tmp[0])); - buf->writestring(p); - buf->writeByte(' '); - } -@@ -588,7 +597,7 @@ void DeprecatedDeclaration::toCBuffer(Ou - - /********************************* LinkDeclaration ****************************/ - --LinkDeclaration::LinkDeclaration(enum LINK p, Dsymbols *decl) -+LinkDeclaration::LinkDeclaration(LINK p, Dsymbols *decl) - : AttribDeclaration(decl) - { - //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl); -@@ -626,7 +635,7 @@ void LinkDeclaration::semantic3(Scope *s - { - //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl); - if (decl) -- { enum LINK linkage_save = sc->linkage; -+ { LINK linkage_save = sc->linkage; - - sc->linkage = linkage; - for (size_t i = 0; i < decl->dim; i++) -@@ -670,7 +679,7 @@ char *LinkDeclaration::toChars() - - /********************************* ProtDeclaration ****************************/ - --ProtDeclaration::ProtDeclaration(enum PROT p, Dsymbols *decl) -+ProtDeclaration::ProtDeclaration(PROT p, Dsymbols *decl) - : AttribDeclaration(decl) - { - protection = p; -@@ -725,7 +734,7 @@ void ProtDeclaration::semantic(Scope *sc - } - } - --void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection) -+void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, PROT protection) - { - const char *p; - -@@ -790,7 +799,7 @@ void AlignDeclaration::toCBuffer(OutBuff - - /********************************* AnonDeclaration ****************************/ - --AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Dsymbols *decl) -+AnonDeclaration::AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl) - : AttribDeclaration(decl) - { - this->loc = loc; -@@ -956,6 +965,30 @@ void PragmaDeclaration::setScope(Scope * - { - } - -+static unsigned setMangleOverride(Dsymbol *s, char *sym) -+{ -+ AttribDeclaration *ad = s->isAttribDeclaration(); -+ -+ if (ad) -+ { -+ Dsymbols *decls = ad->include(NULL, NULL); -+ unsigned nestedCount = 0; -+ -+ if (decls && decls->dim) -+ for (size_t i = 0; i < decls->dim; ++i) -+ nestedCount += setMangleOverride((*decls)[i], sym); -+ -+ return nestedCount; -+ } -+ else if (s->isFuncDeclaration() || s->isVarDeclaration()) -+ { -+ s->isDeclaration()->mangleOverride = sym; -+ return 1; -+ } -+ else -+ return 0; -+} -+ - void PragmaDeclaration::semantic(Scope *sc) - { // Should be merged with PragmaStatement - -@@ -968,10 +1001,13 @@ void PragmaDeclaration::semantic(Scope * - { - Expression *e = (*args)[i]; - -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -- if (e->op != TOKerror && e->op != TOKtype) -- e = e->ctfeInterpret(); -+ sc = sc->endCTFE(); -+ -+ // pragma(msg) is allowed to contain types as well as expressions -+ e = ctfeInterpretForPragmaMsg(e); - if (e->op == TOKerror) - { errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars()); - return; -@@ -979,12 +1015,12 @@ void PragmaDeclaration::semantic(Scope * - StringExp *se = e->toString(); - if (se) - { -- fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); -+ fprintf(stderr, "%.*s", (int)se->len, (char *)se->string); - } - else -- fprintf(stdmsg, "%s", e->toChars()); -+ fprintf(stderr, "%s", e->toChars()); - } -- fprintf(stdmsg, "\n"); -+ fprintf(stderr, "\n"); - } - goto Lnodecl; - } -@@ -996,8 +1032,11 @@ void PragmaDeclaration::semantic(Scope * - { - Expression *e = (*args)[0]; - -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); -+ - e = e->ctfeInterpret(); - (*args)[0] = e; - if (e->op == TOKerror) -@@ -1005,12 +1044,25 @@ void PragmaDeclaration::semantic(Scope * - StringExp *se = e->toString(); - if (!se) - error("string expected for library name, not '%s'", e->toChars()); -- else if (global.params.verbose) -+ else - { - char *name = (char *)mem.malloc(se->len + 1); - memcpy(name, se->string, se->len); - name[se->len] = 0; -- fprintf(stdmsg, "library %s\n", name); -+ if (global.params.verbose) -+ fprintf(global.stdmsg, "library %s\n", name); -+ if (global.params.moduleDeps && !global.params.moduleDepsFile) -+ { -+ OutBuffer *ob = global.params.moduleDeps; -+ Module* imod = sc->instantiatingModule ? sc->instantiatingModule : sc->module; -+ ob->writestring("depsLib "); -+ ob->writestring(imod->toPrettyChars()); -+ ob->writestring(" ("); -+ escapePath(ob, imod->srcfile->toChars()); -+ ob->writestring(") : "); -+ ob->writestring((char *) name); -+ ob->writenl(); -+ } - mem.free(name); - } - } -@@ -1024,8 +1076,12 @@ void PragmaDeclaration::semantic(Scope * - else - { - Expression *e = (*args)[0]; -+ -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); -+ - e = e->ctfeInterpret(); - (*args)[0] = e; - Dsymbol *sa = getDsymbol(e); -@@ -1035,31 +1091,106 @@ void PragmaDeclaration::semantic(Scope * - goto Lnodecl; - } - #endif -+ else if (ident == Id::mangle) -+ { -+ if (!args || args->dim != 1) -+ error("string expected for mangled name"); -+ else -+ { -+ Expression *e = (*args)[0]; -+ -+ e = e->semantic(sc); -+ e = e->ctfeInterpret(); -+ (*args)[0] = e; -+ -+ if (e->op == TOKerror) -+ goto Lnodecl; -+ -+ StringExp *se = e->toString(); -+ -+ if (!se) -+ { -+ error("string expected for mangled name, not '%s'", e->toChars()); -+ return; -+ } -+ -+ if (!se->len) -+ error("zero-length string not allowed for mangled name"); -+ -+ if (se->sz != 1) -+ error("mangled name characters can only be of type char"); -+ -+#if 1 -+ /* Note: D language specification should not have any assumption about backend -+ * implementation. Ideally pragma(mangle) can accept a string of any content. -+ * -+ * Therefore, this validation is compiler implementation specific. -+ */ -+ for (size_t i = 0; i < se->len; ) -+ { -+ utf8_t *p = (utf8_t *)se->string; -+ dchar_t c = p[i]; -+ if (c < 0x80) -+ { -+ if (c >= 'A' && c <= 'Z' || -+ c >= 'a' && c <= 'z' || -+ c >= '0' && c <= '9' || -+ c != 0 && strchr("$%().:?@[]_", c)) -+ { -+ ++i; -+ continue; -+ } -+ else -+ { -+ error("char 0x%02x not allowed in mangled name", c); -+ break; -+ } -+ } -+ -+ if (const char* msg = utf_decodeChar((utf8_t *)se->string, se->len, &i, &c)) -+ { -+ error("%s", msg); -+ break; -+ } -+ -+ if (!isUniAlpha(c)) -+ { -+ error("char 0x%04x not allowed in mangled name", c); -+ break; -+ } -+ } -+#endif -+ } -+ } - else if (global.params.ignoreUnsupportedPragmas) - { - if (global.params.verbose) - { - /* Print unrecognized pragmas - */ -- fprintf(stdmsg, "pragma %s", ident->toChars()); -+ fprintf(global.stdmsg, "pragma %s", ident->toChars()); - if (args) - { - for (size_t i = 0; i < args->dim; i++) - { - Expression *e = (*args)[i]; -+ -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); -+ - e = e->ctfeInterpret(); - if (i == 0) -- printf(" ("); -+ fprintf(global.stdmsg, " ("); - else -- printf(","); -- printf("%s", e->toChars()); -+ fprintf(global.stdmsg, ","); -+ fprintf(global.stdmsg, "%s", e->toChars()); - } - if (args->dim) -- printf(")"); -+ fprintf(global.stdmsg, ")"); - } -- printf("\n"); -+ fprintf(global.stdmsg, "\n"); - } - goto Lnodecl; - } -@@ -1074,6 +1205,20 @@ Ldecl: - Dsymbol *s = (*decl)[i]; - - s->semantic(sc); -+ -+ if (ident == Id::mangle) -+ { -+ StringExp *e = (*args)[0]->toString(); -+ -+ char *name = (char *)mem.malloc(e->len + 1); -+ memcpy(name, e->string, e->len); -+ name[e->len] = 0; -+ -+ unsigned cnt = setMangleOverride(s, name); -+ -+ if (cnt > 1) -+ error("can only apply to a single declaration"); -+ } - } - } - return; -@@ -1086,10 +1231,10 @@ Lnodecl: - } - } - --int PragmaDeclaration::oneMember(Dsymbol **ps, Identifier *ident) -+bool PragmaDeclaration::oneMember(Dsymbol **ps, Identifier *ident) - { - *ps = NULL; -- return TRUE; -+ return true; - } - - const char *PragmaDeclaration::kind() -@@ -1132,7 +1277,7 @@ Dsymbol *ConditionalDeclaration::syntaxC - } - - --int ConditionalDeclaration::oneMember(Dsymbol **ps, Identifier *ident) -+bool ConditionalDeclaration::oneMember(Dsymbol **ps, Identifier *ident) - { - //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc); - if (condition->inc) -@@ -1140,8 +1285,13 @@ int ConditionalDeclaration::oneMember(Ds - Dsymbols *d = condition->include(NULL, NULL) ? decl : elsedecl; - return Dsymbol::oneMembers(d, ps, ident); - } -- *ps = NULL; -- return TRUE; -+ else -+ { -+ bool res = (Dsymbol::oneMembers( decl, ps, ident) && *ps == NULL && -+ Dsymbol::oneMembers(elsedecl, ps, ident) && *ps == NULL); -+ *ps = NULL; -+ return res; -+ } - } - - void ConditionalDeclaration::emitComment(Scope *sc) -@@ -1205,7 +1355,7 @@ void ConditionalDeclaration::importAll(S - } - } - --void ConditionalDeclaration::addComment(unsigned char *comment) -+void ConditionalDeclaration::addComment(utf8_t *comment) - { - /* Because addComment is called by the parser, if we called - * include() it would define a version before it was used. -@@ -1302,7 +1452,13 @@ Dsymbols *StaticIfDeclaration::include(S - - if (condition->inc == 0) - { -+ /* Bugzilla 10101: Condition evaluation may cause self-recursive -+ * condition evaluation. To resolve it, temporarily save sc into scope. -+ */ -+ bool x = !scope && sc; -+ if (x) scope = sc; - Dsymbols *d = ConditionalDeclaration::include(sc, sd); -+ if (x) scope = NULL; - - // Set the scopes lazily. - if (scope && d) -@@ -1411,6 +1567,9 @@ Dsymbol *CompileDeclaration::syntaxCopy( - int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) - { - //printf("CompileDeclaration::addMember(sc = %p, sd = %p, memnum = %d)\n", sc, sd, memnum); -+ if (compiled) -+ return 1; -+ - this->sd = sd; - if (memnum == 0) - { /* No members yet, so parse the mixin now -@@ -1425,8 +1584,10 @@ int CompileDeclaration::addMember(Scope - void CompileDeclaration::compileIt(Scope *sc) - { - //printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars()); -+ sc = sc->startCTFE(); - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); -+ sc = sc->endCTFE(); - exp = exp->ctfeInterpret(); - StringExp *se = exp->toString(); - if (!se) -@@ -1435,12 +1596,15 @@ void CompileDeclaration::compileIt(Scope - else - { - se = se->toUTF8(sc); -- Parser p(sc->module, (unsigned char *)se->string, se->len, 0); -- p.loc = loc; -+ Parser p(sc->module, (utf8_t *)se->string, se->len, 0); -+ p.scanloc = loc; - p.nextToken(); -+ unsigned errors = global.errors; - decl = p.parseDeclDefs(0); - if (p.token.value != TOKeof) - exp->error("incomplete mixin declaration (%s)", se->toChars()); -+ if (global.errors != errors) -+ decl = NULL; - } - } - -@@ -1533,8 +1697,8 @@ Expressions *UserAttributeDeclaration::c - * (do not append to left operand, as this is a copy-on-write operation) - */ - udas = new Expressions(); -- udas->push(new TupleExp(0, udas1)); -- udas->push(new TupleExp(0, udas2)); -+ udas->push(new TupleExp(Loc(), udas1)); -+ udas->push(new TupleExp(Loc(), udas2)); - } - return udas; - } -@@ -1559,8 +1723,8 @@ void UserAttributeDeclaration::setScope( - { - // Create a tuple that combines them - Expressions *exps = new Expressions(); -- exps->push(new TupleExp(0, newsc->userAttributes)); -- exps->push(new TupleExp(0, atts)); -+ exps->push(new TupleExp(Loc(), newsc->userAttributes)); -+ exps->push(new TupleExp(Loc(), atts)); - newsc->userAttributes = exps; - } - } ---- a/src/gcc/d/dfrontend/attrib.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/attrib.h 2014-04-01 16:32:51.000000000 +0100 -@@ -17,18 +17,19 @@ - - #include "dsymbol.h" - --struct Expression; --struct Statement; --struct LabelDsymbol; --struct Initializer; --struct Module; --struct Condition; -+class Expression; -+class Statement; -+class LabelDsymbol; -+class Initializer; -+class Module; -+class Condition; - struct HdrGenState; - - /**************************************************************/ - --struct AttribDeclaration : Dsymbol -+class AttribDeclaration : public Dsymbol - { -+public: - Dsymbols *decl; // array of Dsymbol's - - AttribDeclaration(Dsymbols *decl); -@@ -36,21 +37,21 @@ struct AttribDeclaration : Dsymbol - int apply(Dsymbol_apply_ft_t fp, void *param); - int addMember(Scope *sc, ScopeDsymbol *s, int memnum); - void setScopeNewSc(Scope *sc, -- StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection, -+ StorageClass newstc, LINK linkage, PROT protection, int explictProtection, - structalign_t structalign); - void semanticNewSc(Scope *sc, -- StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection, -+ StorageClass newstc, LINK linkage, PROT protection, int explictProtection, - structalign_t structalign); - void semantic(Scope *sc); - void semantic2(Scope *sc); - void semantic3(Scope *sc); - void inlineScan(); -- void addComment(unsigned char *comment); -+ void addComment(utf8_t *comment); - void emitComment(Scope *sc); - const char *kind(); -- int oneMember(Dsymbol **ps, Identifier *ident); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); -- int hasPointers(); -+ bool hasPointers(); - bool hasStaticCtorOrDtor(); - void checkCtorConstInit(); - void addLocalClass(ClassDeclarations *); -@@ -61,23 +62,25 @@ struct AttribDeclaration : Dsymbol - void toObjFile(int multiobj); // compile to .obj file - }; - --struct StorageClassDeclaration : AttribDeclaration -+class StorageClassDeclaration : public AttribDeclaration - { -+public: - StorageClass stc; - - StorageClassDeclaration(StorageClass stc, Dsymbols *decl); - Dsymbol *syntaxCopy(Dsymbol *s); - void setScope(Scope *sc); - void semantic(Scope *sc); -- int oneMember(Dsymbol **ps, Identifier *ident); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - static const char *stcToChars(char tmp[], StorageClass& stc); - static void stcToCBuffer(OutBuffer *buf, StorageClass stc); - }; - --struct DeprecatedDeclaration : StorageClassDeclaration -+class DeprecatedDeclaration : public StorageClassDeclaration - { -+public: - Expression *msg; - - DeprecatedDeclaration(Expression *msg, Dsymbols *decl); -@@ -86,11 +89,12 @@ struct DeprecatedDeclaration : StorageCl - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct LinkDeclaration : AttribDeclaration -+class LinkDeclaration : public AttribDeclaration - { -- enum LINK linkage; -+public: -+ LINK linkage; - -- LinkDeclaration(enum LINK p, Dsymbols *decl); -+ LinkDeclaration(LINK p, Dsymbols *decl); - Dsymbol *syntaxCopy(Dsymbol *s); - void setScope(Scope *sc); - void semantic(Scope *sc); -@@ -99,22 +103,24 @@ struct LinkDeclaration : AttribDeclarati - char *toChars(); - }; - --struct ProtDeclaration : AttribDeclaration -+class ProtDeclaration : public AttribDeclaration - { -- enum PROT protection; -+public: -+ PROT protection; - -- ProtDeclaration(enum PROT p, Dsymbols *decl); -+ ProtDeclaration(PROT p, Dsymbols *decl); - Dsymbol *syntaxCopy(Dsymbol *s); - void importAll(Scope *sc); - void setScope(Scope *sc); - void semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - -- static void protectionToCBuffer(OutBuffer *buf, enum PROT protection); -+ static void protectionToCBuffer(OutBuffer *buf, PROT protection); - }; - --struct AlignDeclaration : AttribDeclaration -+class AlignDeclaration : public AttribDeclaration - { -+public: - unsigned salign; - - AlignDeclaration(unsigned sa, Dsymbols *decl); -@@ -124,13 +130,14 @@ struct AlignDeclaration : AttribDeclarat - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct AnonDeclaration : AttribDeclaration -+class AnonDeclaration : public AttribDeclaration - { -+public: - bool isunion; - structalign_t alignment; - int sem; // 1 if successful semantic() - -- AnonDeclaration(Loc loc, int isunion, Dsymbols *decl); -+ AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl); - Dsymbol *syntaxCopy(Dsymbol *s); - void semantic(Scope *sc); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); -@@ -138,39 +145,42 @@ struct AnonDeclaration : AttribDeclarati - const char *kind(); - }; - --struct PragmaDeclaration : AttribDeclaration -+class PragmaDeclaration : public AttribDeclaration - { -+public: - Expressions *args; // array of Expression's - - PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl); - Dsymbol *syntaxCopy(Dsymbol *s); - void semantic(Scope *sc); - void setScope(Scope *sc); -- int oneMember(Dsymbol **ps, Identifier *ident); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - const char *kind(); - void toObjFile(int multiobj); // compile to .obj file - }; - --struct ConditionalDeclaration : AttribDeclaration -+class ConditionalDeclaration : public AttribDeclaration - { -+public: - Condition *condition; - Dsymbols *elsedecl; // array of Dsymbol's for else block - - ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl); - Dsymbol *syntaxCopy(Dsymbol *s); -- int oneMember(Dsymbol **ps, Identifier *ident); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - void emitComment(Scope *sc); - Dsymbols *include(Scope *sc, ScopeDsymbol *s); -- void addComment(unsigned char *comment); -+ void addComment(utf8_t *comment); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void toJson(JsonOut *json); - void importAll(Scope *sc); - void setScope(Scope *sc); - }; - --struct StaticIfDeclaration : ConditionalDeclaration -+class StaticIfDeclaration : public ConditionalDeclaration - { -+public: - ScopeDsymbol *sd; - int addisdone; - -@@ -186,8 +196,9 @@ struct StaticIfDeclaration : Conditional - - // Mixin declarations - --struct CompileDeclaration : AttribDeclaration -+class CompileDeclaration : public AttribDeclaration - { -+public: - Expression *exp; - - ScopeDsymbol *sd; -@@ -206,8 +217,9 @@ struct CompileDeclaration : AttribDeclar - * User defined attributes look like: - * [ args, ... ] - */ --struct UserAttributeDeclaration : AttribDeclaration -+class UserAttributeDeclaration : public AttribDeclaration - { -+public: - Expressions *atts; - - UserAttributeDeclaration(Expressions *atts, Dsymbols *decl); ---- a/src/gcc/d/dfrontend/builtin.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/builtin.c 2014-04-01 16:32:51.000000000 +0100 -@@ -30,7 +30,7 @@ - * Determine if function is a builtin one that we can - * evaluate at compile time. - */ --enum BUILTIN FuncDeclaration::isBuiltin() -+BUILTIN FuncDeclaration::isBuiltin() - { - static const char FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real) - static const char FeZe2[] = "FNaNbNeeZe"; // @trusted pure nothrow real function(real) -@@ -165,7 +165,7 @@ uinteger_t eval_bswap(Expression *arg0) - * Return result; NULL if cannot evaluate it. - */ - --Expression *eval_builtin(Loc loc, enum BUILTIN builtin, Expressions *arguments) -+Expression *eval_builtin(Loc loc, BUILTIN builtin, Expressions *arguments) - { - assert(arguments && arguments->dim); - Expression *arg0 = (*arguments)[0]; -@@ -174,27 +174,27 @@ Expression *eval_builtin(Loc loc, enum B - { - case BUILTINsin: - if (arg0->op == TOKfloat64) -- e = new RealExp(0, sinl(arg0->toReal()), arg0->type); -+ e = new RealExp(Loc(), sinl(arg0->toReal()), arg0->type); - break; - - case BUILTINcos: - if (arg0->op == TOKfloat64) -- e = new RealExp(0, cosl(arg0->toReal()), arg0->type); -+ e = new RealExp(Loc(), cosl(arg0->toReal()), arg0->type); - break; - - case BUILTINtan: - if (arg0->op == TOKfloat64) -- e = new RealExp(0, tanl(arg0->toReal()), arg0->type); -+ e = new RealExp(Loc(), tanl(arg0->toReal()), arg0->type); - break; - - case BUILTINsqrt: - if (arg0->op == TOKfloat64) -- e = new RealExp(0, sqrtl(arg0->toReal()), arg0->type); -+ e = new RealExp(Loc(), sqrtl(arg0->toReal()), arg0->type); - break; - - case BUILTINfabs: - if (arg0->op == TOKfloat64) -- e = new RealExp(0, fabsl(arg0->toReal()), arg0->type); -+ e = new RealExp(Loc(), fabsl(arg0->toReal()), arg0->type); - break; - // These math intrinsics are not yet implemented - case BUILTINatan2: ---- a/src/gcc/d/dfrontend/canthrow.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/canthrow.c 2014-04-01 16:32:51.000000000 +0100 -@@ -56,14 +56,15 @@ int lambdaCanThrow(Expression *e, void * - switch (e->op) - { - case TOKdeclaration: -- { DeclarationExp *de = (DeclarationExp *)e; -+ { -+ DeclarationExp *de = (DeclarationExp *)e; - pct->can = Dsymbol_canThrow(de->declaration, pct->mustnot); - break; - } - - case TOKcall: -- { CallExp *ce = (CallExp *)e; -- -+ { -+ CallExp *ce = (CallExp *)e; - if (global.errors && !ce->e1->type) - break; // error recovery - -@@ -79,14 +80,15 @@ int lambdaCanThrow(Expression *e, void * - else - { - if (pct->mustnot) -- e->error("%s is not nothrow", ce->e1->toChars()); -+ e->error("'%s' is not nothrow", ce->f ? ce->f->toPrettyChars() : ce->e1->toChars()); - pct->can = TRUE; - } - break; - } - - case TOKnew: -- { NewExp *ne = (NewExp *)e; -+ { -+ NewExp *ne = (NewExp *)e; - if (ne->member) - { - // See if constructor call can throw -@@ -102,6 +104,33 @@ int lambdaCanThrow(Expression *e, void * - break; - } - -+ case TOKassign: -+ case TOKconstruct: -+ { -+ /* Element-wise assignment could invoke postblits. -+ */ -+ AssignExp *ae = (AssignExp *)e; -+ if (ae->e1->op != TOKslice) -+ break; -+ -+ Type *tv = ae->e1->type->toBasetype()->nextOf()->baseElemOf(); -+ if (tv->ty != Tstruct) -+ break; -+ StructDeclaration *sd = ((TypeStruct *)tv)->sym; -+ if (!sd->postblit || sd->postblit->type->ty != Tfunction) -+ break; -+ -+ if (((TypeFunction *)sd->postblit->type)->isnothrow) -+ ; -+ else -+ { -+ if (pct->mustnot) -+ e->error("'%s' is not nothrow", sd->postblit->toPrettyChars()); -+ pct->can = TRUE; -+ } -+ break; -+ } -+ - case TOKnewanonclass: - assert(0); // should have been lowered by semantic() - break; -@@ -175,7 +204,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mu - else if ((td = s->isTupleDeclaration()) != NULL) - { - for (size_t i = 0; i < td->objects->dim; i++) -- { Object *o = (*td->objects)[i]; -+ { RootObject *o = (*td->objects)[i]; - if (o->dyncast() == DYNCAST_EXPRESSION) - { Expression *eo = (Expression *)o; - if (eo->op == TOKdsymbol) ---- a/src/gcc/d/dfrontend/cast.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/cast.c 2014-04-01 16:32:51.000000000 +0100 -@@ -20,6 +20,7 @@ - #include "aggregate.h" - #include "template.h" - #include "scope.h" -+#include "id.h" - - //#define DUMP .dump(__PRETTY_FUNCTION__, this) - #define DUMP -@@ -162,7 +163,7 @@ MATCH Expression::implicitConvTo(Type *t - type = Type::terror; - } - Expression *e = optimize(WANTvalue | WANTflags); -- if (e->type == t) -+ if (e->type->equals(t)) - return MATCHexact; - if (e != this) - { //printf("\toptimized to %s of type %s\n", e->toChars(), e->type->toChars()); -@@ -280,7 +281,11 @@ MATCH IntegerExp::implicitConvTo(Type *t - goto Lyes; - - case Tint8: -- if ((signed char)value != value) -+ if (ty == Tuns64 && value & ~0x7FUL) -+ goto Lno; -+ //else if (ty == Tint64 && 0x7FUL < value && value < ~0x7FUL) -+ // goto Lno; -+ else if ((signed char)value != value) - goto Lno; - goto Lyes; - -@@ -294,7 +299,11 @@ MATCH IntegerExp::implicitConvTo(Type *t - goto Lyes; - - case Tint16: -- if ((short)value != value) -+ if (ty == Tuns64 && value & ~0x7FFFUL) -+ goto Lno; -+ //else if (ty == Tint64 && 0x7FFFUL < value && value < ~0x7FFFUL) -+ // goto Lno; -+ else if ((short)value != value) - goto Lno; - goto Lyes; - -@@ -310,6 +319,10 @@ MATCH IntegerExp::implicitConvTo(Type *t - if (ty == Tuns32) - { - } -+ else if (ty == Tuns64 && value & ~0x7FFFFFFFUL) -+ goto Lno; -+ //else if (ty == Tint64 && 0x7FFFFFFFUL < value && value < ~0x7FFFFFFFUL) -+ // goto Lno; - else if ((int)value != value) - goto Lno; - goto Lyes; -@@ -327,27 +340,6 @@ MATCH IntegerExp::implicitConvTo(Type *t - goto Lno; - goto Lyes; - --#ifdef IN_GCC -- case Tfloat32: -- case Tfloat64: -- case Tfloat80: -- { -- real_t f; -- if (type->isunsigned()) -- { -- f = real_t((d_uns64) value); -- if ((d_uns64) f.toInt() != (d_uns64) value) -- goto Lno; -- } -- else -- { -- f = real_t((d_int64) value); -- if ((d_int64) f.toInt() != (d_int64) value) -- goto Lno; -- } -- goto Lyes; -- } --#else - case Tfloat32: - { - volatile float f; -@@ -359,8 +351,8 @@ MATCH IntegerExp::implicitConvTo(Type *t - } - else - { -- f = (float)(long long)value; -- if (f != (long long)value) -+ f = (float)(sinteger_t)value; -+ if (f != (sinteger_t)value) - goto Lno; - } - goto Lyes; -@@ -377,8 +369,8 @@ MATCH IntegerExp::implicitConvTo(Type *t - } - else - { -- f = (double)(long long)value; -- if (f != (long long)value) -+ f = (double)(sinteger_t)value; -+ if (f != (sinteger_t)value) - goto Lno; - } - goto Lyes; -@@ -395,13 +387,13 @@ MATCH IntegerExp::implicitConvTo(Type *t - } - else - { -- f = ldouble((long long)value); -- if (f != (long long)value) -+ f = ldouble((sinteger_t)value); -+ if (f != (sinteger_t)value) - goto Lno; - } - goto Lyes; - } --#endif -+ - case Tpointer: - //printf("type = %s\n", type->toBasetype()->toChars()); - //printf("t = %s\n", t->toBasetype()->toChars()); -@@ -426,6 +418,11 @@ Lno: - return MATCHnomatch; - } - -+MATCH ErrorExp::implicitConvTo(Type *t) -+{ -+ return MATCHnomatch; -+} -+ - MATCH NullExp::implicitConvTo(Type *t) - { - #if 0 -@@ -439,7 +436,7 @@ MATCH NullExp::implicitConvTo(Type *t) - * and mutable to immutable. It works because, after all, a null - * doesn't actually point to anything. - */ -- if (t->invariantOf()->equals(type->invariantOf())) -+ if (t->immutableOf()->equals(type->immutableOf())) - return MATCHconst; - - return Expression::implicitConvTo(t); -@@ -460,9 +457,12 @@ MATCH StructLiteralExp::implicitConvTo(T - { - m = MATCHconst; - for (size_t i = 0; i < elements->dim; i++) -- { Expression *e = (*elements)[i]; -+ { -+ Expression *e = (*elements)[i]; -+ if (!e) -+ continue; - Type *te = e->type; -- te = te->castMod(t->mod); -+ te = sd->fields[i]->type->addMod(t->mod); - MATCH m2 = e->implicitConvTo(te); - //printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2); - if (m2 < m) -@@ -659,8 +659,35 @@ MATCH CallExp::implicitConvTo(Type *t) - /* Allow the result of strongly pure functions to - * convert to immutable - */ -- if (f && f->isPure() == PUREstrong && !f->type->hasWild()) -- return type->invariantOf()->implicitConvTo(t); -+ if (f && f->isolateReturn()) -+ return type->immutableOf()->implicitConvTo(t); -+ -+ /* The result of arr.dup and arr.idup can be unique essentially. -+ * So deal with this case specially. -+ */ -+ if (!f && e1->op == TOKvar && ((VarExp *)e1)->var->ident == Id::adDup && -+ t->toBasetype()->ty == Tarray) -+ { -+ assert(type->toBasetype()->ty == Tarray); -+ assert(arguments->dim == 2); -+ Expression *eorg = (*arguments)[1]; -+ Type *tn = t->nextOf(); -+ if (type->nextOf()->implicitConvTo(tn) < MATCHconst) -+ { -+ /* If the operand is an unique array literal, then allow conversion. -+ */ -+ if (eorg->op != TOKarrayliteral) -+ return MATCHnomatch; -+ Expressions *elements = ((ArrayLiteralExp *)eorg)->elements; -+ for (size_t i = 0; i < elements->dim; i++) -+ { -+ if (!(*elements)[i]->implicitConvTo(tn)) -+ return MATCHnomatch; -+ } -+ } -+ m = type->immutableOf()->implicitConvTo(t); -+ return m; -+ } - - return MATCHnomatch; - } -@@ -990,10 +1017,43 @@ MATCH NewExp::implicitConvTo(Type *t) - return MATCHnomatch; - } - -+Type *SliceExp::toStaticArrayType() -+{ -+ if (lwr && upr) -+ { -+ Expression *lwr = this->lwr->optimize(WANTvalue); -+ Expression *upr = this->upr->optimize(WANTvalue); -+ if (lwr->isConst() && upr->isConst()) -+ { -+ size_t len = upr->toUInteger() - lwr->toUInteger(); -+ return TypeSArray::makeType(loc, type->toBasetype()->nextOf(), len); -+ } -+ } -+ return NULL; -+} -+ -+MATCH SliceExp::implicitConvTo(Type *t) -+{ -+ MATCH result = Expression::implicitConvTo(t); -+ -+ Type *tb = t->toBasetype(); -+ Type *typeb = type->toBasetype(); -+ if (result == MATCHnomatch && -+ tb->ty == Tsarray && typeb->ty == Tarray && -+ lwr && upr) -+ { -+ typeb = toStaticArrayType(); -+ if (typeb) -+ result = typeb->implicitConvTo(t); -+ } -+ return result; -+} -+ - /* ==================== castTo ====================== */ - - /************************************** - * Do an explicit cast. -+ * Assume that the 'this' expression does not have any indirections. - */ - - Expression *Expression::castTo(Scope *sc, Type *t) -@@ -1003,12 +1063,21 @@ Expression *Expression::castTo(Scope *sc - printf("Expression::castTo(this=%s, type=%s, t=%s)\n", - toChars(), type->toChars(), t->toChars()); - #endif -- if (type == t) -+ if (type->equals(t)) - return this; -+ if (op == TOKvar) -+ { -+ VarDeclaration *v = ((VarExp *)this)->var->isVarDeclaration(); -+ if (v && v->storage_class & STCmanifest) -+ { -+ Expression *e = ctfeInterpret(); -+ return e->castTo(sc, t); -+ } -+ } - Expression *e = this; - Type *tb = t->toBasetype(); - Type *typeb = type->toBasetype(); -- if (tb != typeb) -+ if (!tb->equals(typeb)) - { - // Do (type *) cast of (type [dim]) - if (tb->ty == Tpointer && -@@ -1076,7 +1145,7 @@ Expression *Expression::castTo(Scope *sc - e = e->semantic(sc); - return e; - } -- else if (typeb->implicitConvTo(tb) == MATCHconst && t == type->constOf()) -+ else if (typeb->implicitConvTo(tb) == MATCHconst && t->equals(type->constOf())) - { - Expression *e = copy(); - e->type = t; -@@ -1103,8 +1172,9 @@ Expression *ErrorExp::castTo(Scope *sc, - - - Expression *RealExp::castTo(Scope *sc, Type *t) --{ Expression *e = this; -- if (type != t) -+{ -+ Expression *e = this; -+ if (!type->equals(t)) - { - if ((type->isreal() && t->isreal()) || - (type->isimaginary() && t->isimaginary()) -@@ -1120,8 +1190,9 @@ Expression *RealExp::castTo(Scope *sc, T - - - Expression *ComplexExp::castTo(Scope *sc, Type *t) --{ Expression *e = this; -- if (type != t) -+{ -+ Expression *e = this; -+ if (!type->equals(t)) - { - if (type->iscomplex() && t->iscomplex()) - { e = copy(); -@@ -1136,8 +1207,8 @@ Expression *ComplexExp::castTo(Scope *sc - - Expression *NullExp::castTo(Scope *sc, Type *t) - { -- //printf("NullExp::castTo(t = %p)\n", t); -- if (type == t) -+ //printf("NullExp::castTo(t = %s) %s\n", t->toChars(), toChars()); -+ if (type->equals(t)) - { - committed = 1; - return this; -@@ -1148,7 +1219,7 @@ Expression *NullExp::castTo(Scope *sc, T - Type *tb = t->toBasetype(); - #if 0 - e->type = type->toBasetype(); -- if (tb != e->type) -+ if (!tb->equals(e->type)) - { - // NULL implicitly converts to any pointer type or dynamic array - if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && -@@ -1179,10 +1250,22 @@ Expression *NullExp::castTo(Scope *sc, T - return e->Expression::castTo(sc, t); - } - #endif -+ if (tb->ty == Tsarray || tb->ty == Tstruct) -+ { -+ error("cannot cast null to %s", t->toChars()); -+ } - e->type = t; - return e; - } - -+Expression *StructLiteralExp::castTo(Scope *sc, Type *t) -+{ -+ Expression *e = Expression::castTo(sc, t); -+ if (e->op == TOKstructliteral) -+ ((StructLiteralExp *)e)->stype = t; // commit type -+ return e; -+} -+ - Expression *StringExp::castTo(Scope *sc, Type *t) - { - /* This follows copy-on-write; any changes to 'this' -@@ -1206,7 +1289,7 @@ Expression *StringExp::castTo(Scope *sc, - copied = 1; - } - -- if (type == t) -+ if (type->equals(t)) - { - return se; - } -@@ -1217,7 +1300,7 @@ Expression *StringExp::castTo(Scope *sc, - return Expression::castTo(sc, t); - - Type *typeb = type->toBasetype(); -- if (typeb == tb) -+ if (typeb->equals(tb)) - { - if (!copied) - { se = (StringExp *)copy(); -@@ -1236,6 +1319,16 @@ Expression *StringExp::castTo(Scope *sc, - se->len = (len * sz) / se->sz; - se->committed = 1; - se->type = t; -+ -+ /* Assure space for terminating 0 -+ */ -+ if ((se->len + 1) * se->sz > (len + 1) * sz) -+ { -+ void *s = (void *)mem.malloc((se->len + 1) * se->sz); -+ memcpy(s, se->string, se->len * se->sz); -+ memset((char *)s + se->len * se->sz, 0, se->sz); -+ se->string = s; -+ } - return se; - } - -@@ -1285,7 +1378,7 @@ Expression *StringExp::castTo(Scope *sc, - case X(Tchar, Twchar): - for (size_t u = 0; u < len;) - { unsigned c; -- const char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c); -+ const char *p = utf_decodeChar((utf8_t *)se->string, len, &u, &c); - if (p) - error("%s", p); - else -@@ -1298,7 +1391,7 @@ Expression *StringExp::castTo(Scope *sc, - case X(Tchar, Tdchar): - for (size_t u = 0; u < len;) - { unsigned c; -- const char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c); -+ const char *p = utf_decodeChar((utf8_t *)se->string, len, &u, &c); - if (p) - error("%s", p); - buffer.write4(c); -@@ -1397,7 +1490,7 @@ L2: - // Copy when changing the string literal - size_t newsz = se->sz; - size_t d = (dim2 < se->len) ? dim2 : se->len; -- void *s = (unsigned char *)mem.malloc((dim2 + 1) * newsz); -+ void *s = (void *)mem.malloc((dim2 + 1) * newsz); - memcpy(s, se->string, d * newsz); - // Extend with 0, add terminating 0 - memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz); -@@ -1426,7 +1519,7 @@ Expression *AddrExp::castTo(Scope *sc, T - - tb = t->toBasetype(); - type = type->toBasetype(); -- if (tb != type) -+ if (!tb->equals(type)) - { - // Look for pointers to functions where the functions are overloaded. - -@@ -1486,7 +1579,12 @@ Expression *AddrExp::castTo(Scope *sc, T - - - Expression *TupleExp::castTo(Scope *sc, Type *t) --{ TupleExp *e = (TupleExp *)copy(); -+{ -+ if (type->equals(t)) -+ return this; -+ -+ TupleExp *e = (TupleExp *)copy(); -+ e->e0 = e0 ? e0->copy() : NULL; - e->exps = (Expressions *)exps->copy(); - for (size_t i = 0; i < e->exps->dim; i++) - { Expression *ex = (*e->exps)[i]; -@@ -1511,7 +1609,9 @@ Expression *ArrayLiteralExp::castTo(Scop - if ((tb->ty == Tarray || tb->ty == Tsarray) && - (typeb->ty == Tarray || typeb->ty == Tsarray) && - // Not trying to convert non-void[] to void[] -- !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid)) -+ !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid) && -+ // Not trying to convert void[n] to others -+ !(typeb->ty == Tsarray && typeb->nextOf()->toBasetype()->ty == Tvoid)) - { - if (tb->ty == Tsarray) - { TypeSArray *tsa = (TypeSArray *)tb; -@@ -1598,12 +1698,12 @@ Expression *SymOffExp::castTo(Scope *sc, - printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", - toChars(), type->toChars(), t->toChars()); - #endif -- if (type == t && hasOverloads == 0) -+ if (type == t && !hasOverloads) - return this; - Expression *e; - Type *tb = t->toBasetype(); - Type *typeb = type->toBasetype(); -- if (tb != typeb) -+ if (!tb->equals(typeb)) - { - // Look for pointers to functions where the functions are overloaded. - FuncDeclaration *f; -@@ -1656,7 +1756,7 @@ Expression *SymOffExp::castTo(Scope *sc, - else - { e = copy(); - e->type = t; -- ((SymOffExp *)e)->hasOverloads = 0; -+ ((SymOffExp *)e)->hasOverloads = false; - } - return e; - } -@@ -1667,12 +1767,12 @@ Expression *DelegateExp::castTo(Scope *s - printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", - toChars(), type->toChars(), t->toChars()); - #endif -- static char msg[] = "cannot form delegate due to covariant return type"; -+ static const char msg[] = "cannot form delegate due to covariant return type"; - - Expression *e = this; - Type *tb = t->toBasetype(); - Type *typeb = type->toBasetype(); -- if (tb != typeb || hasOverloads) -+ if (!tb->equals(typeb) || hasOverloads) - { - // Look for delegates to functions where the functions are overloaded. - FuncDeclaration *f; -@@ -1717,14 +1817,15 @@ Expression *FuncExp::castTo(Scope *sc, T - if (e) - { - if (e != this) -- e = e->castTo(sc, t); -- else if (!e->type->equals(t)) -+ return e->castTo(sc, t); -+ if (!e->type->equals(t) && e->type->implicitConvTo(t)) - { -- assert(e->type->nextOf()->covariant(t->nextOf()) == 1); -+ assert(t->ty == Tpointer && t->nextOf()->ty == Tvoid || // Bugzilla 9928 -+ e->type->nextOf()->covariant(t->nextOf()) == 1); - e = e->copy(); - e->type = t; -+ return e; - } -- return e; - } - return Expression::castTo(sc, t); - } -@@ -1733,7 +1834,7 @@ Expression *CondExp::castTo(Scope *sc, T - { - Expression *e = this; - -- if (type != t) -+ if (!type->equals(t)) - { - if (1 || e1->op == TOKstring || e2->op == TOKstring) - { e = new CondExp(loc, econd, e1->castTo(sc, t), e2->castTo(sc, t)); -@@ -1762,19 +1863,50 @@ Expression *CommaExp::castTo(Scope *sc, - return e; - } - -+Expression *SliceExp::castTo(Scope *sc, Type *t) -+{ -+ Type *typeb = type->toBasetype(); -+ Type *tb = t->toBasetype(); -+ Expression *e; -+ if (typeb->ty == Tarray && tb->ty == Tsarray) -+ { -+ /* If a SliceExp has Tsarray, it will become lvalue. -+ * That's handled in SliceExp::isLvalue and toLvalue -+ */ -+ e = copy(); -+ e->type = t; -+ } -+ else if (typeb->ty == Tarray && tb->ty == Tarray && -+ typeb->nextOf()->constConv(tb->nextOf()) == MATCHconst) -+ { -+ // immutable(T)[] to const(T)[] -+ // T [] to const(T)[] -+ e = copy(); -+ e->type = t; -+ } -+ else -+ { -+ e = Expression::castTo(sc, t); -+ } -+ return e; -+} -+ - /* ==================== inferType ====================== */ - - /**************************************** - * Set type inference target -+ * t Target type - * flag 1: don't put an error when inference fails -+ * sc it is used for the semantic of t, when != NULL -+ * tparams template parameters should be inferred - */ - --Expression *Expression::inferType(Type *t, int flag, TemplateParameters *tparams) -+Expression *Expression::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) - { - return this; - } - --Expression *ArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tparams) -+Expression *ArrayLiteralExp::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) - { - if (t) - { -@@ -1785,7 +1917,7 @@ Expression *ArrayLiteralExp::inferType(T - for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (*elements)[i]; - if (e) -- { e = e->inferType(tn, flag, tparams); -+ { e = e->inferType(tn, flag, sc, tparams); - (*elements)[i] = e; - } - } -@@ -1794,7 +1926,7 @@ Expression *ArrayLiteralExp::inferType(T - return this; - } - --Expression *AssocArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tparams) -+Expression *AssocArrayLiteralExp::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) - { - if (t) - { -@@ -1806,14 +1938,14 @@ Expression *AssocArrayLiteralExp::inferT - for (size_t i = 0; i < keys->dim; i++) - { Expression *e = (*keys)[i]; - if (e) -- { e = e->inferType(ti, flag, tparams); -+ { e = e->inferType(ti, flag, sc, tparams); - (*keys)[i] = e; - } - } - for (size_t i = 0; i < values->dim; i++) - { Expression *e = (*values)[i]; - if (e) -- { e = e->inferType(tv, flag, tparams); -+ { e = e->inferType(tv, flag, sc, tparams); - (*values)[i] = e; - } - } -@@ -1822,7 +1954,7 @@ Expression *AssocArrayLiteralExp::inferT - return this; - } - --Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams) -+Expression *FuncExp::inferType(Type *to, int flag, Scope *sc, TemplateParameters *tparams) - { - if (!to) - return this; -@@ -1880,7 +2012,10 @@ Expression *FuncExp::inferType(Type *to, - Type *tprm = p->type; - if (tprm->reliesOnTident(tparams)) - goto L1; -- tprm = tprm->semantic(loc, td->scope); -+ if (sc) -+ tprm = tprm->semantic(loc, sc); -+ if (tprm->ty == Terror) -+ goto L1; - tiargs->push(tprm); - u = dim; // break inner loop - } -@@ -1936,13 +2071,13 @@ L1: - return e; - } - --Expression *CondExp::inferType(Type *t, int flag, TemplateParameters *tparams) -+Expression *CondExp::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) - { - if (t) - { - t = t->toBasetype(); -- e1 = e1->inferType(t, flag, tparams); -- e2 = e2->inferType(t, flag, tparams); -+ e1 = e1->inferType(t, flag, sc, tparams); -+ e2 = e2->inferType(t, flag, sc, tparams); - } - return this; - } -@@ -1969,7 +2104,7 @@ Expression *BinExp::scaleFactor(Scope *s - if (!t->equals(t2b)) - e2 = e2->castTo(sc, t); - eoff = e2; -- e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t)); -+ e2 = new MulExp(loc, e2, new IntegerExp(Loc(), stride, t)); - e2->type = t; - type = e1->type; - } -@@ -1985,7 +2120,7 @@ Expression *BinExp::scaleFactor(Scope *s - else - e = e1; - eoff = e; -- e = new MulExp(loc, e, new IntegerExp(0, stride, t)); -+ e = new MulExp(loc, e, new IntegerExp(Loc(), stride, t)); - e->type = t; - type = e2->type; - e1 = e2; -@@ -2070,6 +2205,14 @@ int typeMerge(Scope *sc, Expression *e, - assert(t1); - Type *t = t1; - -+ /* The start type of alias this type recursion. -+ * In following case, we should save A, and stop recursion -+ * if it appears again. -+ * X -> Y -> [A] -> B -> A -> B -> ... -+ */ -+ Type *att1 = NULL; -+ Type *att2 = NULL; -+ - //if (t1) printf("\tt1 = %s\n", t1->toChars()); - //if (t2) printf("\tt2 = %s\n", t2->toChars()); - #ifdef DEBUG -@@ -2089,13 +2232,13 @@ Lagain: - - if (t1b->ty == ty1) // if no promotions - { -- if (t1 == t2) -+ if (t1->equals(t2)) - { - t = t1; - goto Lret; - } - -- if (t1b == t2b) -+ if (t1b->equals(t2b)) - { - t = t1b; - goto Lret; -@@ -2117,8 +2260,14 @@ Lagain: - t1 = t1b; - t2 = t2b; - -- if (t1 == t2) -+ if (t1->ty == Ttuple || t2->ty == Ttuple) -+ goto Lincompatible; -+ -+ if (t1->equals(t2)) - { -+ // merging can not result in new enum type -+ if (t->ty == Tenum) -+ t = t1b; - } - else if ((t1->ty == Tpointer && t2->ty == Tpointer) || - (t1->ty == Tdelegate && t2->ty == Tdelegate)) -@@ -2127,7 +2276,7 @@ Lagain: - Type *t1n = t1->nextOf(); - Type *t2n = t2->nextOf(); - -- if (t1n == t2n) -+ if (t1n->equals(t2n)) - ; - else if (t1n->ty == Tvoid) // pointers to void are always compatible - t = t2; -@@ -2373,12 +2522,22 @@ Lcc: - } - else if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis) - { -+ if (att1 && e1->type == att1) -+ goto Lincompatible; -+ if (!att1 && e1->type->checkAliasThisRec()) -+ att1 = e1->type; -+ //printf("att tmerge(c || c) e1 = %s\n", e1->type->toChars()); - e1 = resolveAliasThis(sc, e1); - t1 = e1->type; - continue; - } - else if (t2->ty == Tstruct && ((TypeStruct *)t2)->sym->aliasthis) - { -+ if (att2 && e2->type == att2) -+ goto Lincompatible; -+ if (!att2 && e2->type->checkAliasThisRec()) -+ att2 = e2->type; -+ //printf("att tmerge(c || c) e2 = %s\n", e2->type->toChars()); - e2 = resolveAliasThis(sc, e2); - t2 = e2->type; - continue; -@@ -2414,11 +2573,21 @@ Lcc: - Expression *e2b = NULL; - if (ts2->sym->aliasthis) - { -+ if (att2 && e2->type == att2) -+ goto Lincompatible; -+ if (!att2 && e2->type->checkAliasThisRec()) -+ att2 = e2->type; -+ //printf("att tmerge(s && s) e2 = %s\n", e2->type->toChars()); - e2b = resolveAliasThis(sc, e2); - i1 = e2b->implicitConvTo(t1); - } - if (ts1->sym->aliasthis) - { -+ if (att1 && e1->type == att1) -+ goto Lincompatible; -+ if (!att1 && e1->type->checkAliasThisRec()) -+ att1 = e1->type; -+ //printf("att tmerge(s && s) e1 = %s\n", e1->type->toChars()); - e1b = resolveAliasThis(sc, e1); - i2 = e1b->implicitConvTo(t2); - } -@@ -2446,6 +2615,11 @@ Lcc: - { - if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis) - { -+ if (att1 && e1->type == att1) -+ goto Lincompatible; -+ if (!att1 && e1->type->checkAliasThisRec()) -+ att1 = e1->type; -+ //printf("att tmerge(s || s) e1 = %s\n", e1->type->toChars()); - e1 = resolveAliasThis(sc, e1); - t1 = e1->type; - t = t1; -@@ -2453,6 +2627,11 @@ Lcc: - } - if (t2->ty == Tstruct && ((TypeStruct *)t2)->sym->aliasthis) - { -+ if (att2 && e2->type == att2) -+ goto Lincompatible; -+ if (!att2 && e2->type->checkAliasThisRec()) -+ att2 = e2->type; -+ //printf("att tmerge(s || s) e2 = %s\n", e2->type->toChars()); - e2 = resolveAliasThis(sc, e2); - t2 = e2->type; - t = t2; -@@ -2595,6 +2774,11 @@ Expression *BinExp::typeCombine(Scope *s - - if (!typeMerge(sc, this, &type, &e1, &e2)) - goto Lerror; -+ // If the types have no value, return an error -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - return this; - - Lerror: -@@ -2634,6 +2818,8 @@ Expression *Expression::integralPromotio - case Tdchar: - e = e->castTo(sc, Type::tuns32); - break; -+ default: -+ break; - } - return e; - } -@@ -2648,8 +2834,8 @@ Expression *Expression::integralPromotio - - int arrayTypeCompatible(Loc loc, Type *t1, Type *t2) - { -- t1 = t1->toBasetype(); -- t2 = t2->toBasetype(); -+ t1 = t1->toBasetype()->merge2(); -+ t2 = t2->toBasetype()->merge2(); - - if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && - (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) -@@ -2712,7 +2898,7 @@ IntRange Expression::getIntRange() - - IntRange IntegerExp::getIntRange() - { -- return IntRange(value).cast(type) DUMP; -+ return IntRange(SignExtendedNumber(value)).cast(type) DUMP; - } - - IntRange CastExp::getIntRange() ---- a/src/gcc/d/dfrontend/class.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/class.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -32,16 +32,15 @@ - - /********************************* ClassDeclaration ****************************/ - --ClassDeclaration *ClassDeclaration::classinfo; - ClassDeclaration *ClassDeclaration::object; - ClassDeclaration *ClassDeclaration::throwable; - ClassDeclaration *ClassDeclaration::exception; - ClassDeclaration *ClassDeclaration::errorException; - --ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses) -+ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, bool inObject) - : AggregateDeclaration(loc, id) - { -- static char msg[] = "only object.d can define this reserved class name"; -+ static const char msg[] = "only object.d can define this reserved class name"; - - if (baseclasses) - // Actually, this is a transfer -@@ -77,158 +76,160 @@ ClassDeclaration::ClassDeclaration(Loc l - if (id->toChars()[0] == 'T') - { - if (id == Id::TypeInfo) -- { if (Type::typeinfo) -- Type::typeinfo->error("%s", msg); -- Type::typeinfo = this; -+ { if (!inObject) -+ error("%s", msg); -+ Type::dtypeinfo = this; - } - - if (id == Id::TypeInfo_Class) -- { if (Type::typeinfoclass) -- Type::typeinfoclass->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfoclass = this; - } - - if (id == Id::TypeInfo_Interface) -- { if (Type::typeinfointerface) -- Type::typeinfointerface->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfointerface = this; - } - - if (id == Id::TypeInfo_Struct) -- { if (Type::typeinfostruct) -- Type::typeinfostruct->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfostruct = this; - } - - if (id == Id::TypeInfo_Typedef) -- { if (Type::typeinfotypedef) -- Type::typeinfotypedef->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfotypedef = this; - } - - if (id == Id::TypeInfo_Pointer) -- { if (Type::typeinfopointer) -- Type::typeinfopointer->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfopointer = this; - } - - if (id == Id::TypeInfo_Array) -- { if (Type::typeinfoarray) -- Type::typeinfoarray->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfoarray = this; - } - - if (id == Id::TypeInfo_StaticArray) -- { //if (Type::typeinfostaticarray) -+ { //if (!inObject) - //Type::typeinfostaticarray->error("%s", msg); - Type::typeinfostaticarray = this; - } - - if (id == Id::TypeInfo_AssociativeArray) -- { if (Type::typeinfoassociativearray) -- Type::typeinfoassociativearray->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfoassociativearray = this; - } - - if (id == Id::TypeInfo_Enum) -- { if (Type::typeinfoenum) -- Type::typeinfoenum->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfoenum = this; - } - - if (id == Id::TypeInfo_Function) -- { if (Type::typeinfofunction) -- Type::typeinfofunction->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfofunction = this; - } - - if (id == Id::TypeInfo_Delegate) -- { if (Type::typeinfodelegate) -- Type::typeinfodelegate->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfodelegate = this; - } - - if (id == Id::TypeInfo_Tuple) -- { if (Type::typeinfotypelist) -- Type::typeinfotypelist->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfotypelist = this; - } - - #if DMDV2 - if (id == Id::TypeInfo_Const) -- { if (Type::typeinfoconst) -- Type::typeinfoconst->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfoconst = this; - } - - if (id == Id::TypeInfo_Invariant) -- { if (Type::typeinfoinvariant) -- Type::typeinfoinvariant->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfoinvariant = this; - } - - if (id == Id::TypeInfo_Shared) -- { if (Type::typeinfoshared) -- Type::typeinfoshared->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfoshared = this; - } - - if (id == Id::TypeInfo_Wild) -- { if (Type::typeinfowild) -- Type::typeinfowild->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfowild = this; - } - - if (id == Id::TypeInfo_Vector) -- { if (Type::typeinfovector) -- Type::typeinfovector->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - Type::typeinfovector = this; - } - #endif - } - - if (id == Id::Object) -- { if (object) -- object->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - object = this; - } - - if (id == Id::Throwable) -- { if (throwable) -- throwable->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - throwable = this; - } - - if (id == Id::Exception) -- { if (exception) -- exception->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - exception = this; - } - - if (id == Id::Error) -- { if (errorException) -- errorException->error("%s", msg); -+ { if (!inObject) -+ error("%s", msg); - errorException = this; - } - -- //if (id == Id::ClassInfo) -- if (id == Id::TypeInfo_Class) -- { if (classinfo) -- classinfo->error("%s", msg); -- classinfo = this; -- } -- -+#if !MODULEINFO_IS_STRUCT -+ #ifdef DMDV2 -+ if (id == Id::ModuleInfo && !Module::moduleinfo) -+ Module::moduleinfo = this; -+ #else - if (id == Id::ModuleInfo) - { if (Module::moduleinfo) -- Module::moduleinfo->error("%s", msg); -+ error("%s", msg); - Module::moduleinfo = this; - } -+ #endif -+#endif - } - - com = 0; -+ cpp = 0; - isscope = 0; - isabstract = 0; - inuse = 0; -+ doAncestorsSemantic = SemanticStart; - } - - Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) -@@ -277,7 +278,7 @@ void ClassDeclaration::semantic(Scope *s - type = type->semantic(loc, sc); - handle = type; - -- if (!members) // if forward reference -+ if (!members) // if opaque declaration - { //printf("\tclass '%s' is forward referenced\n", toChars()); - return; - } -@@ -292,13 +293,13 @@ void ClassDeclaration::semantic(Scope *s - - Scope *scx = NULL; - if (scope) -- { sc = scope; -+ { -+ sc = scope; - scx = scope; // save so we don't make redundant copies - scope = NULL; - } - unsigned dprogress_save = Module::dprogress; -- -- int errors = global.gaggedErrors; -+ int errors = global.errors; - - if (sc->stc & STCdeprecated) - { -@@ -307,17 +308,21 @@ void ClassDeclaration::semantic(Scope *s - userAttributes = sc->userAttributes; - - if (sc->linkage == LINKcpp) -- error("cannot create C++ classes"); -+ cpp = 1; - - // Expand any tuples in baseclasses[] - for (size_t i = 0; i < baseclasses->dim; ) -- { BaseClass *b = (*baseclasses)[i]; -+ { -+ // Ungag errors when not speculative -+ Ungag ungag = ungagSpeculative(); -+ -+ BaseClass *b = (*baseclasses)[i]; - b->type = b->type->semantic(loc, sc); -- Type *tb = b->type->toBasetype(); - -+ Type *tb = b->type->toBasetype(); - if (tb->ty == Ttuple) - { TypeTuple *tup = (TypeTuple *)tb; -- enum PROT protection = b->protection; -+ PROT protection = b->protection; - baseclasses->remove(i); - size_t dim = Parameter::dim(tup->arguments); - for (size_t j = 0; j < dim; j++) -@@ -332,21 +337,23 @@ void ClassDeclaration::semantic(Scope *s - - // See if there's a base class as first in baseclasses[] - if (baseclasses->dim) -- { TypeClass *tc; -- BaseClass *b; -- Type *tb; -+ { -+ // Ungag errors when not speculative -+ Ungag ungag = ungagSpeculative(); - -- b = (*baseclasses)[0]; -+ BaseClass *b = (*baseclasses)[0]; - //b->type = b->type->semantic(loc, sc); -- tb = b->type->toBasetype(); -+ -+ Type *tb = b->type->toBasetype(); - if (tb->ty != Tclass) -- { if (b->type != Type::terror) -+ { -+ if (b->type != Type::terror) - error("base type must be class or interface, not %s", b->type->toChars()); - baseclasses->remove(0); - } - else - { -- tc = (TypeClass *)(tb); -+ TypeClass *tc = (TypeClass *)(tb); - - if (tc->sym->isDeprecated()) - { -@@ -374,7 +381,7 @@ void ClassDeclaration::semantic(Scope *s - } - if (!tc->sym->symtab || tc->sym->sizeok == SIZEOKnone) - { // Try to resolve forward reference -- if (/*sc->mustsemantic &&*/ tc->sym->scope) -+ if (/*doAncestorsSemantic == SemanticIn &&*/ tc->sym->scope) - tc->sym->semantic(NULL); - } - if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == SIZEOKnone) -@@ -402,19 +409,18 @@ void ClassDeclaration::semantic(Scope *s - // Treat the remaining entries in baseclasses as interfaces - // Check for errors, handle forward references - for (size_t i = (baseClass ? 1 : 0); i < baseclasses->dim; ) -- { TypeClass *tc; -- BaseClass *b; -- Type *tb; -+ { -+ // Ungag errors when not speculative -+ Ungag ungag = ungagSpeculative(); - -- b = (*baseclasses)[i]; -+ BaseClass *b = (*baseclasses)[i]; - b->type = b->type->semantic(loc, sc); -- tb = b->type->toBasetype(); -- if (tb->ty == Tclass) -- tc = (TypeClass *)tb; -- else -- tc = NULL; -+ -+ Type *tb = b->type->toBasetype(); -+ TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; - if (!tc || !tc->sym->isInterfaceDeclaration()) -- { if (b->type != Type::terror) -+ { -+ if (b->type != Type::terror) - error("base type must be interface, not %s", b->type->toChars()); - baseclasses->remove(i); - continue; -@@ -442,7 +448,7 @@ void ClassDeclaration::semantic(Scope *s - - if (!tc->sym->symtab) - { // Try to resolve forward reference -- if (/*sc->mustsemantic &&*/ tc->sym->scope) -+ if (/*doAncestorsSemantic == SemanticIn &&*/ tc->sym->scope) - tc->sym->semantic(NULL); - } - -@@ -462,64 +468,69 @@ void ClassDeclaration::semantic(Scope *s - } - i++; - } -+ if (doAncestorsSemantic == SemanticIn) -+ doAncestorsSemantic = SemanticDone; - - -- // If no base class, and this is not an Object, use Object as base class -- if (!baseClass && ident != Id::Object) -+ if (sizeok == SIZEOKnone) - { -- if (!object) -+ // If no base class, and this is not an Object, use Object as base class -+ if (!baseClass && ident != Id::Object && !cpp) - { -- error("missing or corrupt object.d"); -- fatal(); -- } -- -- Type *t = object->type; -- t = t->semantic(loc, sc)->toBasetype(); -- assert(t->ty == Tclass); -- TypeClass *tc = (TypeClass *)t; -+ if (!object) -+ { -+ error("missing or corrupt object.d"); -+ fatal(); -+ } - -- BaseClass *b = new BaseClass(tc, PROTpublic); -- baseclasses->shift(b); -+ Type *t = object->type; -+ t = t->semantic(loc, sc)->toBasetype(); -+ assert(t->ty == Tclass); -+ TypeClass *tc = (TypeClass *)t; - -- baseClass = tc->sym; -- assert(!baseClass->isInterfaceDeclaration()); -- b->base = baseClass; -- } -+ BaseClass *b = new BaseClass(tc, PROTpublic); -+ baseclasses->shift(b); - -- interfaces_dim = baseclasses->dim; -- interfaces = baseclasses->tdata(); -+ baseClass = tc->sym; -+ assert(!baseClass->isInterfaceDeclaration()); -+ b->base = baseClass; -+ } - -+ interfaces_dim = baseclasses->dim; -+ interfaces = baseclasses->tdata(); - -- if (baseClass) -- { -- if (baseClass->storage_class & STCfinal) -- error("cannot inherit from final class %s", baseClass->toChars()); -+ if (baseClass) -+ { -+ if (baseClass->storage_class & STCfinal) -+ error("cannot inherit from final class %s", baseClass->toChars()); - -- interfaces_dim--; -- interfaces++; -+ interfaces_dim--; -+ interfaces++; - -- // Copy vtbl[] from base class -- vtbl.setDim(baseClass->vtbl.dim); -- memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim); -+ // Copy vtbl[] from base class -+ vtbl.setDim(baseClass->vtbl.dim); -+ memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim); - -- // Inherit properties from base class -- com = baseClass->isCOMclass(); -- isscope = baseClass->isscope; -- vthis = baseClass->vthis; -- storage_class |= baseClass->storage_class & STC_TYPECTOR; -- } -- else -- { -- // No base class, so this is the root of the class hierarchy -- vtbl.setDim(0); -- vtbl.push(this); // leave room for classinfo as first member -- } -+ // Inherit properties from base class -+ com = baseClass->isCOMclass(); -+ if (baseClass->isCPPclass()) -+ cpp = 1; -+ isscope = baseClass->isscope; -+ vthis = baseClass->vthis; -+ enclosing = baseClass->enclosing; -+ storage_class |= baseClass->storage_class & STC_TYPECTOR; -+ } -+ else -+ { -+ // No base class, so this is the root of the class hierarchy -+ vtbl.setDim(0); -+ if (vtblOffset()) -+ vtbl.push(this); // leave room for classinfo as first member -+ } - -- protection = sc->protection; -- storage_class |= sc->stc; -+ protection = sc->protection; -+ storage_class |= sc->stc; - -- if (sizeok == SIZEOKnone) -- { - interfaceSemantic(sc); - - for (size_t i = 0; i < members->dim; i++) -@@ -532,8 +543,8 @@ void ClassDeclaration::semantic(Scope *s - * member which is a pointer to the enclosing scope. - */ - if (vthis) // if inheriting from nested class -- { // Use the base class's 'this' member -- isnested = true; -+ { -+ // Use the base class's 'this' member - if (storage_class & STCstatic) - error("static class cannot inherit from nested class %s", baseClass->toChars()); - if (toParent2() != baseClass->toParent2() && -@@ -554,57 +565,26 @@ void ClassDeclaration::semantic(Scope *s - baseClass->toChars(), - baseClass->toParent2()->toChars()); - } -- isnested = false; -+ enclosing = NULL; - } - } -- else if (!(storage_class & STCstatic)) -- { Dsymbol *s = toParent2(); -- if (s) -- { -- AggregateDeclaration *ad = s->isClassDeclaration(); -- FuncDeclaration *fd = s->isFuncDeclaration(); -- -+ else -+ makeNested(); - -- if (ad || fd) -- { isnested = true; -- Type *t; -- if (ad) -- t = ad->handle; -- else if (fd) -- { AggregateDeclaration *ad2 = fd->isMember2(); -- if (ad2) -- t = ad2->handle; -- else -- { -- t = Type::tvoidptr; -- } -- } -- else -- assert(0); -- if (t->ty == Tstruct) // ref to struct -- t = Type::tvoidptr; -- assert(!vthis); -- vthis = new ThisDeclaration(loc, t); -- members->push(vthis); -- } -- } -- } -+ if (storage_class & STCauto) -+ error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); -+ if (storage_class & STCscope) -+ isscope = 1; -+ if (storage_class & STCabstract) -+ isabstract = 1; - } - -- if (storage_class & STCauto) -- error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); -- if (storage_class & STCscope) -- isscope = 1; -- if (storage_class & STCabstract) -- isabstract = 1; -- - sc = sc->push(this); - //sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared); - //sc->stc |= storage_class & STC_TYPECTOR; - sc->stc &= STCsafe | STCtrusted | STCsystem; - sc->parent = this; - sc->inunion = 0; -- - if (isCOMclass()) - { - if (global.params.isWindows) -@@ -619,13 +599,19 @@ void ClassDeclaration::semantic(Scope *s - sc->explicitProtection = 0; - sc->structalign = STRUCTALIGN_DEFAULT; - if (baseClass) -- { sc->offset = baseClass->structsize; -+ { -+ sc->offset = baseClass->structsize; - alignsize = baseClass->alignsize; --// if (isnested) -+ sc->offset = (sc->offset + alignsize - 1) & ~(alignsize - 1); -+// if (enclosing) - // sc->offset += Target::ptrsize; // room for uplevel context pointer - } - else -- { sc->offset = Target::ptrsize * 2; // allow room for __vptr and __monitor -+ { -+ if (cpp) -+ sc->offset = Target::ptrsize; // allow room for __vptr -+ else -+ sc->offset = Target::ptrsize * 2; // allow room for __vptr and __monitor - alignsize = Target::ptrsize; - } - sc->userAttributes = NULL; -@@ -638,50 +624,45 @@ void ClassDeclaration::semantic(Scope *s - * resolve individual members like enums. - */ - for (size_t i = 0; i < members_dim; i++) -- { Dsymbol *s = (*members)[i]; -- /* There are problems doing this in the general case because -- * Scope keeps track of things like 'offset' -- */ -- if (s->isEnumDeclaration() || -- (s->isAggregateDeclaration() && s->ident) || -- s->isTemplateMixin() || -- s->isAttribDeclaration() || -- s->isAliasDeclaration()) -- { -- //printf("[%d] setScope %s %s, sc = %p\n", i, s->kind(), s->toChars(), sc); -- s->setScope(sc); -- } -+ { -+ Dsymbol *s = (*members)[i]; -+ //printf("[%d] setScope %s %s, sc = %p\n", i, s->kind(), s->toChars(), sc); -+ s->setScope(sc); - } - - for (size_t i = 0; i < members_dim; i++) -- { Dsymbol *s = (*members)[i]; -+ { -+ Dsymbol *s = (*members)[i]; -+ -+ // Ungag errors when not speculative -+ Ungag ungag = ungagSpeculative(); - s->semantic(sc); - } - - // Set the offsets of the fields and determine the size of the class - - unsigned offset = structsize; -- bool isunion = isUnionDeclaration() != NULL; - for (size_t i = 0; i < members->dim; i++) -- { Dsymbol *s = (*members)[i]; -+ { -+ Dsymbol *s = (*members)[i]; - s->setFieldOffset(this, &offset, false); - } - sc->offset = structsize; - -- if (global.gag && global.gaggedErrors != errors) -- { // The type is no good, yet the error messages were gagged. -+ if (global.errors != errors) -+ { -+ // The type is no good. - type = Type::terror; - } - - if (sizeok == SIZEOKfwd) // failed due to forward references -- { // semantic() failed due to forward references -+ { -+ // semantic() failed due to forward references - // Unwind what we did, and defer it for later -- - for (size_t i = 0; i < fields.dim; i++) -- { Dsymbol *s = fields[i]; -- VarDeclaration *vd = s->isVarDeclaration(); -- if (vd) -- vd->offset = 0; -+ { -+ if (VarDeclaration *v = fields[i]) -+ v->offset = 0; - } - fields.setDim(0); - structsize = 0; -@@ -707,43 +688,52 @@ void ClassDeclaration::semantic(Scope *s - /* Look for special member functions. - * They must be in this class, not in a base class. - */ -- ctor = search(0, Id::ctor, 0); --#if DMDV1 -- if (ctor && (ctor->toParent() != this || !ctor->isCtorDeclaration())) -- ctor = NULL; --#else -+ searchCtor(); - if (ctor && (ctor->toParent() != this || !(ctor->isCtorDeclaration() || ctor->isTemplateDeclaration()))) - ctor = NULL; // search() looks through ancestor classes --#endif -+ if (!ctor && noDefaultCtor) -+ { -+ // A class object is always created by constructor, so this check is legitimate. -+ for (size_t i = 0; i < fields.dim; i++) -+ { -+ VarDeclaration *v = fields[i]->isVarDeclaration(); -+ if (v->storage_class & STCnodefaultctor) -+ ::error(v->loc, "field %s must be initialized in constructor", v->toChars()); -+ } -+ } - --// dtor = (DtorDeclaration *)search(Id::dtor, 0); --// if (dtor && dtor->toParent() != this) --// dtor = NULL; -- --// inv = (InvariantDeclaration *)search(Id::classInvariant, 0); --// if (inv && inv->toParent() != this) --// inv = NULL; -+ inv = buildInv(sc); - - // Can be in base class -- aggNew = (NewDeclaration *)search(0, Id::classNew, 0); -- aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0); -+ aggNew = (NewDeclaration *)search(Loc(), Id::classNew, 0); -+ aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete, 0); - -- // If this class has no constructor, but base class does, create -- // a constructor: -+ // If this class has no constructor, but base class has a default -+ // ctor, create a constructor: - // this() { } - if (!ctor && baseClass && baseClass->ctor) - { -- //printf("Creating default this(){} for class %s\n", toChars()); -- Type *tf = new TypeFunction(NULL, NULL, 0, LINKd, 0); -- CtorDeclaration *ctor = new CtorDeclaration(loc, 0, 0, tf); -- ctor->isImplicit = true; -- ctor->fbody = new CompoundStatement(0, new Statements()); -- members->push(ctor); -- ctor->addMember(sc, this, 1); -- *sc = scsave; // why? What about sc->nofree? -- ctor->semantic(sc); -- this->ctor = ctor; -- defaultCtor = ctor; -+ if (FuncDeclaration *fd = resolveFuncCall(loc, sc, baseClass->ctor, NULL, NULL, NULL, 1)) -+ { -+ //printf("Creating default this(){} for class %s\n", toChars()); -+ TypeFunction *btf = (TypeFunction *)fd->type; -+ TypeFunction *tf = new TypeFunction(NULL, NULL, 0, LINKd, fd->storage_class); -+ tf->purity = btf->purity; -+ tf->isnothrow = btf->isnothrow; -+ tf->trust = btf->trust; -+ CtorDeclaration *ctor = new CtorDeclaration(loc, Loc(), 0, tf); -+ ctor->fbody = new CompoundStatement(Loc(), new Statements()); -+ members->push(ctor); -+ ctor->addMember(sc, this, 1); -+ *sc = scsave; // why? What about sc->nofree? -+ ctor->semantic(sc); -+ this->ctor = ctor; -+ defaultCtor = ctor; -+ } -+ else -+ { -+ error("Cannot implicitly generate a default ctor when base class %s is missing a default ctor", baseClass->toPrettyChars()); -+ } - } - - #if 0 -@@ -782,13 +772,10 @@ void ClassDeclaration::semantic(Scope *s - Module::dprogress++; - - dtor = buildDtor(sc); -- if (Dsymbol *assign = search_function(this, Id::assign)) -+ if (FuncDeclaration *f = hasIdentityOpAssign(sc)) - { -- if (FuncDeclaration *f = hasIdentityOpAssign(sc, assign)) -- { -- if (!(f->storage_class & STCdisable)) -- error("identity assignment operator overload is illegal"); -- } -+ if (!(f->storage_class & STCdisable)) -+ error(f->loc, "identity assignment operator overload is illegal"); - } - sc->pop(); - -@@ -808,6 +795,13 @@ void ClassDeclaration::semantic(Scope *s - deferred->semantic2(sc); - deferred->semantic3(sc); - } -+ -+ if (type->ty == Tclass && ((TypeClass *)type)->sym != this) -+ { -+ error("failed semantic analysis"); -+ this->errors = true; -+ type = Type::terror; -+ } - } - - void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -824,7 +818,7 @@ void ClassDeclaration::toCBuffer(OutBuff - BaseClass *b = (*baseclasses)[i]; - - if (i) -- buf->writeByte(','); -+ buf->writestring(", "); - //buf->writestring(b->base->ident->toChars()); - b->type->toCBuffer(buf, NULL, hgs); - } -@@ -891,10 +885,10 @@ int ClassDeclaration::isBaseOf(ClassDecl - { - /* cd->baseClass might not be set if cd is forward referenced. - */ -- if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) -+ if (!cd->baseClass && cd->scope && !cd->isInterfaceDeclaration()) - { - cd->semantic(NULL); -- if (!cd->baseClass) -+ if (!cd->baseClass && cd->scope) - cd->error("base class is forward referenced by %s", toChars()); - } - -@@ -928,19 +922,17 @@ Dsymbol *ClassDeclaration::search(Loc lo - Dsymbol *s; - //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); - -- if (scope && !symtab) -- { Scope *sc = scope; -- sc->mustsemantic++; -- // If speculatively gagged, ungag now. -- unsigned oldgag = global.gag; -- if (global.isSpeculativeGagging()) -- global.gag = 0; -- semantic(sc); -- global.gag = oldgag; -- sc->mustsemantic--; -+ //if (scope) printf("%s doAncestorsSemantic = %d\n", toChars(), doAncestorsSemantic); -+ if (scope && doAncestorsSemantic == SemanticStart) -+ { -+ // must semantic on base class/interfaces -+ doAncestorsSemantic = SemanticIn; -+ semantic(scope); -+ if (doAncestorsSemantic != SemanticDone) -+ doAncestorsSemantic = SemanticStart; - } - -- if (!members || !symtab) -+ if (!members || !symtab) // opaque or semantic() is not yet called - { - error("is forward referenced when looking for '%s'", ident->toChars()); - //*(char*)0=0; -@@ -982,6 +974,8 @@ ClassDeclaration *ClassDeclaration::sear - { - BaseClass *b = (*baseclasses)[i]; - ClassDeclaration *cdb = b->type->isClassHandle(); -+ if (!cdb) // Bugzilla 10616 -+ return NULL; - if (cdb->ident->equals(ident)) - return cdb; - cdb = cdb->searchBase(loc, ident); -@@ -997,18 +991,22 @@ ClassDeclaration *ClassDeclaration::sear - */ - - #if DMDV2 --int isf(void *param, FuncDeclaration *fd) -+int isf(void *param, Dsymbol *s) - { -+ FuncDeclaration *fd = s->isFuncDeclaration(); -+ if (!fd) -+ return 0; - //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); -- return param == fd; -+ return (RootObject *)param == fd; - } - - int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) - { - //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars()); -- Dsymbol *s = search(0, fd->ident, 4|2); -+ Dsymbol *s = search(Loc(), fd->ident, 4|2); - if (!s) -- { //printf("not found\n"); -+ { -+ //printf("not found\n"); - /* Because, due to a hack, if there are multiple definitions - * of fd->ident, NULL is returned. - */ -@@ -1019,9 +1017,10 @@ int ClassDeclaration::isFuncHidden(FuncD - if (os) - { - for (size_t i = 0; i < os->a.dim; i++) -- { Dsymbol *s2 = os->a[i]; -+ { -+ Dsymbol *s2 = os->a[i]; - FuncDeclaration *f2 = s2->isFuncDeclaration(); -- if (f2 && overloadApply(f2, &isf, fd)) -+ if (f2 && overloadApply(f2, (void *)fd, &isf)) - return 0; - } - return 1; -@@ -1030,7 +1029,7 @@ int ClassDeclaration::isFuncHidden(FuncD - { - FuncDeclaration *fdstart = s->isFuncDeclaration(); - //printf("%s fdstart = %p\n", s->kind(), fdstart); -- if (overloadApply(fdstart, &isf, fd)) -+ if (overloadApply(fdstart, (void *)fd, &isf)) - return 0; - - return !fd->parent->isTemplateMixin(); -@@ -1139,9 +1138,13 @@ void ClassDeclaration::interfaceSemantic - if (b->base->isCOMinterface()) - com = 1; - -+#if 1 - if (b->base->isCPPinterface() && id) - id->cpp = 1; -- -+#else -+ if (b->base->isCPPinterface()) -+ cpp = 1; -+#endif - vtblInterfaces->push(b); - b->copyBaseInterfaces(vtblInterfaces); - } -@@ -1161,6 +1164,11 @@ int ClassDeclaration::isCOMinterface() - } - - #if DMDV2 -+int ClassDeclaration::isCPPclass() -+{ -+ return cpp; -+} -+ - int ClassDeclaration::isCPPinterface() - { - return 0; -@@ -1171,10 +1179,10 @@ int ClassDeclaration::isCPPinterface() - /**************************************** - */ - --int ClassDeclaration::isAbstract() -+bool ClassDeclaration::isAbstract() - { - if (isabstract) -- return TRUE; -+ return true; - for (size_t i = 1; i < vtbl.dim; i++) - { - FuncDeclaration *fd = vtbl[i]->isFuncDeclaration(); -@@ -1183,10 +1191,10 @@ int ClassDeclaration::isAbstract() - if (!fd || fd->isAbstract()) - { - isabstract |= 1; -- return TRUE; -+ return true; - } - } -- return FALSE; -+ return false; - } - - -@@ -1195,11 +1203,14 @@ int ClassDeclaration::isAbstract() - * For class objects, yes, this is where the classinfo ptr goes. - * For COM interfaces, no. - * For non-COM interfaces, yes, this is where the Interface ptr goes. -+ * Returns: -+ * 0 vtbl[0] is first virtual function pointer -+ * 1 vtbl[0] is classinfo/interfaceinfo pointer - */ - - int ClassDeclaration::vtblOffset() - { -- return 1; -+ return cpp ? 0 : 1; - } - - /**************************************** -@@ -1223,8 +1234,6 @@ void ClassDeclaration::addLocalClass(Cla - InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses) - : ClassDeclaration(loc, id, baseclasses) - { -- com = 0; -- cpp = 0; - if (id == Id::IUnknown) // IUnknown is the root of all COM interfaces - { com = 1; - cpp = 1; // IUnknown is also a C++ interface -@@ -1271,12 +1280,13 @@ void InterfaceDeclaration::semantic(Scop - - Scope *scx = NULL; - if (scope) -- { sc = scope; -+ { -+ sc = scope; - scx = scope; // save so we don't make redundant copies - scope = NULL; - } - -- int errors = global.gaggedErrors; -+ int errors = global.errors; - - if (sc->stc & STCdeprecated) - { -@@ -1286,13 +1296,17 @@ void InterfaceDeclaration::semantic(Scop - - // Expand any tuples in baseclasses[] - for (size_t i = 0; i < baseclasses->dim; ) -- { BaseClass *b = (*baseclasses)[i]; -+ { -+ // Ungag errors when not speculative -+ Ungag ungag = ungagSpeculative(); -+ -+ BaseClass *b = (*baseclasses)[i]; - b->type = b->type->semantic(loc, sc); -- Type *tb = b->type->toBasetype(); - -+ Type *tb = b->type->toBasetype(); - if (tb->ty == Ttuple) - { TypeTuple *tup = (TypeTuple *)tb; -- enum PROT protection = b->protection; -+ PROT protection = b->protection; - baseclasses->remove(i); - size_t dim = Parameter::dim(tup->arguments); - for (size_t j = 0; j < dim; j++) -@@ -1310,19 +1324,18 @@ void InterfaceDeclaration::semantic(Scop - - // Check for errors, handle forward references - for (size_t i = 0; i < baseclasses->dim; ) -- { TypeClass *tc; -- BaseClass *b; -- Type *tb; -+ { -+ // Ungag errors when not speculative -+ Ungag ungag = ungagSpeculative(); - -- b = (*baseclasses)[i]; -+ BaseClass *b = (*baseclasses)[i]; - b->type = b->type->semantic(loc, sc); -- tb = b->type->toBasetype(); -- if (tb->ty == Tclass) -- tc = (TypeClass *)tb; -- else -- tc = NULL; -+ -+ Type *tb = b->type->toBasetype(); -+ TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; - if (!tc || !tc->sym->isInterfaceDeclaration()) -- { if (b->type != Type::terror) -+ { -+ if (b->type != Type::terror) - error("base type must be interface, not %s", b->type->toChars()); - baseclasses->remove(i); - continue; -@@ -1346,7 +1359,7 @@ void InterfaceDeclaration::semantic(Scop - } - if (!b->base->symtab) - { // Try to resolve forward reference -- if (sc->mustsemantic && b->base->scope) -+ if (doAncestorsSemantic == SemanticIn && b->base->scope) - b->base->semantic(NULL); - } - if (!b->base->symtab || b->base->scope || b->base->inuse) -@@ -1366,6 +1379,8 @@ void InterfaceDeclaration::semantic(Scop - #endif - i++; - } -+ if (doAncestorsSemantic == SemanticIn) -+ doAncestorsSemantic = SemanticDone; - - interfaces_dim = baseclasses->dim; - interfaces = baseclasses->tdata(); -@@ -1417,9 +1432,9 @@ void InterfaceDeclaration::semantic(Scop - sc = sc->push(this); - sc->stc &= STCsafe | STCtrusted | STCsystem; - sc->parent = this; -- if (isCOMinterface()) -+ if (com) - sc->linkage = LINKwindows; -- else if (isCPPinterface()) -+ else if (cpp) - sc->linkage = LINKcpp; - sc->structalign = STRUCTALIGN_DEFAULT; - sc->protection = PROTpublic; -@@ -1448,11 +1463,14 @@ void InterfaceDeclaration::semantic(Scop - for (size_t i = 0; i < members->dim; i++) - { - Dsymbol *s = (*members)[i]; -+ -+ // Ungag errors when not speculative -+ Ungag ungag = ungagSpeculative(); - s->semantic(sc); - } - -- if (global.gag && global.gaggedErrors != errors) -- { // The type is no good, yet the error messages were gagged. -+ if (global.errors != errors) -+ { // The type is no good. - type = Type::terror; - } - -@@ -1460,6 +1478,13 @@ void InterfaceDeclaration::semantic(Scop - //members->print(); - sc->pop(); - //printf("-InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); -+ -+ if (type->ty == Tclass && ((TypeClass *)type)->sym != this) -+ { -+ error("failed semantic analysis"); -+ this->errors = true; -+ type = Type::terror; -+ } - } - - -@@ -1594,7 +1619,7 @@ BaseClass::BaseClass() - memset(this, 0, sizeof(BaseClass)); - } - --BaseClass::BaseClass(Type *type, enum PROT protection) -+BaseClass::BaseClass(Type *type, PROT protection) - { - //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); - this->type = type; -@@ -1619,7 +1644,6 @@ BaseClass::BaseClass(Type *type, enum PR - - int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance) - { -- ClassDeclaration *id = base; - int result = 0; - - //printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", base->toChars(), cd->toChars()); -@@ -1651,8 +1675,7 @@ int BaseClass::fillVtbl(ClassDeclaration - if (newinstance && - fd->toParent() != cd && - ifd->toParent() == base) -- cd->error("interface function %s.%s is not implemented", -- id->toChars(), ifd->ident->toChars()); -+ cd->error("interface function '%s' is not implemented", ifd->toFullSignature()); - - if (fd->toParent() == cd) - result = 1; -@@ -1662,9 +1685,7 @@ int BaseClass::fillVtbl(ClassDeclaration - //printf(" not found\n"); - // BUG: should mark this class as abstract? - if (!cd->isAbstract()) -- cd->error("interface function %s.%s%s isn't implemented", -- id->toChars(), ifd->ident->toChars(), -- Parameter::argsTypesToChars(tf->parameters, tf->varargs)); -+ cd->error("interface function '%s' is not implemented", ifd->toFullSignature()); - - fd = NULL; - } ---- a/src/gcc/d/dfrontend/clone.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/clone.c 2014-04-01 16:32:51.000000000 +0100 -@@ -25,43 +25,71 @@ - - - /******************************************* -+ * Merge function attributes pure, nothrow, @safe, and @disable -+ */ -+StorageClass mergeFuncAttrs(StorageClass s1, StorageClass s2) -+{ -+ StorageClass stc = 0; -+ StorageClass sa = s1 & s2; -+ StorageClass so = s1 | s2; -+ -+ if (so & STCsystem) -+ stc |= STCsystem; -+ else if (sa & STCtrusted) -+ stc |= STCtrusted; -+ else if ((so & (STCtrusted | STCsafe)) == (STCtrusted | STCsafe)) -+ stc |= STCtrusted; -+ else if (sa & STCsafe) -+ stc |= STCsafe; -+ -+ if (sa & STCpure) -+ stc |= STCpure; -+ -+ if (sa & STCnothrow) -+ stc |= STCnothrow; -+ -+ if (so & STCdisable) -+ stc |= STCdisable; -+ -+ return stc; -+} -+ -+/******************************************* - * Check given opAssign symbol is really identity opAssign or not. - */ - --FuncDeclaration *AggregateDeclaration::hasIdentityOpAssign(Scope *sc, Dsymbol *assign) -+FuncDeclaration *AggregateDeclaration::hasIdentityOpAssign(Scope *sc) - { -+ Dsymbol *assign = search_function(this, Id::assign); - if (assign) - { -- assert(assign->ident == Id::assign); -- - /* check identity opAssign exists - */ - Expression *er = new NullExp(loc, type); // dummy rvalue - Expression *el = new IdentifierExp(loc, Id::p); // dummy lvalue - el->type = type; -- Expressions ar; ar.push(er); -- Expressions al; al.push(el); -+ Expressions *a = new Expressions(); -+ a->setDim(1); - FuncDeclaration *f = NULL; -- if (FuncDeclaration *fd = assign->isFuncDeclaration()) -+ -+ unsigned errors = global.startGagging(); // Do not report errors, even if the -+ unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it. -+ global.speculativeGag = global.gag; -+ sc = sc->push(); -+ sc->speculative = true; -+ -+ for (size_t i = 0; i < 2; i++) - { -- f = fd->overloadResolve(loc, er, &ar, 1); -- if (!f) f = fd->overloadResolve(loc, er, &al, 1); -+ (*a)[0] = (i == 0 ? er : el); -+ f = resolveFuncCall(loc, sc, assign, NULL, type, a, 1); -+ if (f) -+ break; - } -- if (TemplateDeclaration *td = assign->isTemplateDeclaration()) -- { -- unsigned errors = global.startGagging(); // Do not report errors, even if the -- unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it. -- global.speculativeGag = global.gag; -- Scope *sc2 = sc->push(); -- sc2->speculative = true; - -- f = td->deduceFunctionTemplate(sc2, loc, NULL, er, &ar, 1); -- if (!f) f = td->deduceFunctionTemplate(sc2, loc, NULL, er, &al, 1); -+ sc = sc->pop(); -+ global.speculativeGag = oldspec; -+ global.endGagging(errors); - -- sc2->pop(); -- global.speculativeGag = oldspec; -- global.endGagging(errors); -- } - if (f) - { - int varargs; -@@ -104,16 +132,13 @@ int StructDeclaration::needOpAssign() - { - Dsymbol *s = fields[i]; - VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -+ assert(v && v->isField()); - if (v->storage_class & STCref) - continue; -- Type *tv = v->type->toBasetype(); -- while (tv->ty == Tsarray) -- { TypeSArray *ta = (TypeSArray *)tv; -- tv = tv->nextOf()->toBasetype(); -- } -+ Type *tv = v->type->baseElemOf(); - if (tv->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)tv; -+ { -+ TypeStruct *ts = (TypeStruct *)tv; - StructDeclaration *sd = ts->sym; - if (sd->needOpAssign()) - goto Lneed; -@@ -133,41 +158,80 @@ Lneed: - * Build opAssign for struct. - * ref S opAssign(S s) { ... } - * -- * Note that s will be constructed onto the stack, probably copy-constructed. -- * Then, the body is: -- * S tmp = this; // bit copy -- * this = s; // bit copy -- * tmp.dtor(); -+ * Note that s will be constructed onto the stack, and probably -+ * copy-constructed in caller site. -+ * -+ * If S has copy copy construction and/or destructor, -+ * the body will make bit-wise object swap: -+ * S __tmp = this; // bit copy -+ * this = s; // bit copy -+ * __tmp.dtor(); - * Instead of running the destructor on s, run it on tmp instead. -+ * -+ * Otherwise, the body will make member-wise assignments: -+ * Then, the body is: -+ * this.field1 = s.field1; -+ * this.field2 = s.field2; -+ * ...; - */ - - FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc) - { -- Dsymbol *assign = search_function(this, Id::assign); -- if (assign) -+ if (FuncDeclaration *f = hasIdentityOpAssign(sc)) - { -- if (FuncDeclaration *f = hasIdentityOpAssign(sc, assign)) -- return f; -- // Even if non-identity opAssign is defined, built-in identity opAssign -- // will be defined. (Is this an exception of operator overloading rule?) -+ hasIdentityAssign = 1; -+ return f; - } -+ // Even if non-identity opAssign is defined, built-in identity opAssign -+ // will be defined. - - if (!needOpAssign()) - return NULL; - - //printf("StructDeclaration::buildOpAssign() %s\n", toChars()); -+ StorageClass stc = STCsafe | STCnothrow | STCpure; -+ Loc declLoc = this->loc; -+ Loc loc = Loc(); // internal code should have no loc to prevent coverage -+ -+ if (dtor || postblit) -+ { -+ if (dtor) -+ stc = mergeFuncAttrs(stc, dtor->storage_class); -+ } -+ else -+ { -+ for (size_t i = 0; i < fields.dim; i++) -+ { -+ Dsymbol *s = fields[i]; -+ VarDeclaration *v = s->isVarDeclaration(); -+ assert(v && v->isField()); -+ if (v->storage_class & STCref) -+ continue; -+ Type *tv = v->type->baseElemOf(); -+ if (tv->ty == Tstruct) -+ { -+ TypeStruct *ts = (TypeStruct *)tv; -+ StructDeclaration *sd = ts->sym; -+ if (FuncDeclaration *f = sd->hasIdentityOpAssign(sc)) -+ stc = mergeFuncAttrs(stc, f->storage_class); -+ } -+ } -+ } - - Parameters *fparams = new Parameters; - fparams->push(new Parameter(STCnodtor, type, Id::p, NULL)); -- Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd); -- ((TypeFunction *)ftype)->isref = 1; -+ Type *tf = new TypeFunction(fparams, handle, 0, LINKd, stc | STCref); - -- FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::assign, STCundefined, ftype); -+ FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf); - - Expression *e = NULL; -- if (postblit) -- { /* Swap: -- * tmp = *this; *this = s; tmp.dtor(); -+ if (stc & STCdisable) -+ { -+ } -+ else if (dtor || postblit) -+ { -+ /* Do swap this and rhs -+ * tmp = this; this = s; tmp.dtor(); - */ - //printf("\tswap copy\n"); - Identifier *idtmp = Lexer::uniqueId("__tmp"); -@@ -175,20 +239,20 @@ FuncDeclaration *StructDeclaration::buil - AssignExp *ec = NULL; - if (dtor) - { -- tmp = new VarDeclaration(0, type, idtmp, new VoidInitializer(0)); -+ tmp = new VarDeclaration(loc, type, idtmp, new VoidInitializer(loc)); - tmp->noscope = 1; - tmp->storage_class |= STCctfe; -- e = new DeclarationExp(0, tmp); -- ec = new AssignExp(0, -- new VarExp(0, tmp), -- new ThisExp(0) -+ e = new DeclarationExp(loc, tmp); -+ ec = new AssignExp(loc, -+ new VarExp(loc, tmp), -+ new ThisExp(loc) - ); - ec->op = TOKblit; - e = Expression::combine(e, ec); - } -- ec = new AssignExp(0, -- new ThisExp(0), -- new IdentifierExp(0, Id::p)); -+ ec = new AssignExp(loc, -+ new ThisExp(loc), -+ new IdentifierExp(loc, Id::p)); - ec->op = TOKblit; - e = Expression::combine(e, ec); - if (dtor) -@@ -196,38 +260,44 @@ FuncDeclaration *StructDeclaration::buil - /* Instead of running the destructor on s, run it - * on tmp. This avoids needing to copy tmp back in to s. - */ -- Expression *ec2 = new DotVarExp(0, new VarExp(0, tmp), dtor, 0); -- ec2 = new CallExp(0, ec2); -+ Expression *ec2 = new DotVarExp(loc, new VarExp(loc, tmp), dtor, 0); -+ ec2 = new CallExp(loc, ec2); - e = Expression::combine(e, ec2); - } - } - else -- { /* Do memberwise copy -+ { -+ /* Do memberwise copy - */ - //printf("\tmemberwise copy\n"); - for (size_t i = 0; i < fields.dim; i++) - { - Dsymbol *s = fields[i]; - VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -+ assert(v && v->isField()); - // this.v = s.v; -- AssignExp *ec = new AssignExp(0, -- new DotVarExp(0, new ThisExp(0), v, 0), -- new DotVarExp(0, new IdentifierExp(0, Id::p), v, 0)); -+ AssignExp *ec = new AssignExp(loc, -+ new DotVarExp(loc, new ThisExp(loc), v, 0), -+ new DotVarExp(loc, new IdentifierExp(loc, Id::p), v, 0)); - e = Expression::combine(e, ec); - } - } -- Statement *s1 = new ExpStatement(0, e); -+ if (e) -+ { -+ Statement *s1 = new ExpStatement(loc, e); - -- /* Add: -- * return this; -- */ -- e = new ThisExp(0); -- Statement *s2 = new ReturnStatement(0, e); -+ /* Add: -+ * return this; -+ */ -+ e = new ThisExp(loc); -+ Statement *s2 = new ReturnStatement(loc, e); - -- fop->fbody = new CompoundStatement(0, s1, s2); -+ fop->fbody = new CompoundStatement(loc, s1, s2); -+ } - - Dsymbol *s = fop; -+#if 1 // workaround until fixing issue 1528 -+ Dsymbol *assign = search_function(this, Id::assign); - if (assign && assign->isTemplateDeclaration()) - { - // Wrap a template around the function declaration -@@ -238,6 +308,7 @@ FuncDeclaration *StructDeclaration::buil - new TemplateDeclaration(assign->loc, fop->ident, tpl, NULL, decldefs, 0); - s = tempdecl; - } -+#endif - members->push(s); - s->addMember(sc, this, 1); - this->hasIdentityAssign = 1; // temporary mark identity assignable -@@ -281,10 +352,8 @@ int StructDeclaration::needOpEquals() - if (hasIdentityEquals) - goto Lneed; - --#if 0 - if (isUnionDeclaration()) - goto Ldontneed; --#endif - - /* If any of the fields has an opEquals, then we - * need it too. -@@ -293,24 +362,22 @@ int StructDeclaration::needOpEquals() - { - Dsymbol *s = fields[i]; - VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -+ assert(v && v->isField()); - if (v->storage_class & STCref) - continue; - Type *tv = v->type->toBasetype(); --#if 0 - if (tv->isfloating()) - goto Lneed; - if (tv->ty == Tarray) - goto Lneed; -+ if (tv->ty == Taarray) -+ goto Lneed; - if (tv->ty == Tclass) - goto Lneed; --#endif -- while (tv->ty == Tsarray) -- { TypeSArray *ta = (TypeSArray *)tv; -- tv = tv->nextOf()->toBasetype(); -- } -+ tv = tv->baseElemOf(); - if (tv->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)tv; -+ { -+ TypeStruct *ts = (TypeStruct *)tv; - StructDeclaration *sd = ts->sym; - if (sd->needOpEquals()) - goto Lneed; -@@ -326,180 +393,299 @@ Lneed: - #undef X - } - -+FuncDeclaration *AggregateDeclaration::hasIdentityOpEquals(Scope *sc) -+{ -+ Dsymbol *eq = search_function(this, Id::eq); -+ if (eq) -+ { -+ /* check identity opEquals exists -+ */ -+ Expression *er = new NullExp(loc, NULL); // dummy rvalue -+ Expression *el = new IdentifierExp(loc, Id::p); // dummy lvalue -+ Expressions *a = new Expressions(); -+ a->setDim(1); -+ for (size_t i = 0; ; i++) -+ { -+ Type *tthis; -+ if (i == 0) tthis = type; -+ if (i == 1) tthis = type->constOf(); -+ if (i == 2) tthis = type->immutableOf(); -+ if (i == 3) tthis = type->sharedOf(); -+ if (i == 4) tthis = type->sharedConstOf(); -+ if (i == 5) break; -+ FuncDeclaration *f = NULL; -+ -+ unsigned errors = global.startGagging(); // Do not report errors, even if the -+ unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it. -+ global.speculativeGag = global.gag; -+ sc = sc->push(); -+ sc->speculative = true; -+ -+ for (size_t j = 0; j < 2; j++) -+ { -+ (*a)[0] = (j == 0 ? er : el); -+ (*a)[0]->type = tthis; -+ f = resolveFuncCall(loc, sc, eq, NULL, tthis, a, 1); -+ if (f) -+ break; -+ } -+ -+ sc = sc->pop(); -+ global.speculativeGag = oldspec; -+ global.endGagging(errors); -+ -+ if (f) -+ return f; -+ } -+ } -+ return NULL; -+} -+ - /****************************************** - * Build opEquals for struct. - * const bool opEquals(const S s) { ... } -+ * -+ * By fixing bugzilla 3789, opEquals is changed to be never implicitly generated. -+ * Now, struct objects comparison s1 == s2 is translated to: -+ * s1.tupleof == s2.tupleof -+ * to calculate structural equality. See EqualExp::semantic. - */ - - FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc) - { -- Dsymbol *eq = search_function(this, Id::eq); -- if (eq) -+ if (FuncDeclaration *f = hasIdentityOpEquals(sc)) - { -- for (size_t i = 0; i <= 1; i++) -- { -- Expression *e = -- i == 0 ? new NullExp(loc, type->constOf()) // dummy rvalue -- : type->constOf()->defaultInit(); // dummy lvalue -- Expressions *arguments = new Expressions(); -- arguments->push(e); -+ hasIdentityEquals = 1; -+ } -+ return NULL; -+} - -- // check identity opEquals exists -- FuncDeclaration *fd = eq->isFuncDeclaration(); -- if (fd) -- { fd = fd->overloadResolve(loc, e, arguments, 1); -- if (fd && !(fd->storage_class & STCdisable)) -- return fd; -- } -+/****************************************** -+ * Build __xopEquals for TypeInfo_Struct -+ * static bool __xopEquals(ref const S p, ref const S q) -+ * { -+ * return p == q; -+ * } -+ * -+ * This is called by TypeInfo.equals(p1, p2). If the struct does not support -+ * const objects comparison, it will throw "not implemented" Error in runtime. -+ */ -+ -+FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc) -+{ -+ if (!needOpEquals()) -+ return NULL; // bitwise comparison would work - -- TemplateDeclaration *td = eq->isTemplateDeclaration(); -- if (td) -- { fd = td->deduceFunctionTemplate(sc, loc, NULL, e, arguments, 1); -- if (fd && !(fd->storage_class & STCdisable)) -- return fd; -+ //printf("StructDeclaration::buildXopEquals() %s\n", toChars()); -+ if (Dsymbol *eq = search_function(this, Id::eq)) -+ { -+ if (FuncDeclaration *fd = eq->isFuncDeclaration()) -+ { -+ TypeFunction *tfeqptr; -+ { -+ Scope sc; -+ -+ /* const bool opEquals(ref const S s); -+ */ -+ Parameters *parameters = new Parameters; -+ parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL)); -+ tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd); -+ tfeqptr->mod = MODconst; -+ tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &sc); - } -+ fd = fd->overloadExactMatch(tfeqptr); -+ if (fd) -+ return fd; - } -- return NULL; - } - -- if (!needOpEquals()) -- return NULL; -+ if (!xerreq) -+ { -+ Identifier *id = Lexer::idPool("_xopEquals"); -+ Expression *e = new IdentifierExp(loc, Id::empty); -+ e = new DotIdExp(loc, e, Id::object); -+ e = new DotIdExp(loc, e, id); -+ e = e->semantic(sc); -+ Dsymbol *s = getDsymbol(e); -+ if (!s) -+ { -+ ::error(Loc(), "ICE: %s not found in object module. You must update druntime", id->toChars()); -+ fatal(); -+ } -+ assert(s); -+ xerreq = s->isFuncDeclaration(); -+ } - -- //printf("StructDeclaration::buildOpEquals() %s\n", toChars()); -+ Loc declLoc = Loc(); // loc is unnecessary so __xopEquals is never called directly -+ Loc loc = Loc(); // loc is unnecessary so errors are gagged - - Parameters *parameters = new Parameters; -- parameters->push(new Parameter(STCin, type, Id::p, NULL)); -+ parameters->push(new Parameter(STCref | STCconst, type, Id::p, NULL)); -+ parameters->push(new Parameter(STCref | STCconst, type, Id::q, NULL)); - TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd); -- tf->mod = MODconst; - tf = (TypeFunction *)tf->semantic(loc, sc); - -- FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::eq, STCundefined, tf); -- -- Expression *e = NULL; -- /* Do memberwise compare -- */ -- //printf("\tmemberwise compare\n"); -- for (size_t i = 0; i < fields.dim; i++) -- { -- Dsymbol *s = fields[i]; -- VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -- if (v->storage_class & STCref) -- assert(0); // what should we do with this? -- // this.v == s.v; -- EqualExp *ec = new EqualExp(TOKequal, loc, -- new DotVarExp(loc, new ThisExp(loc), v, 0), -- new DotVarExp(loc, new IdentifierExp(loc, Id::p), v, 0)); -- if (e) -- e = new AndAndExp(loc, e, ec); -- else -- e = ec; -- } -- if (!e) -- e = new IntegerExp(loc, 1, Type::tbool); -- fop->fbody = new ReturnStatement(loc, e); -+ Identifier *id = Lexer::idPool("__xopEquals"); -+ FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf); - -- members->push(fop); -- fop->addMember(sc, this, 1); -+ Expression *e1 = new IdentifierExp(loc, Id::p); -+ Expression *e2 = new IdentifierExp(loc, Id::q); -+ Expression *e = new EqualExp(TOKequal, loc, e1, e2); - -- sc = sc->push(); -- sc->stc = 0; -- sc->linkage = LINKd; -+ fop->fbody = new ReturnStatement(loc, e); - -- fop->semantic(sc); -+ unsigned errors = global.startGagging(); // Do not report errors -+ Scope *sc2 = sc->push(); -+ sc2->stc = 0; -+ sc2->linkage = LINKd; - -- sc->pop(); -+ fop->semantic(sc2); -+ fop->semantic2(sc2); - -- //printf("-StructDeclaration::buildOpEquals() %s\n", toChars()); -+ sc2->pop(); -+ if (global.endGagging(errors)) // if errors happened -+ fop = xerreq; - - return fop; - } - - /****************************************** -- * Build __xopEquals for TypeInfo_Struct -- * bool __xopEquals(in void* p, in void* q) { ... } -+ * Build __xopCmp for TypeInfo_Struct -+ * static bool __xopCmp(ref const S p, ref const S q) -+ * { -+ * return p.opCmp(q); -+ * } -+ * -+ * This is called by TypeInfo.compare(p1, p2). If the struct does not support -+ * const objects comparison, it will throw "not implemented" Error in runtime. - */ - --FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc) -+FuncDeclaration *StructDeclaration::buildXopCmp(Scope *sc) - { -- if (!search_function(this, Id::eq)) -+ //printf("StructDeclaration::buildXopCmp() %s\n", toChars()); -+ if (Dsymbol *cmp = search_function(this, Id::cmp)) -+ { -+ if (FuncDeclaration *fd = cmp->isFuncDeclaration()) -+ { -+ TypeFunction *tfcmpptr; -+ { -+ Scope sc; -+ -+ /* const int opCmp(ref const S s); -+ */ -+ Parameters *parameters = new Parameters; -+ parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL)); -+ tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd); -+ tfcmpptr->mod = MODconst; -+ tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &sc); -+ } -+ fd = fd->overloadExactMatch(tfcmpptr); -+ if (fd) -+ return fd; -+ } -+ } -+ else -+ { -+#if 0 // FIXME: doesn't work for recursive alias this -+ /* Check opCmp member exists. -+ * Consider 'alias this', but except opDispatch. -+ */ -+ Expression *e = new DsymbolExp(loc, this); -+ e = new DotIdExp(loc, e, Id::cmp); -+ Scope *sc2 = sc->push(); -+ e = e->trySemantic(sc2); -+ sc2->pop(); -+ if (e) -+ { -+ Dsymbol *s = NULL; -+ switch (e->op) -+ { -+ case TOKoverloadset: s = ((OverExp *)e)->vars; break; -+ case TOKimport: s = ((ScopeExp *)e)->sds; break; -+ case TOKvar: s = ((VarExp *)e)->var; break; -+ default: break; -+ } -+ if (!s || s->ident != Id::cmp) -+ e = NULL; // there's no valid member 'opCmp' -+ } -+ if (!e) -+ return NULL; // bitwise comparison would work -+ /* Essentially, a struct which does not define opCmp is not comparable. -+ * At this time, typeid(S).compare might be correct that throwing "not implement" Error. -+ * But implementing it would break existing code, such as: -+ * -+ * struct S { int value; } // no opCmp -+ * int[S] aa; // Currently AA key uses bitwise comparison -+ * // (It's default behavior of TypeInfo_Strust.compare). -+ * -+ * Not sure we should fix this inconsistency, so just keep current behavior. -+ */ -+#else - return NULL; -+#endif -+ } - -- /* static bool__xopEquals(in void* p, in void* q) { -- * return ( *cast(const S*)(p) ).opEquals( *cast(const S*)(q) ); -- * } -- */ -+ if (!xerrcmp) -+ { -+ Identifier *id = Lexer::idPool("_xopCmp"); -+ Expression *e = new IdentifierExp(loc, Id::empty); -+ e = new DotIdExp(loc, e, Id::object); -+ e = new DotIdExp(loc, e, id); -+ e = e->semantic(sc); -+ Dsymbol *s = getDsymbol(e); -+ if (!s) -+ { -+ ::error(Loc(), "ICE: %s not found in object module. You must update druntime", id->toChars()); -+ fatal(); -+ } -+ assert(s); -+ xerrcmp = s->isFuncDeclaration(); -+ } - -- Parameters *parameters = new Parameters; -- parameters->push(new Parameter(STCin, Type::tvoidptr, Id::p, NULL)); -- parameters->push(new Parameter(STCin, Type::tvoidptr, Id::q, NULL)); -- TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd); -- tf = (TypeFunction *)tf->semantic(0, sc); -+ Loc declLoc = Loc(); // loc is unnecessary so __xopCmp is never called directly -+ Loc loc = Loc(); // loc is unnecessary so errors are gagged - -- Identifier *id = Lexer::idPool("__xopEquals"); -- FuncDeclaration *fop = new FuncDeclaration(0, 0, id, STCstatic, tf); -+ Parameters *parameters = new Parameters; -+ parameters->push(new Parameter(STCref | STCconst, type, Id::p, NULL)); -+ parameters->push(new Parameter(STCref | STCconst, type, Id::q, NULL)); -+ TypeFunction *tf = new TypeFunction(parameters, Type::tint32, 0, LINKd); -+ tf = (TypeFunction *)tf->semantic(loc, sc); - -- Expression *e = new CallExp(0, -- new DotIdExp(0, -- new PtrExp(0, new CastExp(0, -- new IdentifierExp(0, Id::p), type->pointerTo()->constOf())), -- Id::eq), -- new PtrExp(0, new CastExp(0, -- new IdentifierExp(0, Id::q), type->pointerTo()->constOf()))); -+ Identifier *id = Lexer::idPool("__xopCmp"); -+ FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf); - -- fop->fbody = new ReturnStatement(0, e); -+ Expression *e1 = new IdentifierExp(loc, Id::p); -+ Expression *e2 = new IdentifierExp(loc, Id::q); -+ Expression *e = new CallExp(loc, new DotIdExp(loc, e1, Id::cmp), e2); - -- size_t index = members->dim; -- members->push(fop); -+ fop->fbody = new ReturnStatement(loc, e); - -- unsigned errors = global.startGagging(); // Do not report errors, even if the -- unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it. -- global.speculativeGag = global.gag; -+ unsigned errors = global.startGagging(); // Do not report errors - Scope *sc2 = sc->push(); - sc2->stc = 0; - sc2->linkage = LINKd; -- sc2->speculative = true; - - fop->semantic(sc2); - fop->semantic2(sc2); -- fop->semantic3(sc2); - - sc2->pop(); -- global.speculativeGag = oldspec; - if (global.endGagging(errors)) // if errors happened -- { -- members->remove(index); -- -- if (!xerreq) -- { -- Expression *e = new IdentifierExp(0, Id::empty); -- e = new DotIdExp(0, e, Id::object); -- e = new DotIdExp(0, e, Lexer::idPool("_xopEquals")); -- e = e->semantic(sc); -- Dsymbol *s = getDsymbol(e); -- FuncDeclaration *fd = s->isFuncDeclaration(); -- -- xerreq = fd; -- } -- fop = xerreq; -- } -- else -- fop->addMember(sc, this, 1); -+ fop = xerrcmp; - - return fop; - } - -- - /******************************************* - * Build copy constructor for struct. -+ * void __cpctpr(ref const S s) const [pure nothrow @trusted] -+ * { -+ * (*cast(S*)&this) = *cast(S*)s; -+ * (*cast(S*)&this).postBlit(); -+ * } -+ * - * Copy constructors are compiler generated only, and are only - * callable from the compiler. They are not user accessible. -- * A copy constructor is: -- * void cpctpr(ref const S s) const -- * { -- * (*cast(S*)&this) = *cast(S*)s; -- * (*cast(S*)&this).postBlit(); -- * } -+ * - * This is done so: - * - postBlit() never sees uninitialized data - * - memcpy can be much more efficient than memberwise copy -@@ -508,62 +694,59 @@ FuncDeclaration *StructDeclaration::buil - - FuncDeclaration *StructDeclaration::buildCpCtor(Scope *sc) - { -- //printf("StructDeclaration::buildCpCtor() %s\n", toChars()); -- FuncDeclaration *fcp = NULL; -- - /* Copy constructor is only necessary if there is a postblit function, - * otherwise the code generator will just do a bit copy. - */ -- if (postblit) -- { -- //printf("generating cpctor\n"); -- -- StorageClass stc = postblit->storage_class & -- (STCdisable | STCsafe | STCtrusted | STCsystem | STCpure | STCnothrow); -- if (stc & (STCsafe | STCtrusted)) -- stc = stc & ~STCsafe | STCtrusted; -- -- Parameters *fparams = new Parameters; -- fparams->push(new Parameter(STCref, type->constOf(), Id::p, NULL)); -- Type *ftype = new TypeFunction(fparams, Type::tvoid, FALSE, LINKd, stc); -- ftype->mod = MODconst; -- -- fcp = new FuncDeclaration(loc, 0, Id::cpctor, stc, ftype); -- -- if (!(fcp->storage_class & STCdisable)) -- { -- // Build *this = p; -- Expression *e = new ThisExp(0); -- AssignExp *ea = new AssignExp(0, -- new PtrExp(0, new CastExp(0, new AddrExp(0, e), type->mutableOf()->pointerTo())), -- new PtrExp(0, new CastExp(0, new AddrExp(0, new IdentifierExp(0, Id::p)), type->mutableOf()->pointerTo())) -- ); -- ea->op = TOKblit; -- Statement *s = new ExpStatement(0, ea); -- -- // Build postBlit(); -- e = new ThisExp(0); -- e = new PtrExp(0, new CastExp(0, new AddrExp(0, e), type->mutableOf()->pointerTo())); -- e = new DotVarExp(0, e, postblit, 0); -- e = new CallExp(0, e); -+ if (!postblit) -+ return NULL; - -- s = new CompoundStatement(0, s, new ExpStatement(0, e)); -- fcp->fbody = s; -- } -- else -- fcp->fbody = new ExpStatement(0, (Expression *)NULL); -+ //printf("StructDeclaration::buildCpCtor() %s\n", toChars()); -+ StorageClass stc = STCsafe | STCnothrow | STCpure; -+ Loc declLoc = postblit->loc; -+ Loc loc = Loc(); // internal code should have no loc to prevent coverage -+ -+ stc = mergeFuncAttrs(stc, postblit->storage_class); -+ if (stc & STCsafe) // change to @trusted for unsafe casts -+ stc = (stc & ~STCsafe) | STCtrusted; - -- members->push(fcp); -+ Parameters *fparams = new Parameters; -+ fparams->push(new Parameter(STCref, type->constOf(), Id::p, NULL)); -+ Type *tf = new TypeFunction(fparams, Type::tvoid, 0, LINKd, stc); -+ tf->mod = MODconst; - -- sc = sc->push(); -- sc->stc = 0; -- sc->linkage = LINKd; -+ FuncDeclaration *fcp = new FuncDeclaration(declLoc, Loc(), Id::cpctor, stc, tf); - -- fcp->semantic(sc); -+ if (!(stc & STCdisable)) -+ { -+ // Build *this = p; -+ Expression *e = new ThisExp(loc); -+ AssignExp *ea = new AssignExp(loc, -+ new PtrExp(loc, new CastExp(loc, new AddrExp(loc, e), type->mutableOf()->pointerTo())), -+ new PtrExp(loc, new CastExp(loc, new AddrExp(loc, new IdentifierExp(loc, Id::p)), type->mutableOf()->pointerTo())) -+ ); -+ ea->op = TOKblit; -+ Statement *s = new ExpStatement(loc, ea); -+ -+ // Build postBlit(); -+ e = new ThisExp(loc); -+ e = new PtrExp(loc, new CastExp(loc, new AddrExp(loc, e), type->mutableOf()->pointerTo())); -+ e = new DotVarExp(loc, e, postblit, 0); -+ e = new CallExp(loc, e); - -- sc->pop(); -+ s = new CompoundStatement(loc, s, new ExpStatement(loc, e)); -+ fcp->fbody = s; - } - -+ members->push(fcp); -+ -+ sc = sc->push(); -+ sc->stc = 0; -+ sc->linkage = LINKd; -+ -+ fcp->semantic(sc); -+ -+ sc->pop(); -+ - return fcp; - } - -@@ -579,30 +762,33 @@ FuncDeclaration *StructDeclaration::buil - FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc) - { - //printf("StructDeclaration::buildPostBlit() %s\n", toChars()); -- Expression *e = NULL; -- StorageClass stc = 0; -+ StorageClass stc = STCsafe | STCnothrow | STCpure; -+ Loc declLoc = postblits.dim ? postblits[0]->loc : this->loc; -+ Loc loc = Loc(); // internal code should have no loc to prevent coverage - -+ Expression *e = NULL; - for (size_t i = 0; i < fields.dim; i++) - { - Dsymbol *s = fields[i]; - VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -+ assert(v && v->isField()); - if (v->storage_class & STCref) - continue; - Type *tv = v->type->toBasetype(); - dinteger_t dim = 1; - while (tv->ty == Tsarray) -- { TypeSArray *ta = (TypeSArray *)tv; -- dim *= ((TypeSArray *)tv)->dim->toInteger(); -- tv = tv->nextOf()->toBasetype(); -+ { -+ TypeSArray *tsa = (TypeSArray *)tv; -+ dim *= tsa->dim->toInteger(); -+ tv = tsa->next->toBasetype(); - } - if (tv->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)tv; -+ { -+ TypeStruct *ts = (TypeStruct *)tv; - StructDeclaration *sd = ts->sym; - if (sd->postblit && dim) - { -- stc |= sd->postblit->storage_class & STCdisable; -- -+ stc = mergeFuncAttrs(stc, sd->postblit->storage_class); - if (stc & STCdisable) - { - e = NULL; -@@ -610,24 +796,24 @@ FuncDeclaration *StructDeclaration::buil - } - - // this.v -- Expression *ex = new ThisExp(0); -- ex = new DotVarExp(0, ex, v, 0); -+ Expression *ex = new ThisExp(loc); -+ ex = new DotVarExp(loc, ex, v, 0); - - if (v->type->toBasetype()->ty == Tstruct) - { // this.v.postblit() -- ex = new DotVarExp(0, ex, sd->postblit, 0); -- ex = new CallExp(0, ex); -+ ex = new DotVarExp(loc, ex, sd->postblit, 0); -+ ex = new CallExp(loc, ex); - } - else - { - // Typeinfo.postblit(cast(void*)&this.v); -- Expression *ea = new AddrExp(0, ex); -- ea = new CastExp(0, ea, Type::tvoid->pointerTo()); -+ Expression *ea = new AddrExp(loc, ex); -+ ea = new CastExp(loc, ea, Type::tvoid->pointerTo()); - - Expression *et = v->type->getTypeInfo(sc); -- et = new DotIdExp(0, et, Id::postblit); -+ et = new DotIdExp(loc, et, Id::postblit); - -- ex = new CallExp(0, et, ea); -+ ex = new CallExp(loc, et, ea); - } - e = Expression::combine(e, ex); // combine in forward order - } -@@ -638,8 +824,8 @@ FuncDeclaration *StructDeclaration::buil - */ - if (e || (stc & STCdisable)) - { //printf("Building __fieldPostBlit()\n"); -- PostBlitDeclaration *dd = new PostBlitDeclaration(loc, 0, stc, Lexer::idPool("__fieldPostBlit")); -- dd->fbody = new ExpStatement(0, e); -+ PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Lexer::idPool("__fieldPostBlit")); -+ dd->fbody = new ExpStatement(loc, e); - postblits.shift(dd); - members->push(dd); - dd->semantic(sc); -@@ -655,21 +841,23 @@ FuncDeclaration *StructDeclaration::buil - - default: - e = NULL; -+ stc = STCsafe | STCnothrow | STCpure; - for (size_t i = 0; i < postblits.dim; i++) -- { FuncDeclaration *fd = postblits[i]; -- stc |= fd->storage_class & STCdisable; -+ { -+ FuncDeclaration *fd = postblits[i]; -+ stc = mergeFuncAttrs(stc, fd->storage_class); - if (stc & STCdisable) - { - e = NULL; - break; - } -- Expression *ex = new ThisExp(0); -- ex = new DotVarExp(0, ex, fd, 0); -- ex = new CallExp(0, ex); -+ Expression *ex = new ThisExp(loc); -+ ex = new DotVarExp(loc, ex, fd, 0); -+ ex = new CallExp(loc, ex); - e = Expression::combine(e, ex); - } -- PostBlitDeclaration *dd = new PostBlitDeclaration(loc, 0, stc, Lexer::idPool("__aggrPostBlit")); -- dd->fbody = new ExpStatement(0, e); -+ PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Lexer::idPool("__aggrPostBlit")); -+ dd->fbody = new ExpStatement(loc, e); - members->push(dd); - dd->semantic(sc); - return dd; -@@ -689,48 +877,59 @@ FuncDeclaration *StructDeclaration::buil - FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc) - { - //printf("AggregateDeclaration::buildDtor() %s\n", toChars()); -- Expression *e = NULL; -+ StorageClass stc = STCsafe | STCnothrow | STCpure; -+ Loc declLoc = dtors.dim ? dtors[0]->loc : this->loc; -+ Loc loc = Loc(); // internal code should have no loc to prevent coverage - -+ Expression *e = NULL; - #if DMDV2 - for (size_t i = 0; i < fields.dim; i++) - { - Dsymbol *s = fields[i]; - VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -+ assert(v && v->isField()); - if (v->storage_class & STCref) - continue; - Type *tv = v->type->toBasetype(); - dinteger_t dim = 1; - while (tv->ty == Tsarray) -- { TypeSArray *ta = (TypeSArray *)tv; -- dim *= ((TypeSArray *)tv)->dim->toInteger(); -- tv = tv->nextOf()->toBasetype(); -+ { -+ TypeSArray *tsa = (TypeSArray *)tv; -+ dim *= tsa->dim->toInteger(); -+ tv = tsa->next->toBasetype(); - } - if (tv->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)tv; -+ { -+ TypeStruct *ts = (TypeStruct *)tv; - StructDeclaration *sd = ts->sym; - if (sd->dtor && dim) -- { Expression *ex; -+ { -+ stc = mergeFuncAttrs(stc, sd->dtor->storage_class); -+ if (stc & STCdisable) -+ { -+ e = NULL; -+ break; -+ } - - // this.v -- ex = new ThisExp(0); -- ex = new DotVarExp(0, ex, v, 0); -+ Expression *ex = new ThisExp(loc); -+ ex = new DotVarExp(loc, ex, v, 0); - - if (v->type->toBasetype()->ty == Tstruct) - { // this.v.dtor() -- ex = new DotVarExp(0, ex, sd->dtor, 0); -- ex = new CallExp(0, ex); -+ ex = new DotVarExp(loc, ex, sd->dtor, 0); -+ ex = new CallExp(loc, ex); - } - else - { - // Typeinfo.destroy(cast(void*)&this.v); -- Expression *ea = new AddrExp(0, ex); -- ea = new CastExp(0, ea, Type::tvoid->pointerTo()); -+ Expression *ea = new AddrExp(loc, ex); -+ ea = new CastExp(loc, ea, Type::tvoid->pointerTo()); - - Expression *et = v->type->getTypeInfo(sc); -- et = new DotIdExp(0, et, Id::destroy); -+ et = new DotIdExp(loc, et, Id::destroy); - -- ex = new CallExp(0, et, ea); -+ ex = new CallExp(loc, et, ea); - } - e = Expression::combine(ex, e); // combine in reverse order - } -@@ -739,10 +938,10 @@ FuncDeclaration *AggregateDeclaration::b - - /* Build our own "destructor" which executes e - */ -- if (e) -+ if (e || (stc & STCdisable)) - { //printf("Building __fieldDtor()\n"); -- DtorDeclaration *dd = new DtorDeclaration(loc, 0, Lexer::idPool("__fieldDtor")); -- dd->fbody = new ExpStatement(0, e); -+ DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Lexer::idPool("__fieldDtor")); -+ dd->fbody = new ExpStatement(loc, e); - dtors.shift(dd); - members->push(dd); - dd->semantic(sc); -@@ -759,19 +958,82 @@ FuncDeclaration *AggregateDeclaration::b - - default: - e = NULL; -+ stc = STCsafe | STCnothrow | STCpure; - for (size_t i = 0; i < dtors.dim; i++) -- { FuncDeclaration *fd = dtors[i]; -- Expression *ex = new ThisExp(0); -- ex = new DotVarExp(0, ex, fd, 0); -- ex = new CallExp(0, ex); -+ { -+ FuncDeclaration *fd = dtors[i]; -+ stc = mergeFuncAttrs(stc, fd->storage_class); -+ if (stc & STCdisable) -+ { -+ e = NULL; -+ break; -+ } -+ Expression *ex = new ThisExp(loc); -+ ex = new DotVarExp(loc, ex, fd, 0); -+ ex = new CallExp(loc, ex); - e = Expression::combine(ex, e); - } -- DtorDeclaration *dd = new DtorDeclaration(loc, 0, Lexer::idPool("__aggrDtor")); -- dd->fbody = new ExpStatement(0, e); -+ DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Lexer::idPool("__aggrDtor")); -+ dd->fbody = new ExpStatement(loc, e); - members->push(dd); - dd->semantic(sc); - return dd; - } - } - -+/****************************************** -+ * Create inclusive invariant for struct/class by aggregating -+ * all the invariants in invs[]. -+ * void __invariant() const [pure nothrow @trusted] -+ * { -+ * invs[0](), invs[1](), ...; -+ * } -+ */ -+ -+FuncDeclaration *AggregateDeclaration::buildInv(Scope *sc) -+{ -+ StorageClass stc = STCsafe | STCnothrow | STCpure; -+ Loc declLoc = this->loc; -+ Loc loc = Loc(); // internal code should have no loc to prevent coverage -+ -+ switch (invs.dim) -+ { -+ case 0: -+ return NULL; -+ -+ case 1: -+ // Don't return invs[0] so it has uniquely generated name. -+ /* fall through */ -+ -+ default: -+ Expression *e = NULL; -+ StorageClass stcx = 0; -+ for (size_t i = 0; i < invs.dim; i++) -+ { -+ stc = mergeFuncAttrs(stc, invs[i]->storage_class); -+ if (stc & STCdisable) -+ { -+ // What should do? -+ } -+ StorageClass stcy = invs[i]->storage_class & (STCshared | STCsynchronized); -+ if (i == 0) -+ stcx = stcy; -+ else if (stcx ^ stcy) -+ { -+ #if 1 // currently rejects -+ error(invs[i]->loc, "mixing invariants with shared/synchronized differene is not supported"); -+ e = NULL; -+ break; -+ #endif -+ } -+ e = Expression::combine(e, new CallExp(loc, new VarExp(loc, invs[i]))); -+ } -+ InvariantDeclaration *inv; -+ inv = new InvariantDeclaration(declLoc, Loc(), stc | stcx, Id::classInvariant); -+ inv->fbody = new ExpStatement(loc, e); -+ members->push(inv); -+ inv->semantic(sc); -+ return inv; -+ } -+} - ---- a/src/gcc/d/dfrontend/complex_t.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/complex_t.h 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,76 @@ -+ -+// Compiler implementation of the D programming language -+// Copyright (c) 1999-2006 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright and Burton Radons -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#ifndef DMD_COMPLEX_T_H -+#define DMD_COMPLEX_T_H -+ -+/* Roll our own complex type for compilers that don't support complex -+ */ -+ -+struct complex_t -+{ -+ longdouble re; -+ longdouble im; -+ -+ complex_t() { this->re = 0; this->im = 0; } -+ complex_t(longdouble re) { this->re = re; this->im = 0; } -+ complex_t(double re) { this->re = re; this->im = 0; } -+ complex_t(longdouble re, longdouble im) { this->re = re; this->im = im; } -+ complex_t(double re, double im) { this->re = re; this->im = im; } -+ -+ complex_t operator + (complex_t y) { complex_t r; r.re = re + y.re; r.im = im + y.im; return r; } -+ complex_t operator - (complex_t y) { complex_t r; r.re = re - y.re; r.im = im - y.im; return r; } -+ complex_t operator - () { complex_t r; r.re = -re; r.im = -im; return r; } -+ complex_t operator * (complex_t y) { return complex_t(re * y.re - im * y.im, im * y.re + re * y.im); } -+ -+ complex_t operator / (complex_t y) -+ { -+ longdouble abs_y_re = y.re < 0 ? -y.re : y.re; -+ longdouble abs_y_im = y.im < 0 ? -y.im : y.im; -+ longdouble r, den; -+ -+ if (abs_y_re < abs_y_im) -+ { -+ r = y.re / y.im; -+ den = y.im + r * y.re; -+ return complex_t((re * r + im) / den, -+ (im * r - re) / den); -+ } -+ else -+ { -+ r = y.im / y.re; -+ den = y.re + r * y.im; -+ return complex_t((re + r * im) / den, -+ (im - r * re) / den); -+ } -+ } -+ -+ operator bool () { return re || im; } -+ -+ int operator == (complex_t y) { return re == y.re && im == y.im; } -+ int operator != (complex_t y) { return re != y.re || im != y.im; } -+}; -+ -+inline complex_t operator * (longdouble x, complex_t y) { return complex_t(x) * y; } -+inline complex_t operator * (complex_t x, longdouble y) { return x * complex_t(y); } -+inline complex_t operator / (complex_t x, longdouble y) { return x / complex_t(y); } -+ -+ -+inline longdouble creall(complex_t x) -+{ -+ return x.re; -+} -+ -+inline longdouble cimagl(complex_t x) -+{ -+ return x.im; -+} -+ -+#endif ---- a/src/gcc/d/dfrontend/cond.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/cond.c 2014-04-01 16:32:51.000000000 +0100 -@@ -52,7 +52,7 @@ Condition::Condition(Loc loc) - /* ============================================================ */ - - DVCondition::DVCondition(Module *mod, unsigned level, Identifier *ident) -- : Condition(0) -+ : Condition(Loc()) - { - this->mod = mod; - this->level = level; -@@ -84,16 +84,41 @@ DebugCondition::DebugCondition(Module *m - { - } - -+// Helper for printing dependency information -+void printDepsConditional(Scope *sc, DVCondition* condition, const char* depType) -+{ -+ if (!global.params.moduleDeps || global.params.moduleDepsFile) -+ return; -+ OutBuffer *ob = global.params.moduleDeps; -+ Module* imod = sc ? (sc->instantiatingModule ? sc->instantiatingModule : sc->module) : condition->mod; -+ if (!imod) -+ return; -+ ob->writestring(depType); -+ ob->writestring(imod->toPrettyChars()); -+ ob->writestring(" ("); -+ escapePath(ob, imod->srcfile->toChars()); -+ ob->writestring(") : "); -+ if (condition->ident) -+ ob->printf("%s\n", condition->ident->toChars()); -+ else -+ ob->printf("%d\n", condition->level); -+} -+ -+ - int DebugCondition::include(Scope *sc, ScopeDsymbol *s) - { - //printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel); - if (inc == 0) - { - inc = 2; -+ bool definedInModule = false; - if (ident) - { - if (findCondition(mod->debugids, ident)) -+ { - inc = 1; -+ definedInModule = true; -+ } - else if (findCondition(global.params.debugids, ident)) - inc = 1; - else -@@ -104,6 +129,8 @@ int DebugCondition::include(Scope *sc, S - } - else if (level <= global.params.debuglevel || level <= mod->debuglevel) - inc = 1; -+ if (!definedInModule) -+ printDepsConditional(sc, this, "depsDebug "); - } - return (inc == 1); - } -@@ -123,24 +150,87 @@ void VersionCondition::setGlobalLevel(un - global.params.versionlevel = level; - } - --void VersionCondition::checkPredefined(Loc loc, const char *ident) -+bool VersionCondition::isPredefined(const char *ident) - { - static const char* reserved[] = - { -- "DigitalMars", "X86", "X86_64", -- "Windows", "Win32", "Win64", -+ "DigitalMars", -+ "GNU", -+ "LDC", -+ "SDC", -+ "Windows", -+ "Win32", -+ "Win64", - "linux", --#if DMDV2 -- /* Although Posix is predefined by D1, disallowing its -- * redefinition breaks makefiles and older builds. -- */ -- "Posix", -- "D_NET", --#endif -- "OSX", "FreeBSD", -+ "OSX", -+ "FreeBSD", - "OpenBSD", -+ "NetBSD", -+ "DragonFlyBSD", -+ "BSD", - "Solaris", -- "LittleEndian", "BigEndian", -+ "Posix", -+ "AIX", -+ "Haiku", -+ "SkyOS", -+ "SysV3", -+ "SysV4", -+ "Hurd", -+ "Android", -+ "Cygwin", -+ "MinGW", -+ "X86", -+ "X86_64", -+ "ARM", -+ "ARM_Thumb", -+ "ARM_SoftFloat", -+ "ARM_SoftFP", -+ "ARM_HardFloat", -+ "AArch64", -+ "PPC", -+ "PPC_SoftFloat", -+ "PPC_HardFloat", -+ "PPC64", -+ "IA64", -+ "MIPS32", -+ "MIPS64", -+ "MIPS_O32", -+ "MIPS_N32", -+ "MIPS_O64", -+ "MIPS_N64", -+ "MIPS_EABI", -+ "MIPS_SoftFloat", -+ "MIPS_HardFloat", -+ "SPARC", -+ "SPARC_V8Plus", -+ "SPARC_SoftFloat", -+ "SPARC_HardFloat", -+ "SPARC64", -+ "S390", -+ "S390X", -+ "HPPA", -+ "HPPA64", -+ "SH", -+ "SH64", -+ "Alpha", -+ "Alpha_SoftFloat", -+ "Alpha_HardFloat", -+ "LittleEndian", -+ "BigEndian", -+ "D_Coverage", -+ "D_Ddoc", -+ "D_InlineAsm_X86", -+ "D_InlineAsm_X86_64", -+ "D_LP64", -+ "D_X32", -+ "D_HardFloat", -+ "D_SoftFloat", -+ "D_PIC", -+ "D_SIMD", -+ "D_Version2", -+ "D_NoBoundsChecks", -+ "unittest", -+ "assert", - "all", - "none", - }; -@@ -148,21 +238,17 @@ void VersionCondition::checkPredefined(L - for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++) - { - if (strcmp(ident, reserved[i]) == 0) -- goto Lerror; -+ return true; - } - - if (ident[0] == 'D' && ident[1] == '_') -- goto Lerror; -- -- return; -- -- Lerror: -- error(loc, "version identifier '%s' is reserved and cannot be set", ident); -+ return true; -+ return false; - } - - void VersionCondition::addGlobalIdent(const char *ident) - { -- checkPredefined(0, ident); -+ checkPredefined(Loc(), ident); - addPredefinedGlobalIdent(ident); - } - -@@ -186,10 +272,14 @@ int VersionCondition::include(Scope *sc, - if (inc == 0) - { - inc = 2; -+ bool definedInModule=false; - if (ident) - { - if (findCondition(mod->versionids, ident)) -+ { - inc = 1; -+ definedInModule = true; -+ } - else if (findCondition(global.params.versionids, ident)) - inc = 1; - else -@@ -201,6 +291,8 @@ int VersionCondition::include(Scope *sc, - } - else if (level <= global.params.versionlevel || level <= mod->versionlevel) - inc = 1; -+ if (!definedInModule && (!ident || (!isPredefined(ident->toChars()) && ident != Lexer::idPool(Token::toChars(TOKunittest)) && ident != Lexer::idPool(Token::toChars(TOKassert))))) -+ printDepsConditional(sc, this, "depsVersion "); - } - return (inc == 1); - } -@@ -243,9 +335,7 @@ int StaticIfCondition::include(Scope *sc - { - error(loc, (nest > 1000) ? "unresolvable circular static if expression" - : "error evaluating static if expression"); -- if (!global.gag) -- inc = 2; // so we don't see the error message again -- return 0; -+ goto Lerror; - } - - if (!sc) -@@ -259,21 +349,25 @@ int StaticIfCondition::include(Scope *sc - sc = sc->push(sc->scopesym); - sc->sd = s; // s gets any addMember() - sc->flags |= SCOPEstaticif; -+ -+ sc = sc->startCTFE(); - Expression *e = exp->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); -+ - sc->pop(); -+ --nest; -+ - if (!e->type->checkBoolean()) - { - if (e->type->toBasetype() != Type::terror) - exp->error("expression %s of type %s does not have a boolean value", exp->toChars(), e->type->toChars()); -- inc = 0; -- return 0; -+ goto Lerror; - } - e = e->ctfeInterpret(); -- --nest; - if (e->op == TOKerror) -- { exp = e; -- inc = 0; -+ { -+ goto Lerror; - } - else if (e->isBool(TRUE)) - inc = 1; -@@ -282,144 +376,20 @@ int StaticIfCondition::include(Scope *sc - else - { - e->error("expression %s is not constant or does not evaluate to a bool", e->toChars()); -- inc = 2; -+ goto Lerror; - } - } - return (inc == 1); -+ -+Lerror: -+ if (!global.gag) -+ inc = 2; // so we don't see the error message again -+ return 0; - } - - void StaticIfCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { -- buf->writestring("static if("); -+ buf->writestring("static if ("); - exp->toCBuffer(buf, hgs); - buf->writeByte(')'); - } -- -- --/**************************** IftypeCondition *******************************/ -- --IftypeCondition::IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec) -- : Condition(loc) --{ -- this->targ = targ; -- this->id = id; -- this->tok = tok; -- this->tspec = tspec; --} -- --Condition *IftypeCondition::syntaxCopy() --{ -- return new IftypeCondition(loc, -- targ->syntaxCopy(), -- id, -- tok, -- tspec ? tspec->syntaxCopy() : NULL); --} -- --int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd) --{ -- //printf("IftypeCondition::include()\n"); -- if (inc == 0) -- { -- if (!sc) -- { -- error(loc, "iftype conditional cannot be at global scope"); -- inc = 2; -- return 0; -- } -- Type *t = targ->trySemantic(loc, sc); -- if (t) -- targ = t; -- else -- inc = 2; // condition is false -- -- if (!t) -- { -- } -- else if (id && tspec) -- { -- /* Evaluate to TRUE if targ matches tspec. -- * If TRUE, declare id as an alias for the specialized type. -- */ -- -- MATCH m; -- TemplateTypeParameter tp(loc, id, NULL, NULL); -- -- TemplateParameters parameters; -- parameters.setDim(1); -- parameters[0] = &tp; -- -- Objects dedtypes; -- dedtypes.setDim(1); -- -- m = targ->deduceType(sc, tspec, ¶meters, &dedtypes); -- if (m == MATCHnomatch || -- (m != MATCHexact && tok == TOKequal)) -- inc = 2; -- else -- { -- inc = 1; -- Type *tded = (Type *)dedtypes[0]; -- if (!tded) -- tded = targ; -- Dsymbol *s = new AliasDeclaration(loc, id, tded); -- s->semantic(sc); -- sc->insert(s); -- if (sd) -- s->addMember(sc, sd, 1); -- } -- } -- else if (id) -- { -- /* Declare id as an alias for type targ. Evaluate to TRUE -- */ -- Dsymbol *s = new AliasDeclaration(loc, id, targ); -- s->semantic(sc); -- sc->insert(s); -- if (sd) -- s->addMember(sc, sd, 1); -- inc = 1; -- } -- else if (tspec) -- { -- /* Evaluate to TRUE if targ matches tspec -- */ -- tspec = tspec->semantic(loc, sc); -- //printf("targ = %s\n", targ->toChars()); -- //printf("tspec = %s\n", tspec->toChars()); -- if (tok == TOKcolon) -- { if (targ->implicitConvTo(tspec)) -- inc = 1; -- else -- inc = 2; -- } -- else /* == */ -- { if (targ->equals(tspec)) -- inc = 1; -- else -- inc = 2; -- } -- } -- else -- inc = 1; -- //printf("inc = %d\n", inc); -- } -- return (inc == 1); --} -- --void IftypeCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs) --{ -- buf->writestring("iftype("); -- targ->toCBuffer(buf, id, hgs); -- if (tspec) -- { -- if (tok == TOKcolon) -- buf->writestring(" : "); -- else -- buf->writestring(" == "); -- tspec->toCBuffer(buf, NULL, hgs); -- } -- buf->writeByte(')'); --} -- -- ---- a/src/gcc/d/dfrontend/cond.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/cond.h 2014-04-01 16:32:51.000000000 +0100 -@@ -11,21 +11,22 @@ - #ifndef DMD_DEBCOND_H - #define DMD_DEBCOND_H - --struct Expression; --struct Identifier; -+class Expression; -+class Identifier; - struct OutBuffer; --struct Module; -+class Module; - struct Scope; --struct ScopeDsymbol; --struct DebugCondition; -+class ScopeDsymbol; -+class DebugCondition; - #include "lexer.h" // dmdhg - enum TOK; - struct HdrGenState; - - int findCondition(Strings *ids, Identifier *ident); - --struct Condition -+class Condition - { -+public: - Loc loc; - int inc; // 0: not computed yet - // 1: include -@@ -39,8 +40,9 @@ struct Condition - virtual DebugCondition *isDebugCondition() { return NULL; } - }; - --struct DVCondition : Condition -+class DVCondition : public Condition - { -+public: - unsigned level; - Identifier *ident; - Module *mod; -@@ -50,11 +52,11 @@ struct DVCondition : Condition - Condition *syntaxCopy(); - }; - --struct DebugCondition : DVCondition -+class DebugCondition : public DVCondition - { -+public: - static void setGlobalLevel(unsigned level); - static void addGlobalIdent(const char *ident); -- static void addPredefinedGlobalIdent(const char *ident); - - DebugCondition(Module *mod, unsigned level, Identifier *ident); - -@@ -63,10 +65,16 @@ struct DebugCondition : DVCondition - DebugCondition *isDebugCondition() { return this; } - }; - --struct VersionCondition : DVCondition -+class VersionCondition : public DVCondition - { -+public: - static void setGlobalLevel(unsigned level); -- static void checkPredefined(Loc loc, const char *ident); -+ static bool isPredefined(const char *ident); -+ static void checkPredefined(Loc loc, const char *ident) -+ { -+ if (isPredefined(ident)) -+ error(loc, "version identifier '%s' is reserved and cannot be set", ident); -+ } - static void addGlobalIdent(const char *ident); - static void addPredefinedGlobalIdent(const char *ident); - -@@ -76,8 +84,9 @@ struct VersionCondition : DVCondition - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct StaticIfCondition : Condition -+class StaticIfCondition : public Condition - { -+public: - Expression *exp; - int nest; // limit circular dependencies - -@@ -87,20 +96,4 @@ struct StaticIfCondition : Condition - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct IftypeCondition : Condition --{ -- /* iftype (targ id tok tspec) -- */ -- Type *targ; -- Identifier *id; // can be NULL -- enum TOK tok; // ':' or '==' -- Type *tspec; // can be NULL -- -- IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec); -- Condition *syntaxCopy(); -- int include(Scope *sc, ScopeDsymbol *s); -- void toCBuffer(OutBuffer *buf, HdrGenState *hgs); --}; -- -- - #endif ---- a/src/gcc/d/dfrontend/constfold.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/constfold.c 2014-04-01 16:32:51.000000000 +0100 -@@ -326,11 +326,7 @@ Expression *Mul(Type *type, Expression * - - if (type->isfloating()) - { complex_t c; --#ifdef IN_GCC -- real_t r; --#else - d_float80 r; --#endif - - if (e1->type->isreal()) - { -@@ -397,11 +393,7 @@ Expression *Div(Type *type, Expression * - - if (type->isfloating()) - { complex_t c; --#ifdef IN_GCC -- real_t r; --#else - d_float80 r; --#endif - - //e1->type->print(); - //e2->type->print(); -@@ -578,8 +570,8 @@ Expression *Pow(Type *type, Expression * - } - else - { -- r = new RealExp(loc, e1->toReal(), Type::tfloat64); -- v = new RealExp(loc, ldouble(1.0), Type::tfloat64); -+ r = new IntegerExp(loc, e1->toInteger(), e1->type); -+ v = new IntegerExp(loc, 1, e1->type); - } - - while (n != 0) -@@ -603,7 +595,7 @@ Expression *Pow(Type *type, Expression * - // x ^^ y for x < 0 and y not an integer is not defined - if (e1->toReal() < 0.0) - { -- e = new RealExp(loc, ldouble(Port::nan), type); -+ e = new RealExp(loc, Port::ldbl_nan, type); - } - else if (e2->toReal() == 0.5) - { -@@ -753,7 +745,7 @@ Expression *Xor(Type *type, Expression * - - /* Also returns EXP_CANT_INTERPRET if cannot be computed. - */ --Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) -+Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2) - { Expression *e; - Loc loc = e1->loc; - int cmp; -@@ -951,7 +943,7 @@ Expression *Equal(enum TOK op, Type *typ - return e; - } - --Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) -+Expression *Identity(TOK op, Type *type, Expression *e1, Expression *e2) - { - Loc loc = e1->loc; - int cmp; -@@ -998,7 +990,7 @@ Expression *Identity(enum TOK op, Type * - } - - --Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) -+Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2) - { Expression *e; - Loc loc = e1->loc; - dinteger_t n; -@@ -1222,7 +1214,7 @@ Expression *Cast(Type *type, Type *to, E - } - - if (e1->op == TOKarrayliteral && typeb == tb) -- return e1; -+ return expType(to, e1); - - if (e1->isConst() != 1) - return EXP_CANT_INTERPRET; -@@ -1233,23 +1225,7 @@ Expression *Cast(Type *type, Type *to, E - { - if (e1->type->isfloating()) - { dinteger_t result; --#ifdef IN_GCC -- Type * rt = e1->type; -- if (rt->iscomplex()) -- { -- switch (rt->toBasetype()->ty) -- { -- case Tcomplex32: rt = Type::tfloat32; break; -- case Tcomplex64: rt = Type::tfloat64; break; -- case Tcomplex80: rt = Type::tfloat80; break; -- default: -- assert(0); -- } -- } -- d_int64 r = e1->toReal().toInt(rt, type); --#else - real_t r = e1->toReal(); --#endif - - switch (typeb->ty) - { -@@ -1345,6 +1321,8 @@ Expression *ArrayLength(Type *type, Expr - - e = new IntegerExp(loc, dim, type); - } -+ else if (e1->type->toBasetype()->ty == Tsarray) -+ e = ((TypeSArray *)e1->type->toBasetype())->dim; - else - e = EXP_CANT_INTERPRET; - return e; -@@ -1386,6 +1364,7 @@ Expression *Index(Type *type, Expression - { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; - e = (*ale->elements)[i]; - e->type = type; -+ e->loc = loc; - if (e->hasSideEffect()) - e = EXP_CANT_INTERPRET; - } -@@ -1404,6 +1383,7 @@ Expression *Index(Type *type, Expression - else - { e = (*ale->elements)[i]; - e->type = type; -+ e->loc = loc; - if (e->hasSideEffect()) - e = EXP_CANT_INTERPRET; - } -@@ -1424,6 +1404,7 @@ Expression *Index(Type *type, Expression - if (ex->isBool(TRUE)) - { e = (*ae->values)[i]; - e->type = type; -+ e->loc = loc; - if (e->hasSideEffect()) - e = EXP_CANT_INTERPRET; - break; -@@ -1465,12 +1446,12 @@ Expression *Slice(Type *type, Expression - StringExp *es; - - s = mem.malloc((len + 1) * sz); -- memcpy((unsigned char *)s, (unsigned char *)es1->string + ilwr * sz, len * sz); -- memset((unsigned char *)s + len * sz, 0, sz); -+ memcpy((utf8_t *)s, (utf8_t *)es1->string + ilwr * sz, len * sz); -+ memset((utf8_t *)s + len * sz, 0, sz); - - es = new StringExp(loc, s, len, es1->postfix); - es->sz = sz; -- es->committed = 1; -+ es->committed = es1->committed; - es->type = type; - e = es; - } -@@ -1508,7 +1489,7 @@ void sliceAssignArrayLiteralFromString(A - { - size_t newlen = newval->len; - size_t sz = newval->sz; -- unsigned char *s = (unsigned char *)newval->string; -+ utf8_t *s = (utf8_t *)newval->string; - Type *elemType = existingAE->type->nextOf(); - for (size_t j = 0; j < newlen; j++) - { -@@ -1532,7 +1513,7 @@ void sliceAssignArrayLiteralFromString(A - */ - void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex) - { -- unsigned char *s = (unsigned char *)existingSE->string; -+ utf8_t *s = (utf8_t *)existingSE->string; - for (size_t j = 0; j < newae->elements->dim; j++) - { - unsigned value = (unsigned)((*newae->elements)[j]->toInteger()); -@@ -1553,7 +1534,7 @@ void sliceAssignStringFromArrayLiteral(S - */ - void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex) - { -- unsigned char *s = (unsigned char *)existingSE->string; -+ utf8_t *s = (utf8_t *)existingSE->string; - size_t sz = existingSE->sz; - assert(sz == newstr->sz); - memcpy(s + firstIndex * sz, newstr->string, sz * newstr->len); -@@ -1564,8 +1545,8 @@ void sliceAssignStringFromString(StringE - */ - int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len) - { -- unsigned char *s1 = (unsigned char *)se1->string; -- unsigned char *s2 = (unsigned char *)se2->string; -+ utf8_t *s1 = (utf8_t *)se1->string; -+ utf8_t *s2 = (utf8_t *)se2->string; - size_t sz = se1->sz; - assert(sz == se2->sz); - -@@ -1577,11 +1558,9 @@ int sliceCmpStringWithString(StringExp * - */ - int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len) - { -- unsigned char *s = (unsigned char *)se1->string; -+ utf8_t *s = (utf8_t *)se1->string; - size_t sz = se1->sz; - -- int c = 0; -- - for (size_t j = 0; j < len; j++) - { - unsigned value = (unsigned)((*ae2->elements)[j + lo2]->toInteger()); -@@ -1637,12 +1616,12 @@ Expression *Cat(Type *type, Expression * - size_t len = (t->ty == tn->ty) ? 1 : utf_codeLength(sz, v); - s = mem.malloc((len + 1) * sz); - if (t->ty == tn->ty) -- memcpy((unsigned char *)s, &v, sz); -+ memcpy((utf8_t *)s, &v, sz); - else - utf_encode(sz, s, v); - - // Add terminating 0 -- memset((unsigned char *)s + len * sz, 0, sz); -+ memset((utf8_t *)s + len * sz, 0, sz); - - es = new StringExp(loc, s, len); - es->sz = sz; -@@ -1696,10 +1675,10 @@ Expression *Cat(Type *type, Expression * - } - s = mem.malloc((len + 1) * sz); - memcpy(s, es1->string, es1->len * sz); -- memcpy((unsigned char *)s + es1->len * sz, es2->string, es2->len * sz); -+ memcpy((utf8_t *)s + es1->len * sz, es2->string, es2->len * sz); - - // Add terminating 0 -- memset((unsigned char *)s + len * sz, 0, sz); -+ memset((utf8_t *)s + len * sz, 0, sz); - - es = new StringExp(loc, s, len); - es->sz = sz; -@@ -1761,12 +1740,12 @@ Expression *Cat(Type *type, Expression * - s = mem.malloc((len + 1) * sz); - memcpy(s, es1->string, es1->len * sz); - if (homoConcat) -- memcpy((unsigned char *)s + (sz * es1->len), &v, sz); -+ memcpy((utf8_t *)s + (sz * es1->len), &v, sz); - else -- utf_encode(sz, (unsigned char *)s + (sz * es1->len), v); -+ utf_encode(sz, (utf8_t *)s + (sz * es1->len), v); - - // Add terminating 0 -- memset((unsigned char *)s + len * sz, 0, sz); -+ memset((utf8_t *)s + len * sz, 0, sz); - - es = new StringExp(loc, s, len); - es->sz = sz; -@@ -1785,11 +1764,11 @@ Expression *Cat(Type *type, Expression * - dinteger_t v = e1->toInteger(); - - s = mem.malloc((len + 1) * sz); -- memcpy((unsigned char *)s, &v, sz); -- memcpy((unsigned char *)s + sz, es2->string, es2->len * sz); -+ memcpy((utf8_t *)s, &v, sz); -+ memcpy((utf8_t *)s + sz, es2->string, es2->len * sz); - - // Add terminating 0 -- memset((unsigned char *)s + len * sz, 0, sz); -+ memset((utf8_t *)s + len * sz, 0, sz); - - es = new StringExp(loc, s, len); - es->sz = sz; -@@ -1810,8 +1789,7 @@ Expression *Cat(Type *type, Expression * - - if (type->toBasetype()->ty == Tsarray) - { -- e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es1->elements->dim, Type::tindex)); -- e->type = e->type->semantic(loc, NULL); -+ e->type = TypeSArray::makeType(loc, t1->nextOf(), es1->elements->dim); - } - else - e->type = type; -@@ -1835,8 +1813,7 @@ Expression *Cat(Type *type, Expression * - - if (type->toBasetype()->ty == Tsarray) - { -- e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es->elements->dim, Type::tindex)); -- e->type = e->type->semantic(loc, NULL); -+ e->type = TypeSArray::makeType(loc, t1->nextOf(), es->elements->dim); - } - else - e->type = type; -@@ -1858,8 +1835,7 @@ Expression *Cat(Type *type, Expression * - - if (type->toBasetype()->ty == Tsarray) - { -- e->type = new TypeSArray(e2->type, new IntegerExp(loc, es1->elements->dim, Type::tindex)); -- e->type = e->type->semantic(loc, NULL); -+ e->type = TypeSArray::makeType(loc, e2->type, es1->elements->dim); - } - else - e->type = type; -@@ -1875,8 +1851,7 @@ Expression *Cat(Type *type, Expression * - - if (type->toBasetype()->ty == Tsarray) - { -- e->type = new TypeSArray(e1->type, new IntegerExp(loc, es2->elements->dim, Type::tindex)); -- e->type = e->type->semantic(loc, NULL); -+ e->type = TypeSArray::makeType(loc, e1->type, es2->elements->dim); - } - else - e->type = type; ---- a/src/gcc/d/dfrontend/cppmangle.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/cppmangle.c 2014-04-01 16:32:51.000000000 +0100 -@@ -129,16 +129,24 @@ void cpp_mangle_name(OutBuffer *buf, Cpp - buf->writeByte('N'); - - FuncDeclaration *fd = s->isFuncDeclaration(); -- if (!fd) -+ VarDeclaration *vd = s->isVarDeclaration(); -+ if (fd && fd->type->isConst()) - { -- s->error("C++ static variables not supported"); -- } -- else if (fd->type->isConst()) - buf->writeByte('K'); -- -- prefix_name(buf, cms, p); -- source_name(buf, s); -- -+ } -+ if (vd && !(vd->storage_class & (STCextern | STCgshared))) -+ { -+ s->error("C++ static non- __gshared non-extern variables not supported"); -+ } -+ if (vd || fd) -+ { -+ prefix_name(buf, cms, p); -+ source_name(buf, s); -+ } -+ else -+ { -+ assert(0); -+ } - buf->writeByte('E'); - } - else -@@ -402,11 +410,17 @@ void TypeTypedef::toCppMangle(OutBuffer - - void TypeClass::toCppMangle(OutBuffer *buf, CppMangleState *cms) - { -- if (!cms->substitute(buf, this)) -- { buf->writeByte('P'); -+ if (!cms->exist(this)) -+ { -+ buf->writeByte('P'); -+ - if (!cms->substitute(buf, sym)) - cpp_mangle_name(buf, cms, sym); -+ -+ cms->store(this); - } -+ else -+ cms->substitute(buf, this); - } - - struct ArgsCppMangleCtx -@@ -420,7 +434,7 @@ static int argsCppMangleDg(void *ctx, si - { - ArgsCppMangleCtx *p = (ArgsCppMangleCtx *)ctx; - -- Type *t = arg->type; -+ Type *t = arg->type->merge2(); - if (arg->storageClass & (STCout | STCref)) - t = t->referenceTo(); - else if (arg->storageClass & STClazy) -@@ -430,7 +444,7 @@ static int argsCppMangleDg(void *ctx, si - t = t->merge(); - } - if (t->ty == Tsarray) -- { // Mangle static arrays as pointers -+ { // Mangle static arrays as pointers. - t = t->pointerTo(); - } - ---- a/src/gcc/d/dfrontend/ctfeexpr.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/ctfeexpr.c 2014-04-01 16:32:51.000000000 +0100 -@@ -44,9 +44,9 @@ Expression *ClassReferenceExp::interpret - return this; - } - --char *ClassReferenceExp::toChars() -+void ClassReferenceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { -- return value->toChars(); -+ buf->writestring(value->toChars()); - } - - ClassDeclaration *ClassReferenceExp::originalClass() -@@ -160,8 +160,10 @@ char *ThrownExceptionExp::toChars() - // Generate an error message when this exception is not caught - void ThrownExceptionExp::generateUncaughtError() - { -- thrown->error("Uncaught CTFE exception %s(%s)", thrown->type->toChars(), -- thrown->value->elements->tdata()[0]->toChars()); -+ Expression *e = (*thrown->value->elements)[0]; -+ StringExp* se = e->toString(); -+ thrown->error("Uncaught CTFE exception %s(%s)", thrown->type->toChars(), se ? se->toChars() : e->toChars()); -+ - /* Also give the line where the throw statement was. We won't have it - * in the case where the ThrowStatement is generated internally - * (eg, in ScopeStatement) -@@ -174,6 +176,8 @@ void ThrownExceptionExp::generateUncaugh - // True if 'e' is EXP_CANT_INTERPRET, or an exception - bool exceptionOrCantInterpret(Expression *e) - { -+ assert(EXP_CANT_INTERPRET && "EXP_CANT_INTERPRET must be distinct from " -+ "null, Expression::init not called?"); - if (e == EXP_CANT_INTERPRET) return true; - if (!e || e == EXP_GOTO_INTERPRET || e == EXP_VOID_INTERPRET - || e == EXP_BREAK_INTERPRET || e == EXP_CONTINUE_INTERPRET) -@@ -229,7 +233,7 @@ Expressions *copyLiteralArray(Expression - Expressions *newelems = new Expressions(); - newelems->setDim(oldelems->dim); - for (size_t i = 0; i < oldelems->dim; i++) -- newelems->tdata()[i] = copyLiteral(oldelems->tdata()[i]); -+ (*newelems)[i] = copyLiteral((*oldelems)[i]); - return newelems; - } - -@@ -240,8 +244,7 @@ Expression *copyLiteral(Expression *e) - if (e->op == TOKstring) // syntaxCopy doesn't make a copy for StringExp! - { - StringExp *se = (StringExp *)e; -- unsigned char *s; -- s = (unsigned char *)mem.calloc(se->len + 1, se->sz); -+ utf8_t *s = (utf8_t *)mem.calloc(se->len + 1, se->sz); - memcpy(s, se->string, se->len * se->sz); - StringExp *se2 = new StringExp(se->loc, s, se->len); - se2->committed = se->committed; -@@ -281,7 +284,7 @@ Expression *copyLiteral(Expression *e) - newelems->setDim(oldelems->dim); - for (size_t i = 0; i < newelems->dim; i++) - { -- Expression *m = oldelems->tdata()[i]; -+ Expression *m = (*oldelems)[i]; - // We need the struct definition to detect block assignment - AggregateDeclaration *sd = se->sd; - Dsymbol *s = sd->fields[i]; -@@ -301,7 +304,7 @@ Expression *copyLiteral(Expression *e) - } - else if (v->type->ty != Tarray && v->type->ty!=Taarray) // NOTE: do not copy array references - m = copyLiteral(m); -- newelems->tdata()[i] = m; -+ (*newelems)[i] = m; - } - #if DMDV2 - StructLiteralExp *r = new StructLiteralExp(e->loc, se->sd, newelems, se->stype); -@@ -310,6 +313,7 @@ Expression *copyLiteral(Expression *e) - #endif - r->type = e->type; - r->ownedByCtfe = true; -+ r->origin = ((StructLiteralExp*)e)->origin; - return r; - } - else if (e->op == TOKfunction || e->op == TOKdelegate -@@ -317,7 +321,7 @@ Expression *copyLiteral(Expression *e) - || e->op == TOKvar - || e->op == TOKint64 || e->op == TOKfloat64 - || e->op == TOKchar || e->op == TOKcomplex80 -- || e->op == TOKvoid) -+ || e->op == TOKvoid || e->op == TOKvector) - { // Simple value types - Expression *r = e->syntaxCopy(); - r->type = e->type; -@@ -331,12 +335,12 @@ Expression *copyLiteral(Expression *e) - else if (e->op == TOKindex) - r = new IndexExp(e->loc, ((IndexExp *)e)->e1, ((IndexExp *)e)->e2); - else if (e->op == TOKdotvar) -- r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1, -- ((DotVarExp *)e)->var - #if DMDV2 -- , ((DotVarExp *)e)->hasOverloads -+ r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1, -+ ((DotVarExp *)e)->var, ((DotVarExp *)e)->hasOverloads); -+#else -+ r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1, ((DotVarExp *)e)->var); - #endif -- ); - else - assert(0); - r->type = e->type; -@@ -351,6 +355,8 @@ Expression *copyLiteral(Expression *e) - } - else if (e->op == TOKclassreference) - return new ClassReferenceExp(e->loc, ((ClassReferenceExp *)e)->value, e->type); -+ else if (e->op == TOKerror) -+ return e; - else - { - e->error("Internal Compiler Error: CTFE literal %s", e->toChars()); -@@ -367,8 +373,13 @@ Expression *copyLiteral(Expression *e) - */ - Expression *paintTypeOntoLiteral(Type *type, Expression *lit) - { -- if (lit->type == type) -+ if (lit->type->equals(type)) -+ return lit; -+ -+ // If it is a cast to inout, retain the original type. -+ if (type->hasWild()) - return lit; -+ - Expression *e; - if (lit->op == TOKslice) - { -@@ -383,13 +394,13 @@ Expression *paintTypeOntoLiteral(Type *t - else if (lit->op == TOKarrayliteral) - { - e = new SliceExp(lit->loc, lit, -- new IntegerExp(0, 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit)); -+ new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit)); - } - else if (lit->op == TOKstring) - { - // For strings, we need to introduce another level of indirection - e = new SliceExp(lit->loc, lit, -- new IntegerExp(0, 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit)); -+ new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit)); - } - else if (lit->op == TOKassocarrayliteral) - { -@@ -458,6 +469,13 @@ ArrayLiteralExp *createBlockDuplicatedAr - { - Expressions *elements = new Expressions(); - elements->setDim(dim); -+ if (type->ty == Tsarray && type->nextOf()->ty == Tsarray && -+ elem->type->ty != Tsarray) -+ { -+ // If it is a multidimensional array literal, do it recursively -+ elem = createBlockDuplicatedArrayLiteral(loc, type->nextOf(), elem, -+ ((TypeSArray *)type->nextOf())->dim->toInteger()); -+ } - bool mustCopy = needToCopyLiteral(elem); - for (size_t i = 0; i < dim; i++) - { if (mustCopy) -@@ -477,8 +495,7 @@ ArrayLiteralExp *createBlockDuplicatedAr - StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type, - unsigned value, size_t dim, int sz) - { -- unsigned char *s; -- s = (unsigned char *)mem.calloc(dim + 1, sz); -+ utf8_t *s = (utf8_t *)mem.calloc(dim + 1, sz); - for (size_t elemi = 0; elemi < dim; ++elemi) - { - switch (sz) -@@ -529,13 +546,23 @@ TypeAArray *toBuiltinAAType(Type *t) - assert(sym->ident == Id::AssociativeArray); - TemplateInstance *tinst = sym->parent->isTemplateInstance(); - assert(tinst); -- return new TypeAArray((Type *)(tinst->tiargs->tdata()[1]), (Type *)(tinst->tiargs->tdata()[0])); -+ return new TypeAArray((Type *)(*tinst->tiargs)[1], (Type *)(*tinst->tiargs)[0]); - #else - assert(0); - return NULL; - #endif - } - -+/************** TypeInfo operations ************************************/ -+ -+// Return true if type is TypeInfo_Class -+bool isTypeInfo_Class(Type *type) -+{ -+ return type->ty == Tclass && -+ (( Type::dtypeinfo == ((TypeClass*)type)->sym) -+ || Type::dtypeinfo->isBaseOf(((TypeClass*)type)->sym, NULL)); -+} -+ - /************** Pointer operations ************************************/ - - // Return true if t is a pointer (not a function pointer) -@@ -557,20 +584,36 @@ int isTrueBool(Expression *e) - * destPointee may be void. - */ - bool isSafePointerCast(Type *srcPointee, Type *destPointee) --{ // It's OK if both are the same (modulo const) -+{ -+ // It's safe to cast S** to D** if it's OK to cast S* to D* -+ while (srcPointee->ty == Tpointer && destPointee->ty == Tpointer) -+ { -+ srcPointee = srcPointee->nextOf(); -+ destPointee = destPointee->nextOf(); -+ } -+ - #if DMDV2 -- if (srcPointee->castMod(0) == destPointee->castMod(0)) -- return true; --#else -+ // It's OK if both are the same (modulo const) -+ srcPointee = srcPointee->castMod(0); -+ destPointee = destPointee->castMod(0); -+#endif - if (srcPointee == destPointee) - return true; --#endif -+ -+ // It's OK if function pointers differ only in safe/pure/nothrow -+ if (srcPointee->ty == Tfunction && destPointee->ty == Tfunction) -+ return srcPointee->covariant(destPointee) == 1; -+ - // it's OK to cast to void* - if (destPointee->ty == Tvoid) - return true; -- // It's OK if they are the same size integers, eg int* and uint* -- return srcPointee->isintegral() && destPointee->isintegral() -- && srcPointee->size() == destPointee->size(); -+ -+ // It's OK if they are the same size (static array of) integers, eg: -+ // int* --> uint* -+ // int[5][] --> uint[5][] -+ return srcPointee->baseElemOf()->isintegral() && -+ destPointee->baseElemOf()->isintegral() && -+ srcPointee->size() == destPointee->size(); - } - - Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs) -@@ -578,6 +621,8 @@ Expression *getAggregateFromPointer(Expr - *ofs = 0; - if (e->op == TOKaddress) - e = ((AddrExp *)e)->e1; -+ if (e->op == TOKsymoff) -+ *ofs = ((SymOffExp *)e)->offset; - if (e->op == TOKdotvar) - { - Expression *ex = ((DotVarExp *)e)->e1; -@@ -590,7 +635,7 @@ Expression *getAggregateFromPointer(Expr - i = ((ClassReferenceExp *)ex)->getFieldIndex(e->type, v->offset); - else - i = se->getFieldIndex(e->type, v->offset); -- e = se->elements->tdata()[i]; -+ e = (*se->elements)[i]; - } - if (e->op == TOKindex) - { -@@ -611,11 +656,19 @@ Expression *getAggregateFromPointer(Expr - */ - bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2) - { -+ // For integers cast to pointers, we regard them as non-comparable -+ // unless they are identical. (This may be overly strict). -+ if (agg1->op == TOKint64 && agg2->op == TOKint64 -+ && agg1->toInteger() == agg2->toInteger()) -+ return true; -+ - // Note that type painting can occur with VarExp, so we - // must compare the variables being pointed to. - return agg1 == agg2 || - (agg1->op == TOKvar && agg2->op == TOKvar && -- ((VarExp *)agg1)->var == ((VarExp *)agg2)->var); -+ ((VarExp *)agg1)->var == ((VarExp *)agg2)->var) || -+ (agg1->op == TOKsymoff && agg2->op == TOKsymoff && -+ ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var); - } - - // return e1 - e2 as an integer, or error if not possible -@@ -634,11 +687,16 @@ Expression *pointerDifference(Loc loc, T - { - if (((StringExp *)agg1)->string == ((StringExp *)agg2)->string) - { -- Type *pointee = ((TypePointer *)agg1->type)->next; -- dinteger_t sz = pointee->size(); -- return new IntegerExp(loc, (ofs1-ofs2)*sz, type); -+ Type *pointee = ((TypePointer *)agg1->type)->next; -+ dinteger_t sz = pointee->size(); -+ return new IntegerExp(loc, (ofs1-ofs2)*sz, type); - } - } -+ else if (agg1->op == TOKsymoff && agg2->op == TOKsymoff && -+ ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var) -+ { -+ return new IntegerExp(loc, ofs1-ofs2, type); -+ } - error(loc, "%s - %s cannot be interpreted at compile time: cannot subtract " - "pointers to two different memory blocks", - e1->toChars(), e2->toChars()); -@@ -647,7 +705,7 @@ Expression *pointerDifference(Loc loc, T - - // Return eptr op e2, where eptr is a pointer, e2 is an integer, - // and op is TOKadd or TOKmin --Expression *pointerArithmetic(Loc loc, enum TOK op, Type *type, -+Expression *pointerArithmetic(Loc loc, TOK op, Type *type, - Expression *eptr, Expression *e2) - { - if (eptr->type->nextOf()->ty == Tvoid) -@@ -659,21 +717,36 @@ Expression *pointerArithmetic(Loc loc, e - if (eptr->op == TOKaddress) - eptr = ((AddrExp *)eptr)->e1; - Expression *agg1 = getAggregateFromPointer(eptr, &ofs1); -- if (agg1->op != TOKstring && agg1->op != TOKarrayliteral) -+ if (agg1->op == TOKsymoff) -+ { -+ if (((SymOffExp *)agg1)->var->type->ty != Tsarray) -+ { -+ error(loc, "cannot perform pointer arithmetic on arrays of unknown length at compile time"); -+ return EXP_CANT_INTERPRET; -+ } -+ } -+ else if (agg1->op != TOKstring && agg1->op != TOKarrayliteral) - { - error(loc, "cannot perform pointer arithmetic on non-arrays at compile time"); - return EXP_CANT_INTERPRET; - } - ofs2 = e2->toInteger(); - Type *pointee = ((TypePointer *)agg1->type)->next; -+ sinteger_t indx = ofs1; - dinteger_t sz = pointee->size(); -- Expression *dollar = ArrayLength(Type::tsize_t, agg1); -- assert(dollar != EXP_CANT_INTERPRET); -+ Expression *dollar; -+ if (agg1->op == TOKsymoff) -+ { -+ dollar = ((TypeSArray *)(((SymOffExp *)agg1)->var->type))->dim; -+ indx = ofs1/sz; -+ } -+ else -+ { -+ dollar = ArrayLength(Type::tsize_t, agg1); -+ assert(dollar != EXP_CANT_INTERPRET); -+ } - dinteger_t len = dollar->toInteger(); - -- Expression *val = agg1; -- TypeArray *tar = (TypeArray *)val->type; -- sinteger_t indx = ofs1; - if (op == TOKadd || op == TOKaddass || op == TOKplusplus) - indx = indx + ofs2/sz; - else if (op == TOKmin || op == TOKminass || op == TOKminusminus) -@@ -683,14 +756,24 @@ Expression *pointerArithmetic(Loc loc, e - error(loc, "CTFE Internal compiler error: bad pointer operation"); - return EXP_CANT_INTERPRET; - } -- if (val->op != TOKarrayliteral && val->op != TOKstring) -+ -+ if (indx < 0 || indx > len) - { -- error(loc, "CTFE Internal compiler error: pointer arithmetic %s", val->toChars()); -+ error(loc, "cannot assign pointer to index %lld inside memory block [0..%lld]", indx, len); - return EXP_CANT_INTERPRET; - } -- if (indx < 0 || indx > len) -+ -+ if (agg1->op == TOKsymoff) - { -- error(loc, "cannot assign pointer to index %lld inside memory block [0..%lld]", indx, len); -+ SymOffExp *se = new SymOffExp(loc, ((SymOffExp *)agg1)->var, indx*sz); -+ se->type = type; -+ return se; -+ } -+ -+ Expression *val = agg1; -+ if (val->op != TOKarrayliteral && val->op != TOKstring) -+ { -+ error(loc, "CTFE Internal compiler error: pointer arithmetic %s", val->toChars()); - return EXP_CANT_INTERPRET; - } - -@@ -702,14 +785,12 @@ Expression *pointerArithmetic(Loc loc, e - - // Return 1 if true, 0 if false - // -1 if comparison is illegal because they point to non-comparable memory blocks --int comparePointers(Loc loc, enum TOK op, Type *type, Expression *agg1, dinteger_t ofs1, -+int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t ofs1, - Expression *agg2, dinteger_t ofs2) - { - if ( pointToSameMemoryBlock(agg1, agg2) ) - { -- dinteger_t cm = ofs1 - ofs2; - dinteger_t n; -- dinteger_t zero = 0; - switch(op) - { - case TOKlt: n = (ofs1 < ofs2); break; -@@ -743,6 +824,8 @@ int comparePointers(Loc loc, enum TOK op - case TOKnotequal: - cmp = (null1 == null2); - break; -+ default: -+ assert(0); - } - } - else -@@ -801,7 +884,7 @@ Expression *paintFloatInt(Expression *fr - if (to->isintegral()) - { - u.f = fromVal->toReal(); -- return new IntegerExp(fromVal->loc, ldouble(u.x), to); -+ return new IntegerExp(fromVal->loc, (dinteger_t)ldouble(u.x), to); - } - else - { -@@ -845,6 +928,9 @@ void intUnary(TOK op, IntegerExp *e) - case TOKtilde: - e->value = ~e->value; - break; -+ default: -+ assert(0); -+ break; - } - } - -@@ -1047,6 +1133,8 @@ bool isCtfeComparable(Expression *e) - if (x->isConst() != 1 && - x->op != TOKnull && - x->op != TOKstring && -+ x->op != TOKfunction && -+ x->op != TOKdelegate && - x->op != TOKarrayliteral && - x->op != TOKstructliteral && - x->op != TOKclassreference) -@@ -1202,16 +1290,16 @@ int ctfeCmpArrays(Loc loc, Expression *e - { lo1 = ((SliceExp *)x)->lwr->toInteger(); - x = ((SliceExp*)x)->e1; - } -- StringExp *se1 = (x->op == TOKstring) ? (StringExp *)x : 0; -- ArrayLiteralExp *ae1 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : 0; -+ StringExp *se1 = (x->op == TOKstring) ? (StringExp *)x : NULL; -+ ArrayLiteralExp *ae1 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : NULL; - - x = e2; - if (x->op == TOKslice) - { lo2 = ((SliceExp *)x)->lwr->toInteger(); - x = ((SliceExp*)x)->e1; - } -- StringExp *se2 = (x->op == TOKstring) ? (StringExp *)x : 0; -- ArrayLiteralExp *ae2 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : 0; -+ StringExp *se2 = (x->op == TOKstring) ? (StringExp *)x : NULL; -+ ArrayLiteralExp *ae2 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : NULL; - - // Now both must be either TOKarrayliteral or TOKstring - if (se1 && se2) -@@ -1244,6 +1332,21 @@ int ctfeCmpArrays(Loc loc, Expression *e - return 0; - } - -+/* Given a delegate expression e, return .funcptr. -+ * If e is NullExp, return NULL. -+ */ -+FuncDeclaration *funcptrOf(Expression *e) -+{ -+ assert(e->type->ty == Tdelegate); -+ -+ if (e->op == TOKdelegate) -+ return ((DelegateExp *)e)->func; -+ if (e->op == TOKfunction) -+ return ((FuncExp *)e)->fd; -+ assert(e->op == TOKnull); -+ return NULL; -+} -+ - bool isArray(Expression *e) - { - return e->op == TOKarrayliteral || e->op == TOKstring || -@@ -1261,13 +1364,16 @@ int ctfeRawCmp(Loc loc, Expression *e1, - return 0; - return 1; - } -+ -+ // null == null, regardless of type -+ - if (e1->op == TOKnull && e2->op == TOKnull) - return 0; - - if (e1->type->ty == Tpointer && e2->type->ty == Tpointer) -- { // Can only be an equality test. -- if (e1->op == TOKnull && e2->op == TOKnull) -- return 0; -+ { -+ // Can only be an equality test. -+ - dinteger_t ofs1, ofs2; - Expression *agg1 = getAggregateFromPointer(e1, &ofs1); - Expression *agg2 = getAggregateFromPointer(e2, &ofs2); -@@ -1278,6 +1384,35 @@ int ctfeRawCmp(Loc loc, Expression *e1, - } - return 1; - } -+ if (e1->type->ty == Tdelegate && e2->type->ty == Tdelegate) -+ { -+ // If .funcptr isn't the same, they are not equal -+ -+ if (funcptrOf(e1) != funcptrOf(e2)) -+ return 1; -+ -+ // If both are delegate literals, assume they have the -+ // same closure pointer. TODO: We don't support closures yet! -+ if (e1->op == TOKfunction && e2->op == TOKfunction) -+ return 0; -+ assert(e1->op == TOKdelegate && e2->op == TOKdelegate); -+ -+ // Same .funcptr. Do they have the same .ptr? -+ Expression * ptr1 = ((DelegateExp *)e1)->e1; -+ Expression * ptr2 = ((DelegateExp *)e2)->e1; -+ -+ dinteger_t ofs1, ofs2; -+ Expression *agg1 = getAggregateFromPointer(ptr1, &ofs1); -+ Expression *agg2 = getAggregateFromPointer(ptr2, &ofs2); -+ // If they are TOKvar, it means they are FuncDeclarations -+ if ((agg1 == agg2 && ofs1 == ofs2) || -+ (agg1->op == TOKvar && agg2->op == TOKvar && -+ ((VarExp *)agg1)->var == ((VarExp *)agg2)->var)) -+ { -+ return 0; -+ } -+ return 1; -+ } - if (isArray(e1) && isArray(e2)) - { - uinteger_t len1 = resolveArrayLength(e1); -@@ -1367,7 +1502,7 @@ int ctfeRawCmp(Loc loc, Expression *e1, - - - /// Evaluate ==, !=. Resolves slices before comparing. Returns 0 or 1 --int ctfeEqual(Loc loc, enum TOK op, Expression *e1, Expression *e2) -+int ctfeEqual(Loc loc, TOK op, Expression *e1, Expression *e2) - { - int cmp = !ctfeRawCmp(loc, e1, e2); - if (op == TOKnotequal) -@@ -1377,7 +1512,7 @@ int ctfeEqual(Loc loc, enum TOK op, Expr - - - /// Evaluate is, !is. Resolves slices before comparing. Returns 0 or 1 --int ctfeIdentity(Loc loc, enum TOK op, Expression *e1, Expression *e2) -+int ctfeIdentity(Loc loc, TOK op, Expression *e1, Expression *e2) - { - int cmp; - if (e1->op == TOKnull) -@@ -1414,10 +1549,12 @@ int ctfeIdentity(Loc loc, enum TOK op, E - - - /// Evaluate >,<=, etc. Resolves slices before comparing. Returns 0 or 1 --int ctfeCmp(Loc loc, enum TOK op, Expression *e1, Expression *e2) -+int ctfeCmp(Loc loc, TOK op, Expression *e1, Expression *e2) - { - int n; -- if (e1->type->isString() && e2->type->isString()) -+ Type *t1 = e1->type->toBasetype(); -+ Type *t2 = e2->type->toBasetype(); -+ if (t1->isString() && t2->isString()) - { - int cmp = ctfeRawCmp(loc, e1, e2); - switch (op) -@@ -1440,15 +1577,15 @@ int ctfeCmp(Loc loc, enum TOK op, Expres - assert(0); - } - } -- else if (e1->type->isreal()) -+ else if (t1->isreal()) - { - n = realCmp(op, e1->toReal(), e2->toReal()); - } -- else if (e1->type->isimaginary()) -+ else if (t1->isimaginary()) - { - n = realCmp(op, e1->toImaginary(), e2->toImaginary()); - } -- else if (e1->type->isunsigned() || e2->type->isunsigned()) -+ else if (t1->isunsigned() || t2->isunsigned()) - { - n = intUnsignedCmp(op, e1->toInteger(), e2->toInteger()); - } -@@ -1478,15 +1615,16 @@ Expression *ctfeCat(Type *type, Expressi - void *s = mem.malloc((len + 1) * sz); - memcpy((char *)s + sz * es2->elements->dim, es1->string, es1->len * sz); - for (size_t i = 0; i < es2->elements->dim; i++) -- { Expression *es2e = es2->elements->tdata()[i]; -+ { -+ Expression *es2e = (*es2->elements)[i]; - if (es2e->op != TOKint64) - return EXP_CANT_INTERPRET; - dinteger_t v = es2e->toInteger(); -- memcpy((unsigned char *)s + i * sz, &v, sz); -+ memcpy((utf8_t *)s + i * sz, &v, sz); - } - - // Add terminating 0 -- memset((unsigned char *)s + len * sz, 0, sz); -+ memset((utf8_t *)s + len * sz, 0, sz); - - StringExp *es = new StringExp(loc, s, len); - es->sz = sz; -@@ -1508,15 +1646,16 @@ Expression *ctfeCat(Type *type, Expressi - void *s = mem.malloc((len + 1) * sz); - memcpy(s, es1->string, es1->len * sz); - for (size_t i = 0; i < es2->elements->dim; i++) -- { Expression *es2e = es2->elements->tdata()[i]; -+ { -+ Expression *es2e = (*es2->elements)[i]; - if (es2e->op != TOKint64) - return EXP_CANT_INTERPRET; - dinteger_t v = es2e->toInteger(); -- memcpy((unsigned char *)s + (es1->len + i) * sz, &v, sz); -+ memcpy((utf8_t *)s + (es1->len + i) * sz, &v, sz); - } - - // Add terminating 0 -- memset((unsigned char *)s + len * sz, 0, sz); -+ memset((utf8_t *)s + len * sz, 0, sz); - - StringExp *es = new StringExp(loc, s, len); - es->sz = sz; -@@ -1525,6 +1664,32 @@ Expression *ctfeCat(Type *type, Expressi - e = es; - return e; - } -+ else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral && -+ t1->nextOf()->equals(t2->nextOf())) -+ { -+ // [ e1 ] ~ [ e2 ] ---> [ e1, e2 ] -+ ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; -+ ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; -+ -+ es1 = new ArrayLiteralExp(es1->loc, copyLiteralArray(es1->elements)); -+ es1->elements->insert(es1->elements->dim, copyLiteralArray(es2->elements)); -+ e = es1; -+ e->type = type; -+ return e; -+ } -+ else if (e1->op == TOKarrayliteral && e2->op == TOKnull && -+ t1->nextOf()->equals(t2->nextOf())) -+ { -+ // [ e1 ] ~ null ----> [ e1 ].dup -+ return paintTypeOntoLiteral(type, copyLiteral(e1)); -+ } -+ else if (e1->op == TOKnull && e2->op == TOKarrayliteral && -+ t1->nextOf()->equals(t2->nextOf())) -+ { -+ // null ~ [ e2 ] ----> [ e2 ].dup -+ return paintTypeOntoLiteral(type, copyLiteral(e2)); -+ } -+ - return Cat(type, e1, e2); - } - -@@ -1538,11 +1703,11 @@ Expression *findKeyInAA(Loc loc, AssocAr - for (size_t i = ae->keys->dim; i;) - { - i--; -- Expression *ekey = ae->keys->tdata()[i]; -+ Expression *ekey = (*ae->keys)[i]; - int eq = ctfeEqual(loc, TOKequal, ekey, e2); - if (eq) - { -- return ae->values->tdata()[i]; -+ return (*ae->values)[i]; - } - } - return NULL; -@@ -1572,7 +1737,7 @@ Expression *ctfeIndex(Loc loc, Type *typ - error(loc, "array index %llu is out of bounds %s[0 .. %llu]", indx, e1->toChars(), (ulonglong)ale->elements->dim); - return EXP_CANT_INTERPRET; - } -- Expression *e = ale->elements->tdata()[indx]; -+ Expression *e = (*ale->elements)[indx]; - return paintTypeOntoLiteral(type, e); - } - -@@ -1589,6 +1754,15 @@ Expression *ctfeCast(Loc loc, Type *type - else - return new NullExp(loc, to); - } -+ // Allow TypeInfo type painting -+ if (isTypeInfo_Class(e->type) && e->type->implicitConvTo(to)) -+ return paintTypeOntoLiteral(to, e); -+#if DMDV2 -+ // Allow casting away const for struct literals -+ if (e->op == TOKstructliteral && -+ e->type->toBasetype()->castMod(0) == to->toBasetype()->castMod(0)) -+ return paintTypeOntoLiteral(to, e); -+#endif - Expression *r = Cast(type, to, e); - if (r == EXP_CANT_INTERPRET) - error(loc, "cannot cast %s to %s at compile time", e->toChars(), to->toChars()); -@@ -1645,8 +1819,8 @@ void assignInPlace(Expression *dest, Exp - - for (size_t i= 0; i < oldelems->dim; ++i) - { -- Expression *e = newelems->tdata()[i]; -- Expression *o = oldelems->tdata()[i]; -+ Expression *e = (*newelems)[i]; -+ Expression *o = (*oldelems)[i]; - if (e->op == TOKstructliteral) - { - assert(o->op == e->op); -@@ -1658,7 +1832,7 @@ void assignInPlace(Expression *dest, Exp - } - else - { -- oldelems->tdata()[i] = newelems->tdata()[i]; -+ (*oldelems)[i] = (*newelems)[i]; - } - } - } -@@ -1668,10 +1842,10 @@ void recursiveBlockAssign(ArrayLiteralEx - assert( ae->type->ty == Tsarray || ae->type->ty == Tarray); - #if DMDV2 - Type *desttype = ((TypeArray *)ae->type)->next->castMod(0); -- bool directblk = (val->type->toBasetype()->castMod(0)) == desttype; -+ bool directblk = (val->type->toBasetype()->castMod(0))->equals(desttype); - #else - Type *desttype = ((TypeArray *)ae->type)->next; -- bool directblk = (val->type->toBasetype()) == desttype; -+ bool directblk = (val->type->toBasetype())->equals(desttype); - #endif - - bool cow = !(val->op == TOKstructliteral || val->op == TOKarrayliteral -@@ -1679,16 +1853,16 @@ void recursiveBlockAssign(ArrayLiteralEx - - for (size_t k = 0; k < ae->elements->dim; k++) - { -- if (!directblk && ae->elements->tdata()[k]->op == TOKarrayliteral) -+ if (!directblk && (*ae->elements)[k]->op == TOKarrayliteral) - { -- recursiveBlockAssign((ArrayLiteralExp *)ae->elements->tdata()[k], val, wantRef); -+ recursiveBlockAssign((ArrayLiteralExp *)(*ae->elements)[k], val, wantRef); - } - else - { - if (wantRef || cow) -- ae->elements->tdata()[k] = val; -+ (*ae->elements)[k] = val; - else -- assignInPlace(ae->elements->tdata()[k], val); -+ assignInPlace((*ae->elements)[k], val); - } - } - } -@@ -1704,7 +1878,7 @@ Expressions *changeOneElement(Expression - if (j == indexToChange) - (*expsx)[j] = newelem; - else -- (*expsx)[j] = oldelems->tdata()[j]; -+ (*expsx)[j] = (*oldelems)[j]; - } - return expsx; - } -@@ -1735,10 +1909,11 @@ Expression *assignAssocArrayElement(Loc - int updated = 0; - for (size_t j = valuesx->dim; j; ) - { j--; -- Expression *ekey = aae->keys->tdata()[j]; -+ Expression *ekey = (*aae->keys)[j]; - int eq = ctfeEqual(loc, TOKequal, ekey, index); - if (eq) -- { valuesx->tdata()[j] = newval; -+ { -+ (*valuesx)[j] = newval; - updated = 1; - } - } -@@ -1756,7 +1931,7 @@ Expression *assignAssocArrayElement(Loc - Expression *changeArrayLiteralLength(Loc loc, TypeArray *arrayType, - Expression *oldval, size_t oldlen, size_t newlen) - { -- Type *elemType = elemType = arrayType->next; -+ Type *elemType = arrayType->next; - assert(elemType); - Expression *defaultElem = elemType->defaultInitLiteral(loc); - Expressions *elements = new Expressions(); -@@ -1772,7 +1947,7 @@ Expression *changeArrayLiteralLength(Loc - if (oldval->op == TOKstring) - { - StringExp *oldse = (StringExp *)oldval; -- unsigned char *s = (unsigned char *)mem.calloc(newlen + 1, oldse->sz); -+ utf8_t *s = (utf8_t *)mem.calloc(newlen + 1, oldse->sz); - memcpy(s, oldse->string, copylen * oldse->sz); - unsigned defaultValue = (unsigned)(defaultElem->toInteger()); - for (size_t elemi = copylen; elemi < newlen; ++elemi) -@@ -1824,11 +1999,12 @@ Expression *changeArrayLiteralLength(Loc - - bool isCtfeValueValid(Expression *newval) - { -- if ( - #if DMDV2 -- newval->type->ty == Tnull || -+ bool isnull = newval->type->ty == Tnull; -+#else -+ bool isnull = false; - #endif -- isPointer(newval->type) ) -+ if (isnull || isPointer(newval->type)) - { - if (newval->op == TOKaddress || newval->op == TOKnull || - newval->op == TOKstring) -@@ -1880,13 +2056,30 @@ bool isCtfeValueValid(Expression *newval - if (ie->e2->op == TOKvar) - return true; - } -- if (newval->op == TOKfunction) return true; // function/delegate literal -- if (newval->op == TOKdelegate) return true; -+ -+ if (newval->op == TOKfunction) -+ return true; // function literal or delegate literal -+ -+ if (newval->op == TOKvector) -+ return true; // vector literal -+ -+ if (newval->op == TOKdelegate) -+ { -+ Expression *dge = ((DelegateExp *)newval)->e1; -+ if (dge->op == TOKvar && ((VarExp *)dge)->var->isFuncDeclaration()) -+ return true; // &nestedfunc -+ -+ if (dge->op == TOKstructliteral || dge->op == TOKclassreference) -+ return true; // &struct.func or &clasinst.func -+ } - if (newval->op == TOKsymoff) // function pointer - { - if (((SymOffExp *)newval)->var->isFuncDeclaration()) - return true; -+ if (((SymOffExp *)newval)->var->isDataseg()) -+ return true; // pointer to static variable - } -+ - if (newval->op == TOKint64 || newval->op == TOKfloat64 || - newval->op == TOKchar || newval->op == TOKcomplex80) - return true; ---- a/src/gcc/d/dfrontend/ctfe.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/ctfe.h 2014-04-01 16:32:51.000000000 +0100 -@@ -14,6 +14,7 @@ - #pragma once - #endif /* __DMC__ */ - -+#include "arraytypes.h" - - /** - Global status of the CTFE engine. Mostly used for performance diagnostics -@@ -29,22 +30,17 @@ struct CtfeStatus - static int numAssignments; // total number of assignments executed - }; - -- --/** Expression subclasses which only exist in CTFE */ -- --#define TOKclassreference ((TOK)(TOKMAX+1)) --#define TOKthrownexception ((TOK)(TOKMAX+2)) -- - /** - A reference to a class, or an interface. We need this when we - point to a base class (we must record what the type is). - */ --struct ClassReferenceExp : Expression -+class ClassReferenceExp : public Expression - { -+public: - StructLiteralExp *value; - ClassReferenceExp(Loc loc, StructLiteralExp *lit, Type *type); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- char *toChars(); -+ void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - ClassDeclaration *originalClass(); - VarDeclaration *getFieldAt(unsigned index); - -@@ -53,6 +49,12 @@ struct ClassReferenceExp : Expression - /// Return index of the field, or -1 if not found - /// Same as getFieldIndex, but checks for a direct match with the VarDeclaration - int findFieldIndexByName(VarDeclaration *v); -+ dt_t **toDt(dt_t **pdt); -+ dt_t **toDtI(dt_t **pdt, int offset); -+ Symbol* toSymbol(); -+ dt_t **toInstanceDt(dt_t **pdt); -+ dt_t **toDt2(dt_t **pdt, ClassDeclaration *cd, Dts *dts); -+ elem *toElem(IRState *irs); - }; - - /// Return index of the field, or -1 if not found -@@ -62,8 +64,9 @@ int findFieldIndexByName(StructDeclarati - - /** An uninitialized value - */ --struct VoidInitExp : Expression -+class VoidInitExp : public Expression - { -+public: - VarDeclaration *var; - - VoidInitExp(VarDeclaration *var, Type *type); -@@ -75,8 +78,9 @@ struct VoidInitExp : Expression - /** Fake class which holds the thrown exception. - Used for implementing exception handling. - */ --struct ThrownExceptionExp : Expression -+class ThrownExceptionExp : public Expression - { -+public: - ClassReferenceExp *thrown; // the thing being tossed - ThrownExceptionExp(Loc loc, ClassReferenceExp *victim); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -@@ -175,11 +179,11 @@ Expression *pointerDifference(Loc loc, T - - /// Return 1 if true, 0 if false - /// -1 if comparison is illegal because they point to non-comparable memory blocks --int comparePointers(Loc loc, enum TOK op, Type *type, Expression *agg1, dinteger_t ofs1, Expression *agg2, dinteger_t ofs2); -+int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t ofs1, Expression *agg2, dinteger_t ofs2); - - // Return eptr op e2, where eptr is a pointer, e2 is an integer, - // and op is TOKadd or TOKmin --Expression *pointerArithmetic(Loc loc, enum TOK op, Type *type, -+Expression *pointerArithmetic(Loc loc, TOK op, Type *type, - Expression *eptr, Expression *e2); - - // True if conversion from type 'from' to 'to' involves a reinterpret_cast -@@ -201,6 +205,9 @@ TypeAArray *toBuiltinAAType(Type *t); - */ - Expression *findKeyInAA(Loc loc, AssocArrayLiteralExp *ae, Expression *e2); - -+/// True if type is TypeInfo_Class -+bool isTypeInfo_Class(Type *type); -+ - /*********************************************** - In-place integer operations - ***********************************************/ -@@ -221,13 +228,13 @@ void intBinary(TOK op, IntegerExp *dest, - bool isCtfeComparable(Expression *e); - - /// Evaluate ==, !=. Resolves slices before comparing. Returns 0 or 1 --int ctfeEqual(Loc loc, enum TOK op, Expression *e1, Expression *e2); -+int ctfeEqual(Loc loc, TOK op, Expression *e1, Expression *e2); - - /// Evaluate is, !is. Resolves slices before comparing. Returns 0 or 1 --int ctfeIdentity(Loc loc, enum TOK op, Expression *e1, Expression *e2); -+int ctfeIdentity(Loc loc, TOK op, Expression *e1, Expression *e2); - - /// Evaluate >,<=, etc. Resolves slices before comparing. Returns 0 or 1 --int ctfeCmp(Loc loc, enum TOK op, Expression *e1, Expression *e2); -+int ctfeCmp(Loc loc, TOK op, Expression *e1, Expression *e2); - - /// Returns e1 ~ e2. Resolves slices before concatenation. - Expression *ctfeCat(Type *type, Expression *e1, Expression *e2); ---- a/src/gcc/d/dfrontend/declaration.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/declaration.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -24,13 +24,14 @@ - #include "expression.h" - #include "statement.h" - #include "hdrgen.h" -+#include "ctfe.h" - #include "target.h" - - AggregateDeclaration *isAggregate(Type *t); // from opover.c - - void checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad) - { -- if (!ad->isnested) -+ if (!ad->isNested()) - return; - - Dsymbol *s = sc->func; -@@ -83,6 +84,7 @@ Declaration::Declaration(Identifier *id) - linkage = LINKdefault; - inuse = 0; - sem = SemanticStart; -+ mangleOverride = NULL; - } - - void Declaration::semantic(Scope *sc) -@@ -100,27 +102,27 @@ unsigned Declaration::size(Loc loc) - return type->size(); - } - --int Declaration::isDelete() -+bool Declaration::isDelete() - { -- return FALSE; -+ return false; - } - --int Declaration::isDataseg() -+bool Declaration::isDataseg() - { -- return FALSE; -+ return false; - } - --int Declaration::isThreadlocal() -+bool Declaration::isThreadlocal() - { -- return FALSE; -+ return false; - } - --int Declaration::isCodeseg() -+bool Declaration::isCodeseg() - { -- return FALSE; -+ return false; - } - --enum PROT Declaration::prot() -+PROT Declaration::prot() - { - return protection; - } -@@ -138,18 +140,20 @@ int Declaration::checkModify(Loc loc, Sc - if (v && v->canassign) - return 2; - -- if ((sc->flags & SCOPEcontract) && isParameter()) -+ if (isParameter() || isResult()) - { -- if (!flag) error(loc, "cannot modify parameter '%s' in contract", toChars()); -- return 0; -- } -- if ((sc->flags & SCOPEcontract) && isResult()) -- { -- if (!flag) error(loc, "cannot modify result '%s' in contract", toChars()); -- return 0; -+ for (Scope *scx = sc; scx; scx = scx->enclosing) -+ { -+ if (scx->func == parent && (scx->flags & SCOPEcontract)) -+ { -+ const char *s = isParameter() && parent->ident != Id::ensure ? "parameter" : "result"; -+ if (!flag) error(loc, "cannot modify %s '%s' in contract", s, toChars()); -+ return 2; // do not report type related errors -+ } -+ } - } - -- if (v && isCtorinit()) -+ if (v && (isCtorinit() || isField())) - { // It's only modifiable if inside the right constructor - if ((storage_class & (STCforeach | STCref)) == (STCforeach | STCref)) - return 2; -@@ -180,7 +184,7 @@ TupleDeclaration::TupleDeclaration(Loc l - this->loc = loc; - this->type = NULL; - this->objects = objects; -- this->isexp = 0; -+ this->isexp = false; - this->tupletype = NULL; - } - -@@ -208,7 +212,7 @@ Type *TupleDeclaration::getType() - /* It's only a type tuple if all the Object's are types - */ - for (size_t i = 0; i < objects->dim; i++) -- { Object *o = (*objects)[i]; -+ { RootObject *o = (*objects)[i]; - - if (o->dyncast() != DYNCAST_TYPE) - { -@@ -243,17 +247,17 @@ Type *TupleDeclaration::getType() - - tupletype = new TypeTuple(args); - if (hasdeco) -- return tupletype->semantic(0, NULL); -+ return tupletype->semantic(Loc(), NULL); - } - - return tupletype; - } - --int TupleDeclaration::needThis() -+bool TupleDeclaration::needThis() - { - //printf("TupleDeclaration::needThis(%s)\n", toChars()); - for (size_t i = 0; i < objects->dim; i++) -- { Object *o = (*objects)[i]; -+ { RootObject *o = (*objects)[i]; - if (o->dyncast() == DYNCAST_EXPRESSION) - { Expression *e = (Expression *)o; - if (e->op == TOKdsymbol) -@@ -261,12 +265,12 @@ int TupleDeclaration::needThis() - Declaration *d = ve->s->isDeclaration(); - if (d && d->needThis()) - { -- return 1; -+ return true; - } - } - } - } -- return 0; -+ return false; - } - - -@@ -367,7 +371,7 @@ void TypedefDeclaration::semantic2(Scope - Initializer *savedinit = init; - int errors = global.errors; - init = init->semantic(sc, basetype, INITinterpret); -- if (errors != global.errors) -+ if (errors != global.errors || init->isErrorInitializer()) - { - init = savedinit; - return; -@@ -420,7 +424,7 @@ AliasDeclaration::AliasDeclaration(Loc l - this->htype = NULL; - this->haliassym = NULL; - this->overnext = NULL; -- this->inSemantic = 0; -+ this->inSemantic = false; - assert(type); - } - -@@ -436,7 +440,7 @@ AliasDeclaration::AliasDeclaration(Loc l - this->htype = NULL; - this->haliassym = NULL; - this->overnext = NULL; -- this->inSemantic = 0; -+ this->inSemantic = false; - assert(s); - } - -@@ -481,7 +485,7 @@ void AliasDeclaration::semantic(Scope *s - aliassym->semantic(sc); - return; - } -- this->inSemantic = 1; -+ this->inSemantic = true; - - #if DMDV1 // don't really know why this is here - if (storage_class & STCconst) -@@ -514,6 +518,12 @@ void AliasDeclaration::semantic(Scope *s - * try to alias y to 3. - */ - s = type->toDsymbol(sc); -+ if (s && s == this) -+ { -+ error("cannot resolve"); -+ s = NULL; -+ type = Type::terror; -+ } - if (s - #if DMDV2 - && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()) -@@ -555,8 +565,8 @@ void AliasDeclaration::semantic(Scope *s - //printf("\talias resolved to type %s\n", type->toChars()); - } - if (overnext) -- ScopeDsymbol::multiplyDefined(0, overnext, this); -- this->inSemantic = 0; -+ ScopeDsymbol::multiplyDefined(Loc(), overnext, this); -+ this->inSemantic = false; - - if (global.gag && errors != global.errors) - type = savedtype; -@@ -581,7 +591,7 @@ void AliasDeclaration::semantic(Scope *s - { - FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); - if (!fa->overloadInsert(overnext)) -- ScopeDsymbol::multiplyDefined(0, overnext, f); -+ ScopeDsymbol::multiplyDefined(Loc(), overnext, f); - overnext = NULL; - s = fa; - s->parent = sc->parent; -@@ -599,7 +609,7 @@ void AliasDeclaration::semantic(Scope *s - } - } - if (overnext) -- ScopeDsymbol::multiplyDefined(0, overnext, this); -+ ScopeDsymbol::multiplyDefined(Loc(), overnext, this); - if (s == this) - { - assert(global.errors); -@@ -610,16 +620,16 @@ void AliasDeclaration::semantic(Scope *s - type = savedtype; - overnext = savedovernext; - aliassym = NULL; -- inSemantic = 0; -+ inSemantic = false; - return; - } - } - //printf("setting aliassym %s to %s %s\n", toChars(), s->kind(), s->toChars()); - aliassym = s; -- this->inSemantic = 0; -+ this->inSemantic = false; - } - --int AliasDeclaration::overloadInsert(Dsymbol *s) -+bool AliasDeclaration::overloadInsert(Dsymbol *s) - { - /* Don't know yet what the aliased symbol is, so assume it can - * be overloaded and check later for correctness. -@@ -642,10 +652,10 @@ int AliasDeclaration::overloadInsert(Dsy - { - if (s == this) - { -- return TRUE; -+ return true; - } - overnext = s; -- return TRUE; -+ return true; - } - else - { -@@ -671,15 +681,21 @@ Dsymbol *AliasDeclaration::toAlias() - assert(this != aliassym); - //static int count; if (++count == 10) *(char*)0=0; - if (inSemantic) -- { error("recursive alias declaration"); -+ { -+ error("recursive alias declaration"); -+ -+ // Avoid breaking "recursive alias" state during errors gagged -+ if (global.isSpeculativeGagging()) -+ return this; -+ - aliassym = new AliasDeclaration(loc, ident, Type::terror); - type = Type::terror; - } - else if (aliassym || type->deco) - ; // semantic is already done. -- else if (import) -+ else if (import && import->scope) - { -- /* If this is an internal alias for selective import, -+ /* If this is an internal alias for selective/renamed import, - * resolve it under the correct scope. - */ - import->semantic(NULL); -@@ -816,8 +832,13 @@ void VarDeclaration::semantic(Scope *sc) - // return; - // sem = SemanticIn; - -+ if (sem >= SemanticDone) -+ return; -+ -+ Scope *scx = NULL; - if (scope) - { sc = scope; -+ scx = sc; - scope = NULL; - } - -@@ -839,6 +860,11 @@ void VarDeclaration::semantic(Scope *sc) - if (!type) - { inuse++; - -+ // Infering the type requires running semantic, -+ // so mark the scope as ctfe if required -+ bool needctfe = (storage_class & (STCmanifest | STCstatic)); -+ if (needctfe) sc = sc->startCTFE(); -+ - //printf("inferring type for %s with init %s\n", toChars(), init->toChars()); - ArrayInitializer *ai = init->isArrayInitializer(); - if (ai) -@@ -858,8 +884,11 @@ void VarDeclaration::semantic(Scope *sc) - type = type->nextOf()->arrayOf(); - } - else -+ { - type = init->inferType(sc); -+ } - -+ if (needctfe) sc = sc->endCTFE(); - // type = type->semantic(loc, sc); - - inuse--; -@@ -879,7 +908,9 @@ void VarDeclaration::semantic(Scope *sc) - else - { if (!originalType) - originalType = type->syntaxCopy(); -+ inuse++; - type = type->semantic(loc, sc); -+ inuse--; - } - //printf(" semantic type = %s\n", type ? type->toChars() : "null"); - -@@ -933,6 +964,7 @@ void VarDeclaration::semantic(Scope *sc) - FuncDeclaration *fd = parent->isFuncDeclaration(); - - Type *tb = type->toBasetype(); -+ Type *tbn = tb->baseElemOf(); - if (tb->ty == Tvoid && !(storage_class & STClazy)) - { - if (inferred) -@@ -969,7 +1001,7 @@ void VarDeclaration::semantic(Scope *sc) - size_t nelems = Parameter::dim(tt->arguments); - Objects *exps = new Objects(); - exps->setDim(nelems); -- Expression *ie = init ? init->toExpression() : NULL; -+ Expression *ie = (init && !init->isVoidInitializer()) ? init->toExpression() : NULL; - if (ie) ie = ie->semantic(sc); - - if (nelems > 0 && ie) -@@ -1005,6 +1037,7 @@ void VarDeclaration::semantic(Scope *sc) - - iexps->remove(pos); - iexps->insert(pos, te->exps); -+ (*iexps)[pos] = Expression::combine(te->e0, (*iexps)[pos]); - goto Lexpand1; - } - else if (isAliasThisTuple(e)) -@@ -1060,16 +1093,19 @@ void VarDeclaration::semantic(Scope *sc) - Lnomatch: - - if (ie && ie->op == TOKtuple) -- { size_t tedim = ((TupleExp *)ie)->exps->dim; -+ { -+ TupleExp *te = (TupleExp *)ie; -+ size_t tedim = te->exps->dim; - if (tedim != nelems) - { ::error(loc, "tuple of %d elements cannot be assigned to tuple of %d elements", (int)tedim, (int)nelems); - for (size_t u = tedim; u < nelems; u++) // fill dummy expression -- ((TupleExp *)ie)->exps->push(new ErrorExp()); -+ te->exps->push(new ErrorExp()); - } - } - - for (size_t i = 0; i < nelems; i++) -- { Parameter *arg = Parameter::getNth(tt->arguments, i); -+ { -+ Parameter *arg = Parameter::getNth(tt->arguments, i); - - OutBuffer buf; - buf.printf("_%s_field_%llu", ident->toChars(), (ulonglong)i); -@@ -1077,16 +1113,24 @@ Lnomatch: - const char *name = (const char *)buf.extractData(); - Identifier *id = Lexer::idPool(name); - -- Expression *einit = ie; -- if (ie && ie->op == TOKtuple) -- { einit = (*((TupleExp *)ie)->exps)[i]; -- } -- Initializer *ti = init; -- if (einit) -- { ti = new ExpInitializer(einit->loc, einit); -+ Initializer *ti; -+ if (ie) -+ { -+ Expression *einit = ie; -+ if (ie->op == TOKtuple) -+ { -+ TupleExp *te = (TupleExp *)ie; -+ einit = (*te->exps)[i]; -+ if (i == 0) -+ einit = Expression::combine(te->e0, einit); -+ } -+ ti = new ExpInitializer(einit->loc, einit); - } -+ else -+ ti = init ? init->syntaxCopy() : NULL; - - VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); -+ v->storage_class |= storage_class; - if (arg->storageClass & STCparameter) - v->storage_class |= arg->storageClass; - //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); -@@ -1103,7 +1147,7 @@ Lnomatch: - } - TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); - v2->parent = this->parent; -- v2->isexp = 1; -+ v2->isexp = true; - aliassym = v2; - return; - } -@@ -1126,7 +1170,10 @@ Lnomatch: - else if (type->isWild()) - storage_class |= STCwild; - -- if (isSynchronized()) -+ if (storage_class & (STCmanifest | STCstatic | STCgshared)) -+ { -+ } -+ else if (isSynchronized()) - { - error("variable %s cannot be synchronized", toChars()); - } -@@ -1151,24 +1198,46 @@ Lnomatch: - AggregateDeclaration *aad = parent->isAggregateDeclaration(); - if (aad) - { --#if DMDV2 -+#if PULL93 - assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); -- -+ if (storage_class & (STCconst | STCimmutable) && init && -+ global.params.vfield) -+ { -+ const char *p = loc.toChars(); -+ const char *s = (storage_class & STCimmutable) ? "immutable" : "const"; -+ fprintf(global.stdmsg, "%s: %s.%s is %s field\n", p ? p : "", ad->toPrettyChars(), toChars(), s); -+ } -+ storage_class |= STCfield; -+#if DMDV2 -+ if (tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor || -+ tbn->ty == Tclass && ((TypeClass *)tbn)->sym->noDefaultCtor) -+ { -+ if (!isThisDeclaration()) -+ aad->noDefaultCtor = TRUE; -+ } -+#endif -+#else - if (storage_class & (STCconst | STCimmutable) && init) - { -+ StorageClass stc = storage_class & (STCconst | STCimmutable); -+ warning(loc, "%s field with initializer should be static, __gshared, or an enum", -+ StorageClassDeclaration::stcToChars(NULL, stc)); - if (!tb->isTypeBasic()) - storage_class |= STCstatic; - } - else --#endif - { - storage_class |= STCfield; - #if DMDV2 -- if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor || -- tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor) -- aad->noDefaultCtor = TRUE; -+ if ((tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor) || -+ (tbn->ty == Tclass && ((TypeClass *)tbn)->sym->noDefaultCtor)) -+ { -+ if (!isThisDeclaration()) -+ aad->noDefaultCtor = TRUE; -+ } - #endif - } -+#endif - } - - InterfaceDeclaration *id = parent->isInterfaceDeclaration(); -@@ -1221,25 +1290,35 @@ Lnomatch: - { - if (func->fes) - func = func->fes->func; -- if (!((TypeFunction *)func->type)->iswild) -+ bool isWild = false; -+ for (FuncDeclaration *fd = func; fd; fd = fd->toParent2()->isFuncDeclaration()) -+ { -+ if (((TypeFunction *)fd->type)->iswild) -+ { -+ isWild = true; -+ break; -+ } -+ } -+ if (!isWild) - { - error("inout variables can only be declared inside inout functions"); - } - } - } - -- if (!(storage_class & (STCctfe | STCref)) && tb->ty == Tstruct && -- ((TypeStruct *)tb)->sym->noDefaultCtor) -+ if (!(storage_class & (STCctfe | STCref | STCresult)) && tbn->ty == Tstruct && -+ ((TypeStruct *)tbn)->sym->noDefaultCtor) - { - if (!init) -- { if (storage_class & STCfield) -+ { -+ if (isField()) - /* For fields, we'll check the constructor later to make sure it is initialized - */ - storage_class |= STCnodefaultctor; - else if (storage_class & STCparameter) - ; - else -- error("initializer required for type %s", type->toChars()); -+ error("default construction is disabled for type %s", type->toChars()); - } - } - #endif -@@ -1268,8 +1347,8 @@ Lnomatch: - else if (storage_class & STCmanifest) - error("manifest constants must have initializers"); - -- enum TOK op = TOKconstruct; -- if (!init && !sc->inunion && !isStatic() && fd && -+ TOK op = TOKconstruct; -+ if (!init && !sc->inunion && !(storage_class & (STCstatic | STCgshared | STCextern)) && fd && - (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult)) - || (storage_class & STCout)) && - type->size() != 0) -@@ -1344,7 +1423,6 @@ Lnomatch: - init = new ExpInitializer(e->loc, e); - } - -- StructInitializer *si = init->isStructInitializer(); - ExpInitializer *ei = init->isExpInitializer(); - - if (ei && isScope()) -@@ -1413,7 +1491,7 @@ Lnomatch: - if (t->ty != Tsarray) - break; - dim *= ((TypeSArray *)t)->dim->toInteger(); -- e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex)); -+ e1->type = TypeSArray::makeType(Loc(), t->nextOf(), dim); - } - } - e1 = new SliceExp(loc, e1, NULL, NULL); -@@ -1440,7 +1518,7 @@ Lnomatch: - /* Look for form of constructor call which is: - * *__ctmp.ctor(arguments...) - */ -- if (1) -+ if ((*pinit)->type->implicitConvTo(t)) - { CallExp *ce = (CallExp *)(*pinit); - if (ce->e1->op == TOKdotvar) - { DotVarExp *dve = (DotVarExp *)ce->e1; -@@ -1459,17 +1537,19 @@ Lnomatch: - */ - storage_class &= ~(STCref | STCforeach | STCparameter); - -- Expression *e; -+ Expression *e = new VarExp(loc, this); - if (sd->zeroInit == 1) - { -- e = new ConstructExp(loc, new VarExp(loc, this), new IntegerExp(loc, 0, Type::tint32)); -+ e = new ConstructExp(loc, e, new IntegerExp(loc, 0, Type::tint32)); - } - else if (sd->isNested()) -- { e = new AssignExp(loc, new VarExp(loc, this), t->defaultInitLiteral(loc)); -+ { -+ e = new AssignExp(loc, e, t->defaultInitLiteral(loc)); - e->op = TOKblit; - } - else -- { e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc)); -+ { -+ e = new AssignExp(loc, e, t->defaultInit(loc)); - e->op = TOKblit; - } - e->type = t; -@@ -1548,6 +1628,11 @@ Lnomatch: - init = init->semantic(sc, type, INITinterpret); - } - } -+ else if (parent->isAggregateDeclaration()) -+ { -+ scope = scx ? scx : new Scope(*sc); -+ scope->setNoFree(); -+ } - else if (storage_class & (STCconst | STCimmutable | STCmanifest) || - type->isConst() || type->isImmutable()) - { -@@ -1557,18 +1642,21 @@ Lnomatch: - * Ignore failure. - */ - -- if (!global.errors && !inferred) -+ if (!inferred) - { -- unsigned errors = global.startGagging(); -- Expression *exp; -- Initializer *i2 = init; -+ unsigned errors = global.errors; - inuse++; -+#if DMDV2 - if (ei) - { -- exp = ei->exp->syntaxCopy(); -+ Expression *exp = ei->exp->syntaxCopy(); -+ -+ bool needctfe = isDataseg() || (storage_class & STCmanifest); -+ if (needctfe) sc = sc->startCTFE(); - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); --#if DMDV2 -+ if (needctfe) sc = sc->endCTFE(); -+ - Type *tb = type->toBasetype(); - Type *ti = exp->type->toBasetype(); - -@@ -1584,103 +1672,35 @@ Lnomatch: - * because the postblit doesn't get run on the initialization of w. - */ - if (ti->ty == Tstruct) -- { StructDeclaration *sd = ((TypeStruct *)ti)->sym; -+ { -+ StructDeclaration *sd = ((TypeStruct *)ti)->sym; - /* Look to see if initializer involves a copy constructor - * (which implies a postblit) - */ - if (sd->cpctor && // there is a copy constructor -- tb->equals(ti)) // rvalue is the same struct -+ tb->toDsymbol(NULL) == sd) // exp is the same struct - { - // The only allowable initializer is a (non-copy) constructor -- if (exp->op == TOKcall) -- { -- CallExp *ce = (CallExp *)exp; -- if (ce->e1->op == TOKdotvar) -- { -- DotVarExp *dve = (DotVarExp *)ce->e1; -- if (dve->var->isCtorDeclaration()) -- goto LNoCopyConstruction; -- } -- } -- global.gag--; -- error("of type struct %s uses this(this), which is not allowed in static initialization", tb->toChars()); -- global.gag++; -- -- LNoCopyConstruction: -- ; -+ if (exp->isLvalue()) -+ error("of type struct %s uses this(this), which is not allowed in static initialization", tb->toChars()); - } - } -- -- // Look for implicit constructor call -- if (tb->ty == Tstruct && -- !(ti->ty == Tstruct && tb->toDsymbol(sc) == ti->toDsymbol(sc)) && -- !exp->implicitConvTo(type)) -- { -- StructDeclaration *sd = ((TypeStruct *)tb)->sym; -- if (sd->ctor) -- { // Look for constructor first -- // Rewrite as e1.ctor(arguments) -- Expression *e; -- e = new StructLiteralExp(loc, sd, NULL, NULL); -- e = new DotIdExp(loc, e, Id::ctor); -- e = new CallExp(loc, e, exp); -- e = e->semantic(sc); -- exp = e->ctfeInterpret(); -- } -- } --#endif -- exp = exp->implicitCastTo(sc, type); -- } -- else if (si || ai) -- { i2 = init->syntaxCopy(); -- i2 = i2->semantic(sc, type, INITinterpret); -+ ei->exp = exp; - } -+#endif -+ init = init->semantic(sc, type, INITinterpret); - inuse--; -- if (global.endGagging(errors)) // if errors happened -+ if (global.errors > errors) - { --#if DMDV2 -- /* Save scope for later use, to try again -- */ -- scope = new Scope(*sc); -- scope->setNoFree(); --#endif -+ init = new ErrorInitializer(); -+ type = Type::terror; - } -- else if (ei) -- { -- if (isDataseg() || (storage_class & STCmanifest)) -- exp = exp->ctfeInterpret(); -- else -- exp = exp->optimize(WANTvalue); -- switch (exp->op) -- { -- case TOKint64: -- case TOKfloat64: -- case TOKstring: -- case TOKarrayliteral: -- case TOKassocarrayliteral: -- case TOKstructliteral: -- case TOKnull: -- ei->exp = exp; // no errors, keep result -- break; -- -- default: --#if DMDV2 -- /* Save scope for later use, to try again -- */ -- scope = new Scope(*sc); -- scope->setNoFree(); --#endif -- break; -- } -- } -- else -- init = i2; // no errors, keep result - } -- } -- else if (parent->isAggregateDeclaration()) -- { -- scope = new Scope(*sc); -- scope->setNoFree(); -+ else -+ { -+ scope = scx ? scx : new Scope(*sc); -+ scope->setNoFree(); -+ } - } - sc = sc->pop(); - } -@@ -1691,7 +1711,10 @@ Ldtor: - edtor = callScopeDtor(sc); - if (edtor) - { -- edtor = edtor->semantic(sc); -+ if (sc->func && storage_class & (STCstatic | STCgshared)) -+ edtor = edtor->semantic(sc->module->scope); -+ else -+ edtor = edtor->semantic(sc); - - #if 0 // currently disabled because of std.stdio.stdin, stdout and stderr - if (isDataseg() && !(storage_class & STCextern)) -@@ -1700,6 +1723,9 @@ Ldtor: - } - - sem = SemanticDone; -+ -+ if (type->toBasetype()->ty == Terror) -+ errors = true; - } - - void VarDeclaration::semantic2(Scope *sc) -@@ -1743,6 +1769,55 @@ void VarDeclaration::semantic2(Scope *sc - init = init->semantic(sc, type, INITinterpret); - inuse--; - } -+ if (storage_class & STCmanifest) -+ { -+ #if 0 -+ if ((type->ty == Tclass)&&type->isMutable()) -+ { -+ error("is mutable. Only const and immutable class enum are allowed, not %s", type->toChars()); -+ } -+ else if (type->ty == Tpointer && type->nextOf()->ty == Tstruct && type->nextOf()->isMutable()) -+ { -+ ExpInitializer *ei = init->isExpInitializer(); -+ if (ei->exp->op == TOKaddress && ((AddrExp *)ei->exp)->e1->op == TOKstructliteral) -+ { -+ error("is a pointer to mutable struct. Only pointers to const or immutable struct enum are allowed, not %s", type->toChars()); -+ } -+ } -+ #else -+ if (type->ty == Tclass && init) -+ { -+ ExpInitializer *ei = init->isExpInitializer(); -+ if (ei->exp->op == TOKclassreference) -+ error(": Unable to initialize enum with class or pointer to struct. Use static const variable instead."); -+ } -+ else if (type->ty == Tpointer && type->nextOf()->ty == Tstruct) -+ { -+ ExpInitializer *ei = init->isExpInitializer(); -+ if (ei && ei->exp->op == TOKaddress && ((AddrExp *)ei->exp)->e1->op == TOKstructliteral) -+ { -+ error(": Unable to initialize enum with class or pointer to struct. Use static const variable instead."); -+ } -+ } -+ #endif -+ } -+ else if (init && isThreadlocal()) -+ { -+ if ((type->ty == Tclass)&&type->isMutable()&&!type->isShared()) -+ { -+ ExpInitializer *ei = init->isExpInitializer(); -+ if (ei->exp->op == TOKclassreference) -+ error("is mutable. Only const or immutable class thread local variable are allowed, not %s", type->toChars()); -+ } -+ else if (type->ty == Tpointer && type->nextOf()->ty == Tstruct && type->nextOf()->isMutable() &&!type->nextOf()->isShared()) -+ { -+ ExpInitializer *ei = init->isExpInitializer(); -+ if (ei && ei->exp->op == TOKaddress && ((AddrExp *)ei->exp)->e1->op == TOKstructliteral) -+ { -+ error("is a pointer to mutable struct. Only pointers to const, immutable or shared struct thread local variable are allowed are allowed, not %s", type->toChars()); -+ } -+ } -+ } - sem = Semantic2Done; - } - -@@ -1755,7 +1830,7 @@ void VarDeclaration::setFieldOffset(Aggr - TupleDeclaration *v2 = aliassym->isTupleDeclaration(); - assert(v2); - for (size_t i = 0; i < v2->objects->dim; i++) -- { Object *o = (*v2->objects)[i]; -+ { RootObject *o = (*v2->objects)[i]; - assert(o->dyncast() == DYNCAST_EXPRESSION); - Expression *e = (Expression *)o; - assert(e->op == TOKdsymbol); -@@ -1765,7 +1840,7 @@ void VarDeclaration::setFieldOffset(Aggr - return; - } - -- if (!(storage_class & STCfield)) -+ if (!isField()) - return; - assert(!(storage_class & (STCstatic | STCextern | STCparameter | STCtls))); - -@@ -1786,47 +1861,32 @@ void VarDeclaration::setFieldOffset(Aggr - { // References are the size of a pointer - t = Type::tvoidptr; - } -- if (t->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)t; --#if DMDV2 -- if (ts->sym == ad) -- { -- ad->error("cannot have field %s with same struct type", toChars()); -- } --#endif -- -- if (ts->sym->sizeok != SIZEOKdone && ts->sym->scope) -- ts->sym->semantic(NULL); -- if (ts->sym->sizeok != SIZEOKdone) -- { -- ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced -- return; -- } -- } -- if (t->ty == Tident) -+ if (t->ty == Tstruct || t->ty == Tsarray) - { -- ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced -- return; -- } --#if DMDV2 -- else if (t->ty == Tsarray) -- { -- Type *tv = t->toBasetype(); -- while (tv->ty == Tsarray) -- { -- tv = tv->nextOf()->toBasetype(); -- } -+ Type *tv = t->baseElemOf(); - if (tv->ty == Tstruct) - { - TypeStruct *ts = (TypeStruct *)tv; -- if (ad == ts->sym) -+ if (ts->sym == ad) -+ { -+ const char *s = (t->ty == Tsarray) ? "static array of " : ""; -+ ad->error("cannot have field %s with %ssame struct type", toChars(), s); -+ } -+ if (ts->sym->sizeok != SIZEOKdone && ts->sym->scope) -+ ts->sym->semantic(NULL); -+ if (ts->sym->sizeok != SIZEOKdone) - { -- ad->error("cannot have field %s with same struct type", toChars()); -+ ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced - return; - } - } - } --#endif -+ if (t->ty == Tident) -+ { -+ ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced -+ return; -+ } -+ - - unsigned memsize = t->size(loc); // size of member - unsigned memalignsize = Target::fieldalign(t); // size of member for alignment purposes -@@ -1885,9 +1945,10 @@ AggregateDeclaration *VarDeclaration::is - if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | - STCtls | STCgshared | STCctfe))) - { -+#if !PULL93 - if ((storage_class & (STCconst | STCimmutable | STCwild)) && init) - return NULL; -- -+#endif - for (Dsymbol *s = this; s; s = s->parent) - { - ad = s->isMember(); -@@ -1899,24 +1960,29 @@ AggregateDeclaration *VarDeclaration::is - return ad; - } - --int VarDeclaration::needThis() -+bool VarDeclaration::needThis() - { - //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class); -- return storage_class & STCfield; -+ return isField(); -+} -+ -+bool VarDeclaration::isExport() -+{ -+ return protection == PROTexport; - } - --int VarDeclaration::isImportedSymbol() -+bool VarDeclaration::isImportedSymbol() - { - if (protection == PROTexport && !init && - (storage_class & STCstatic || parent->isModule())) -- return TRUE; -- return FALSE; -+ return true; -+ return false; - } - - void VarDeclaration::checkCtorConstInit() - { - #if 0 /* doesn't work if more than one static ctor */ -- if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) -+ if (ctorinit == 0 && isCtorinit() && !isField()) - error("missing initializer in static constructor for const variable"); - #endif - } -@@ -1970,6 +2036,16 @@ void VarDeclaration::checkNestedReferenc - if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration()) - { - fld->tok = TOKdelegate; -+ -+ /* This is necessary to avoid breaking tests for 8751 & 8793. -+ * See: compilable/testInference.d -+ */ -+ if (type->isMutable() || // mutable variable -+ !type->implicitConvTo(type->immutableOf()) || // has any mutable indirections -+ !fdv->isPureBypassingInference()) // does not belong to pure function -+ { -+ fld->setImpure(); // Bugzilla 9415 -+ } - } - } - -@@ -2021,28 +2097,37 @@ ExpInitializer *VarDeclaration::getExpIn - * Otherwise, return NULL. - */ - --Expression *VarDeclaration::getConstInitializer() -+Expression *VarDeclaration::getConstInitializer(bool needFullType) - { -- if ((isConst() || isImmutable() || storage_class & STCmanifest) && -- storage_class & STCinit) -+ assert(type && init); -+ -+ // Ungag errors when not speculative -+ unsigned oldgag = global.gag; -+ if (global.isSpeculativeGagging()) - { -- ExpInitializer *ei = getExpInitializer(); -- if (ei) -- return ei->exp; -- else if (init) -- { -- return init->toExpression(); -- } -+ Dsymbol *sym = toParent()->isAggregateDeclaration(); -+ if (sym && !sym->isSpeculative()) -+ global.gag = 0; - } - -- return NULL; -+ if (scope) -+ { -+ inuse++; -+ init = init->semantic(scope, type, INITinterpret); -+ scope = NULL; -+ inuse--; -+ } -+ Expression *e = init->toExpression(needFullType ? type : NULL); -+ -+ global.gag = oldgag; -+ return e; - } - - /************************************* -- * Return !=0 if we can take the address of this variable. -+ * Return true if we can take the address of this variable. - */ - --int VarDeclaration::canTakeAddressOf() -+bool VarDeclaration::canTakeAddressOf() - { - #if 0 - /* Global variables and struct/class fields of the form: -@@ -2051,18 +2136,18 @@ int VarDeclaration::canTakeAddressOf() - */ - if ((isConst() || isImmutable()) && - storage_class & STCinit && -- (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) && -+ (!(storage_class & (STCstatic | STCextern)) || isField()) && - (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) && - type->toBasetype()->isTypeBasic() - ) - { -- return 0; -+ return false; - } - #else - if (storage_class & STCmanifest) -- return 0; -+ return false; - #endif -- return 1; -+ return true; - } - - -@@ -2071,7 +2156,7 @@ int VarDeclaration::canTakeAddressOf() - * Includes extern variables. - */ - --int VarDeclaration::isDataseg() -+bool VarDeclaration::isDataseg() - { - #if 0 - printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars()); -@@ -2079,12 +2164,12 @@ int VarDeclaration::isDataseg() - printf("parent = '%s'\n", parent->toChars()); - #endif - if (storage_class & STCmanifest) -- return 0; -+ return false; - Dsymbol *parent = this->toParent(); - if (!parent && !(storage_class & STCstatic)) - { error("forward referenced"); - type = Type::terror; -- return 0; -+ return false; - } - return canTakeAddressOf() && - (storage_class & (STCstatic | STCextern | STCtls | STCgshared) || -@@ -2096,7 +2181,7 @@ int VarDeclaration::isDataseg() - * Does symbol go into thread local storage? - */ - --int VarDeclaration::isThreadlocal() -+bool VarDeclaration::isThreadlocal() - { - //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars()); - #if 0 //|| TARGET_OSX -@@ -2109,7 +2194,7 @@ int VarDeclaration::isThreadlocal() - /* Data defaults to being thread-local. It is not thread-local - * if it is immutable, const or shared. - */ -- int i = isDataseg() && -+ bool i = isDataseg() && - !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared)); - //printf("\treturn %d\n", i); - return i; -@@ -2120,29 +2205,29 @@ int VarDeclaration::isThreadlocal() - * Can variable be read and written by CTFE? - */ - --int VarDeclaration::isCTFE() -+bool VarDeclaration::isCTFE() - { - return (storage_class & STCctfe) != 0; // || !isDataseg(); - } - --int VarDeclaration::hasPointers() -+bool VarDeclaration::hasPointers() - { - //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); - return (!isDataseg() && type->hasPointers()); - } - - /****************************************** -- * Return TRUE if variable needs to call the destructor. -+ * Return true if variable needs to call the destructor. - */ - --int VarDeclaration::needsAutoDtor() -+bool VarDeclaration::needsAutoDtor() - { - //printf("VarDeclaration::needsAutoDtor() %s\n", toChars()); - - if (noscope || !edtor) -- return FALSE; -+ return false; - -- return TRUE; -+ return true; - } - - -@@ -2163,19 +2248,14 @@ Expression *VarDeclaration::callScopeDto - } - - // Destructors for structs and arrays of structs -- bool array = false; -- Type *tv = type->toBasetype(); -- while (tv->ty == Tsarray) -- { TypeSArray *ta = (TypeSArray *)tv; -- array = true; -- tv = tv->nextOf()->toBasetype(); -- } -+ Type *tv = type->baseElemOf(); - if (tv->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)tv; -+ { -+ TypeStruct *ts = (TypeStruct *)tv; - StructDeclaration *sd = ts->sym; - if (sd->dtor) - { -- if (array) -+ if (type->toBasetype()->ty == Tsarray) - { - // Typeinfo.destroy(cast(void*)&v); - Expression *ea = new SymOffExp(loc, this, 0, 0); -@@ -2236,15 +2316,24 @@ Expression *VarDeclaration::callScopeDto - - void ObjectNotFound(Identifier *id) - { -- Type::error(0, "%s not found. object.d may be incorrectly installed or corrupt.", id->toChars()); -+ Type::error(Loc(), "%s not found. object.d may be incorrectly installed or corrupt.", id->toChars()); - fatal(); - } - -+/******************************** SymbolDeclaration ********************************/ -+ -+SymbolDeclaration::SymbolDeclaration(Loc loc, StructDeclaration *dsym) -+ : Declaration(dsym->ident) -+{ -+ this->loc = loc; -+ this->dsym = dsym; -+ storage_class |= STCconst; -+} - - /********************************* ClassInfoDeclaration ****************************/ - - ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd) -- : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL) -+ : VarDeclaration(Loc(), Type::typeinfoclass->type, cd->ident, NULL) - { - this->cd = cd; - storage_class = STCstatic | STCgshared; -@@ -2260,29 +2349,10 @@ void ClassInfoDeclaration::semantic(Scop - { - } - --/********************************* ModuleInfoDeclaration ****************************/ -- --ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod) -- : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL) --{ -- this->mod = mod; -- storage_class = STCstatic | STCgshared; --} -- --Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s) --{ -- assert(0); // should never be produced by syntax -- return NULL; --} -- --void ModuleInfoDeclaration::semantic(Scope *sc) --{ --} -- - /********************************* TypeInfoDeclaration ****************************/ - - TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal) -- : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) -+ : VarDeclaration(Loc(), Type::dtypeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) - { - this->tinfo = tinfo; - storage_class = STCstatic | STCgshared; -@@ -2301,6 +2371,17 @@ void TypeInfoDeclaration::semantic(Scope - assert(linkage == LINKc); - } - -+char *TypeInfoDeclaration::toChars() -+{ -+ //printf("TypeInfoDeclaration::toChars() tinfo = %s\n", tinfo->toChars()); -+ OutBuffer buf; -+ buf.writestring("typeid("); -+ buf.writestring(tinfo->toChars()); -+ buf.writeByte(')'); -+ buf.writeByte(0); -+ return buf.extractData(); -+} -+ - /***************************** TypeInfoConstDeclaration **********************/ - - #if DMDV2 ---- a/src/gcc/d/dfrontend/declaration.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/declaration.h 2014-04-01 16:32:51.000000000 +0100 -@@ -19,19 +19,19 @@ - #include "lexer.h" - #include "mtype.h" - --struct Expression; --struct Statement; --struct LabelDsymbol; --struct Initializer; --struct Module; -+class Expression; -+class Statement; -+class LabelDsymbol; -+class Initializer; -+class Module; - struct InlineScanState; --struct ForeachStatement; --struct FuncDeclaration; --struct ExpInitializer; --struct StructDeclaration; --struct TupleType; -+class ForeachStatement; -+class FuncDeclaration; -+class ExpInitializer; -+class StructDeclaration; - struct InterState; - struct IRState; -+struct CompiledCtfeFunction; - - enum PROT; - enum LINK; -@@ -87,15 +87,11 @@ enum PURE; - #define STCtemp 0x10000000000LL // temporary variable introduced by inlining - // and used only in backend process, so it's rvalue - --#define STCStorageClass (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal | \ -- STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias | \ -- STCout | STCin | \ -- STCmanifest | STCimmutable | STCshared | STCnothrow | STCpure | STCref | STCtls | \ -- STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable) -- --#ifdef BUG6652 --#define STCbug6652 0x800000000000LL // --#endif -+const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal | -+ STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias | -+ STCout | STCin | -+ STCmanifest | STCimmutable | STCshared | STCnothrow | STCpure | STCref | STCtls | -+ STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable); - - struct Match - { -@@ -106,11 +102,10 @@ struct Match - FuncDeclaration *anyf; // pick a func, any func, to use for error recovery - }; - --void overloadResolveX(Match *m, FuncDeclaration *f, -- Expression *ethis, Expressions *arguments); --int overloadApply(FuncDeclaration *fstart, -- int (*fp)(void *, FuncDeclaration *), -- void *param); -+void functionResolve(Match *m, Dsymbol *fd, Loc loc, Scope *sc, Objects *tiargs, Type *tthis, Expressions *fargs); -+int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *)); -+ -+void ObjectNotFound(Identifier *id); - - enum Semantic - { -@@ -122,16 +117,17 @@ enum Semantic - - /**************************************************************/ - --struct Declaration : Dsymbol -+class Declaration : public Dsymbol - { -+public: - Type *type; - Type *originalType; // before semantic analysis - StorageClass storage_class; -- enum PROT protection; -- enum LINK linkage; -+ PROT protection; -+ LINK linkage; - int inuse; // used to detect cycles -- -- enum Semantic sem; -+ const char *mangleOverride; // overridden symbol with pragma(mangle, "...") -+ Semantic sem; - - Declaration(Identifier *id); - void semantic(Scope *sc); -@@ -143,44 +139,46 @@ struct Declaration : Dsymbol - - void emitComment(Scope *sc); - void toJson(JsonOut *json); -- void jsonProperties(JsonOut *json); -+ virtual void jsonProperties(JsonOut *json); - void toDocBuffer(OutBuffer *buf, Scope *sc); - -- char *mangle(bool isv = false); -- int isStatic() { return storage_class & STCstatic; } -- virtual int isDelete(); -- virtual int isDataseg(); -- virtual int isThreadlocal(); -- virtual int isCodeseg(); -- int isCtorinit() { return storage_class & STCctorinit; } -- int isFinal() { return storage_class & STCfinal; } -- int isAbstract() { return storage_class & STCabstract; } -- int isConst() { return storage_class & STCconst; } -- int isImmutable() { return storage_class & STCimmutable; } -- int isWild() { return storage_class & STCwild; } -- int isAuto() { return storage_class & STCauto; } -- int isScope() { return storage_class & STCscope; } -- int isSynchronized() { return storage_class & STCsynchronized; } -- int isParameter() { return storage_class & STCparameter; } -- int isDeprecated() { return storage_class & STCdeprecated; } -- int isOverride() { return storage_class & STCoverride; } -- StorageClass isResult() { return storage_class & STCresult; } -- -- int isIn() { return storage_class & STCin; } -- int isOut() { return storage_class & STCout; } -- int isRef() { return storage_class & STCref; } -+ const char *mangle(bool isv = false); -+ bool isStatic() { return (storage_class & STCstatic) != 0; } -+ virtual bool isDelete(); -+ virtual bool isDataseg(); -+ virtual bool isThreadlocal(); -+ virtual bool isCodeseg(); -+ bool isCtorinit() { return (storage_class & STCctorinit) != 0; } -+ bool isFinal() { return (storage_class & STCfinal) != 0; } -+ bool isAbstract() { return (storage_class & STCabstract) != 0; } -+ bool isConst() { return (storage_class & STCconst) != 0; } -+ bool isImmutable() { return (storage_class & STCimmutable) != 0; } -+ bool isWild() { return (storage_class & STCwild) != 0; } -+ bool isAuto() { return (storage_class & STCauto) != 0; } -+ bool isScope() { return (storage_class & STCscope) != 0; } -+ bool isSynchronized() { return (storage_class & STCsynchronized) != 0; } -+ bool isParameter() { return (storage_class & STCparameter) != 0; } -+ bool isDeprecated() { return (storage_class & STCdeprecated) != 0; } -+ bool isOverride() { return (storage_class & STCoverride) != 0; } -+ bool isResult() { return (storage_class & STCresult) != 0; } -+ bool isField() { return (storage_class & STCfield) != 0; } -+ -+ bool isIn() { return (storage_class & STCin) != 0; } -+ bool isOut() { return (storage_class & STCout) != 0; } -+ bool isRef() { return (storage_class & STCref) != 0; } - -- enum PROT prot(); -+ PROT prot(); - - Declaration *isDeclaration() { return this; } - }; - - /**************************************************************/ - --struct TupleDeclaration : Declaration -+class TupleDeclaration : public Declaration - { -+public: - Objects *objects; -- int isexp; // 1: expression tuple -+ bool isexp; // true: expression tuple - - TypeTuple *tupletype; // !=NULL if this is a type tuple - -@@ -188,15 +186,16 @@ struct TupleDeclaration : Declaration - Dsymbol *syntaxCopy(Dsymbol *); - const char *kind(); - Type *getType(); -- int needThis(); -+ bool needThis(); - - TupleDeclaration *isTupleDeclaration() { return this; } - }; - - /**************************************************************/ - --struct TypedefDeclaration : Declaration -+class TypedefDeclaration : public Declaration - { -+public: - Type *basetype; - Initializer *init; - -@@ -204,7 +203,7 @@ struct TypedefDeclaration : Declaration - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - void semantic2(Scope *sc); -- char *mangle(bool isv = false); -+ const char *mangle(bool isv = false); - const char *kind(); - Type *getType(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -226,18 +225,19 @@ struct TypedefDeclaration : Declaration - - /**************************************************************/ - --struct AliasDeclaration : Declaration -+class AliasDeclaration : public Declaration - { -+public: - Dsymbol *aliassym; - Dsymbol *overnext; // next in overload list - Dsymbol *import; // !=NULL if unresolved internal alias for selective import -- int inSemantic; -+ bool inSemantic; - - AliasDeclaration(Loc loc, Identifier *ident, Type *type); - AliasDeclaration(Loc loc, Identifier *ident, Dsymbol *s); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); -- int overloadInsert(Dsymbol *s); -+ bool overloadInsert(Dsymbol *s); - const char *kind(); - Type *getType(); - Dsymbol *toAlias(); -@@ -252,8 +252,9 @@ struct AliasDeclaration : Declaration - - /**************************************************************/ - --struct VarDeclaration : Declaration -+class VarDeclaration : public Declaration - { -+public: - Initializer *init; - unsigned offset; - bool noscope; // no auto semantics -@@ -298,27 +299,27 @@ struct VarDeclaration : Declaration - Type *htype; - Initializer *hinit; - AggregateDeclaration *isThis(); -- int needThis(); -- int isImportedSymbol(); -- int isDataseg(); -- int isThreadlocal(); -- int isCTFE(); -- int hasPointers(); -+ bool needThis(); -+ bool isExport(); -+ bool isImportedSymbol(); -+ bool isDataseg(); -+ bool isThreadlocal(); -+ bool isCTFE(); -+ bool hasPointers(); - #if DMDV2 -- int canTakeAddressOf(); -- int needsAutoDtor(); -+ bool canTakeAddressOf(); -+ bool needsAutoDtor(); - #endif - Expression *callScopeDtor(Scope *sc); - ExpInitializer *getExpInitializer(); -- Expression *getConstInitializer(); -+ Expression *getConstInitializer(bool needFullType = true); - void checkCtorConstInit(); - void checkNestedReference(Scope *sc, Loc loc); - Dsymbol *toAlias(); -- - Symbol *toSymbol(); - void toObjFile(int multiobj); // compile to .obj file - int cvMember(unsigned char *p); -- -+ const char *mangle(bool isv = false); - // Eliminate need for dynamic_cast - VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } - }; -@@ -327,12 +328,12 @@ struct VarDeclaration : Declaration - - // This is a shell around a back end symbol - --struct SymbolDeclaration : Declaration -+class SymbolDeclaration : public Declaration - { -- Symbol *sym; -+public: - StructDeclaration *dsym; - -- SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym); -+ SymbolDeclaration(Loc loc, StructDeclaration *dsym); - - Symbol *toSymbol(); - -@@ -340,8 +341,9 @@ struct SymbolDeclaration : Declaration - SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; } - }; - --struct ClassInfoDeclaration : VarDeclaration -+class ClassInfoDeclaration : public VarDeclaration - { -+public: - ClassDeclaration *cd; - - ClassInfoDeclaration(ClassDeclaration *cd); -@@ -354,27 +356,15 @@ struct ClassInfoDeclaration : VarDeclara - Symbol *toSymbol(); - }; - --struct ModuleInfoDeclaration : VarDeclaration --{ -- Module *mod; -- -- ModuleInfoDeclaration(Module *mod); -- Dsymbol *syntaxCopy(Dsymbol *); -- void semantic(Scope *sc); -- -- void emitComment(Scope *sc); -- void toJson(JsonOut *json); -- -- Symbol *toSymbol(); --}; -- --struct TypeInfoDeclaration : VarDeclaration -+class TypeInfoDeclaration : public VarDeclaration - { -+public: - Type *tinfo; - - TypeInfoDeclaration(Type *tinfo, int internal); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); -+ char *toChars(); - - void emitComment(Scope *sc); - void toJson(JsonOut *json); -@@ -382,124 +372,143 @@ struct TypeInfoDeclaration : VarDeclarat - Symbol *toSymbol(); - void toObjFile(int multiobj); // compile to .obj file - virtual void toDt(dt_t **pdt); -+ -+ TypeInfoDeclaration *isTypeInfoDeclaration() { return this; } - }; - --struct TypeInfoStructDeclaration : TypeInfoDeclaration -+class TypeInfoStructDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoStructDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoClassDeclaration : TypeInfoDeclaration -+class TypeInfoClassDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoClassDeclaration(Type *tinfo); - Symbol *toSymbol(); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoInterfaceDeclaration : TypeInfoDeclaration -+class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoInterfaceDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoTypedefDeclaration : TypeInfoDeclaration -+class TypeInfoTypedefDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoTypedefDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoPointerDeclaration : TypeInfoDeclaration -+class TypeInfoPointerDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoPointerDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoArrayDeclaration : TypeInfoDeclaration -+class TypeInfoArrayDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoArrayDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoStaticArrayDeclaration : TypeInfoDeclaration -+class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoStaticArrayDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration -+class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoAssociativeArrayDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoEnumDeclaration : TypeInfoDeclaration -+class TypeInfoEnumDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoEnumDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoFunctionDeclaration : TypeInfoDeclaration -+class TypeInfoFunctionDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoFunctionDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoDelegateDeclaration : TypeInfoDeclaration -+class TypeInfoDelegateDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoDelegateDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoTupleDeclaration : TypeInfoDeclaration -+class TypeInfoTupleDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoTupleDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - - #if DMDV2 --struct TypeInfoConstDeclaration : TypeInfoDeclaration -+class TypeInfoConstDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoConstDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoInvariantDeclaration : TypeInfoDeclaration -+class TypeInfoInvariantDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoInvariantDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoSharedDeclaration : TypeInfoDeclaration -+class TypeInfoSharedDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoSharedDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoWildDeclaration : TypeInfoDeclaration -+class TypeInfoWildDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoWildDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); - }; - --struct TypeInfoVectorDeclaration : TypeInfoDeclaration -+class TypeInfoVectorDeclaration : public TypeInfoDeclaration - { -+public: - TypeInfoVectorDeclaration(Type *tinfo); - - void toDt(dt_t **pdt); -@@ -508,8 +517,9 @@ struct TypeInfoVectorDeclaration : TypeI - - /**************************************************************/ - --struct ThisDeclaration : VarDeclaration -+class ThisDeclaration : public VarDeclaration - { -+public: - ThisDeclaration(Loc loc, Type *t); - Dsymbol *syntaxCopy(Dsymbol *); - ThisDeclaration *isThisDeclaration() { return this; } -@@ -548,14 +558,15 @@ enum BUILTIN - #endif - }; - --Expression *eval_builtin(Loc loc, enum BUILTIN builtin, Expressions *arguments); -+Expression *eval_builtin(Loc loc, BUILTIN builtin, Expressions *arguments); - - #else - enum BUILTIN { }; - #endif - --struct FuncDeclaration : Declaration -+class FuncDeclaration : public Declaration - { -+public: - Types *fthrows; // Array of Type's of exceptions (not used) - Statement *frequire; - Statement *fensure; -@@ -581,23 +592,26 @@ struct FuncDeclaration : Declaration - VarDeclaration *v_argsave; // save area for args passed in registers for variadic functions - VarDeclarations *parameters; // Array of VarDeclaration's for parameters - DsymbolTable *labtab; // statement label symbol table -- Declaration *overnext; // next in overload list -+ Dsymbol *overnext; // next in overload list -+ FuncDeclaration *overnext0; // next in overload list (only used during IFTI) - Loc endloc; // location of closing curly bracket - int vtblIndex; // for member functions, index into vtbl[] -- bool naked; // !=0 if naked -+ bool naked; // true if naked - ILS inlineStatusStmt; - ILS inlineStatusExp; -+ -+ CompiledCtfeFunction *ctfeCode; // Compiled code for interpreter - int inlineNest; // !=0 if nested inline -- bool isArrayOp; // !=0 if array operation -- enum PASS semanticRun; -+ bool isArrayOp; // true if array operation -+ FuncDeclaration *dArrayOp; // D version of array op for ctfe - int semantic3Errors; // !=0 if errors in semantic3 - // this function's frame ptr - ForeachStatement *fes; // if foreach body, this is the foreach -- bool introducing; // !=0 if 'introducing' function -+ bool introducing; // true if 'introducing' function - Type *tintro; // if !=NULL, then this is the type - // of the 'introducing' function - // this one is overriding -- int inferRetType; // !=0 if return type is to be inferred -+ bool inferRetType; // true if return type is to be inferred - StorageClass storage_class2; // storage class for template onemember's - - // Things that should really go into Scope -@@ -607,14 +621,14 @@ struct FuncDeclaration : Declaration - // 8 if there's inline asm - - // Support for NRVO (named return value optimization) -- bool nrvo_can; // !=0 means we can do it -+ bool nrvo_can; // true means we can do it - VarDeclaration *nrvo_var; // variable to replace with shidden - Symbol *shidden; // hidden pointer passed to function - - ReturnStatements *returns; - - #if DMDV2 -- enum BUILTIN builtin; // set if this is a known, builtin -+ BUILTIN builtin; // set if this is a known, builtin - // function we can evaluate at compile - // time - -@@ -645,16 +659,16 @@ struct FuncDeclaration : Declaration - bool functionSemantic3(); - // called from semantic3 - VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad); -- int equals(Object *o); -+ bool equals(RootObject *o); - - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs); - void toJson(JsonOut *json); - int overrides(FuncDeclaration *fd); - int findVtblIndex(Dsymbols *vtbl, int dim); -- int overloadInsert(Dsymbol *s); -+ bool overloadInsert(Dsymbol *s); - FuncDeclaration *overloadExactMatch(Type *t); -- FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags = 0); -+ TemplateDeclaration *findTemplateDeclRoot(); - MATCH leastAsSpecialized(FuncDeclaration *g); - LabelDsymbol *searchLabel(Identifier *ident); - AggregateDeclaration *isThis(); -@@ -662,33 +676,37 @@ struct FuncDeclaration : Declaration - int getLevel(Loc loc, Scope *sc, FuncDeclaration *fd); // lexical nesting level difference - void appendExp(Expression *e); - void appendState(Statement *s); -- char *mangle(bool isv = false); -+ const char *mangle(bool isv = false); -+ const char *mangleExact(bool isv = false); - const char *toPrettyChars(); -- int isMain(); -- int isWinMain(); -- int isDllMain(); -- enum BUILTIN isBuiltin(); -- int isExport(); -- int isImportedSymbol(); -- int isAbstract(); -- int isCodeseg(); -- int isOverloadable(); -- int hasOverloads(); -- enum PURE isPure(); -- enum PURE isPureBypassingInference(); -+ const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure' -+ bool isMain(); -+ bool isWinMain(); -+ bool isDllMain(); -+ BUILTIN isBuiltin(); -+ bool isExport(); -+ bool isImportedSymbol(); -+ bool isCodeseg(); -+ bool isOverloadable(); -+ bool hasOverloads(); -+ PURE isPure(); -+ PURE isPureBypassingInference(); - bool setImpure(); -- int isSafe(); -+ bool isSafe(); - bool isSafeBypassingInference(); -- int isTrusted(); -+ bool isTrusted(); - bool setUnsafe(); -- virtual int isNested(); -- int needThis(); -- int isVirtualMethod(); -- virtual int isVirtual(); -- virtual int isFinal(); -- virtual int addPreInvariant(); -- virtual int addPostInvariant(); -+ bool isolateReturn(); -+ bool parametersIntersect(Type *t); -+ virtual bool isNested(); -+ bool needThis(); -+ bool isVirtualMethod(); -+ virtual bool isVirtual(); -+ virtual bool isFinalFunc(); -+ virtual bool addPreInvariant(); -+ virtual bool addPostInvariant(); - Expression *interpret(InterState *istate, Expressions *arguments, Expression *thisexp = NULL); -+ void ctfeCompile(); - void inlineScan(); - int canInline(int hasthis, int hdrscan, int statementsToo); - Expression *expandInline(InlineScanState *iss, Expression *ethis, Expressions *arguments, Statement **ps); -@@ -696,15 +714,15 @@ struct FuncDeclaration : Declaration - void toDocBuffer(OutBuffer *buf, Scope *sc); - FuncDeclaration *isUnique(); - void checkNestedReference(Scope *sc, Loc loc); -- int needsClosure(); -- int hasNestedFrameRefs(); -+ bool needsClosure(); -+ bool hasNestedFrameRefs(); - void buildResultVar(); - Statement *mergeFrequire(Statement *); -- Statement *mergeFensure(Statement *); -+ Statement *mergeFensure(Statement *, Identifier *oid); - Parameters *getParameters(int *pvarargs); - -- static FuncDeclaration *genCfunc(Type *treturn, const char *name); -- static FuncDeclaration *genCfunc(Type *treturn, Identifier *id); -+ static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name); -+ static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id); - - Symbol *toSymbol(); - Symbol *toThunkSymbol(int offset); // thunk version -@@ -718,105 +736,110 @@ struct FuncDeclaration : Declaration - }; - - #if DMDV2 --FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s, -+FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s, - Objects *tiargs, -- Expression *ethis, -+ Type *tthis, - Expressions *arguments, -- int flags); -+ int flags = 0); - #endif - --struct FuncAliasDeclaration : FuncDeclaration -+class FuncAliasDeclaration : public FuncDeclaration - { -+public: - FuncDeclaration *funcalias; -- int hasOverloads; -+ bool hasOverloads; - -- FuncAliasDeclaration(FuncDeclaration *funcalias, int hasOverloads = 1); -+ FuncAliasDeclaration(FuncDeclaration *funcalias, bool hasOverloads = true); - - FuncAliasDeclaration *isFuncAliasDeclaration() { return this; } - const char *kind(); - Symbol *toSymbol(); -- char *mangle(bool isv = false) { return toAliasFunc()->mangle(isv); } -+ const char *mangle(bool isv = false); - - FuncDeclaration *toAliasFunc(); - }; - --struct FuncLiteralDeclaration : FuncDeclaration -+class FuncLiteralDeclaration : public FuncDeclaration - { -- enum TOK tok; // TOKfunction or TOKdelegate -+public: -+ TOK tok; // TOKfunction or TOKdelegate - Type *treq; // target of return type inference - -- FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, enum TOK tok, -- ForeachStatement *fes); -+ FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, TOK tok, -+ ForeachStatement *fes, Identifier *id = NULL); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - Dsymbol *syntaxCopy(Dsymbol *); -- int isNested(); -- int isVirtual(); -+ bool isNested(); -+ bool isVirtual(); - - FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; } - const char *kind(); - }; - --struct CtorDeclaration : FuncDeclaration -+class CtorDeclaration : public FuncDeclaration - { -+public: - CtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Type *type); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - const char *kind(); - char *toChars(); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -- bool isImplicit; // implicitly generated ctor -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); - - CtorDeclaration *isCtorDeclaration() { return this; } - }; - - #if DMDV2 --struct PostBlitDeclaration : FuncDeclaration -+class PostBlitDeclaration : public FuncDeclaration - { -+public: - PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void toJson(JsonOut *json); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -- int overloadInsert(Dsymbol *s); -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); -+ bool overloadInsert(Dsymbol *s); - void emitComment(Scope *sc); - - PostBlitDeclaration *isPostBlitDeclaration() { return this; } - }; - #endif - --struct DtorDeclaration : FuncDeclaration -+class DtorDeclaration : public FuncDeclaration - { -+public: - DtorDeclaration(Loc loc, Loc endloc); -- DtorDeclaration(Loc loc, Loc endloc, Identifier *id); -+ DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - const char *kind(); - char *toChars(); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -- int overloadInsert(Dsymbol *s); -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); -+ bool overloadInsert(Dsymbol *s); - void emitComment(Scope *sc); - - DtorDeclaration *isDtorDeclaration() { return this; } - }; - --struct StaticCtorDeclaration : FuncDeclaration -+class StaticCtorDeclaration : public FuncDeclaration - { -+public: - StaticCtorDeclaration(Loc loc, Loc endloc); - StaticCtorDeclaration(Loc loc, Loc endloc, const char *name); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - AggregateDeclaration *isThis(); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); - bool hasStaticCtorOrDtor(); - void emitComment(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -825,8 +848,9 @@ struct StaticCtorDeclaration : FuncDecla - }; - - #if DMDV2 --struct SharedStaticCtorDeclaration : StaticCtorDeclaration -+class SharedStaticCtorDeclaration : public StaticCtorDeclaration - { -+public: - SharedStaticCtorDeclaration(Loc loc, Loc endloc); - Dsymbol *syntaxCopy(Dsymbol *); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -835,18 +859,20 @@ struct SharedStaticCtorDeclaration : Sta - }; - #endif - --struct StaticDtorDeclaration : FuncDeclaration --{ VarDeclaration *vgate; // 'gate' variable -+class StaticDtorDeclaration : public FuncDeclaration -+{ -+public: -+ VarDeclaration *vgate; // 'gate' variable - -- StaticDtorDeclaration(Loc loc, Loc endloc); -- StaticDtorDeclaration(Loc loc, Loc endloc, const char *name); -+ StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc); -+ StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - AggregateDeclaration *isThis(); -- int isVirtual(); -+ bool isVirtual(); - bool hasStaticCtorOrDtor(); -- int addPreInvariant(); -- int addPostInvariant(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); - void emitComment(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - -@@ -854,9 +880,10 @@ struct StaticDtorDeclaration : FuncDecla - }; - - #if DMDV2 --struct SharedStaticDtorDeclaration : StaticDtorDeclaration -+class SharedStaticDtorDeclaration : public StaticDtorDeclaration - { -- SharedStaticDtorDeclaration(Loc loc, Loc endloc); -+public: -+ SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc); - Dsymbol *syntaxCopy(Dsymbol *); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - -@@ -864,36 +891,42 @@ struct SharedStaticDtorDeclaration : Sta - }; - #endif - --struct InvariantDeclaration : FuncDeclaration -+class InvariantDeclaration : public FuncDeclaration - { -- InvariantDeclaration(Loc loc, Loc endloc); -+public: -+ InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id = NULL); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); - void emitComment(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - InvariantDeclaration *isInvariantDeclaration() { return this; } - }; - --struct UnitTestDeclaration : FuncDeclaration -+class UnitTestDeclaration : public FuncDeclaration - { -- UnitTestDeclaration(Loc loc, Loc endloc); -+public: -+ char *codedoc; /** For documented unittest. */ -+ UnitTestDeclaration(Loc loc, Loc endloc, char *codedoc); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - AggregateDeclaration *isThis(); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); -+ void emitComment(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - UnitTestDeclaration *isUnitTestDeclaration() { return this; } - }; - --struct NewDeclaration : FuncDeclaration --{ Parameters *arguments; -+class NewDeclaration : public FuncDeclaration -+{ -+public: -+ Parameters *arguments; - int varargs; - - NewDeclaration(Loc loc, Loc endloc, Parameters *arguments, int varargs); -@@ -901,26 +934,28 @@ struct NewDeclaration : FuncDeclaration - void semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - const char *kind(); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); - - NewDeclaration *isNewDeclaration() { return this; } - }; - - --struct DeleteDeclaration : FuncDeclaration --{ Parameters *arguments; -+class DeleteDeclaration : public FuncDeclaration -+{ -+public: -+ Parameters *arguments; - - DeleteDeclaration(Loc loc, Loc endloc, Parameters *arguments); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - const char *kind(); -- int isDelete(); -- int isVirtual(); -- int addPreInvariant(); -- int addPostInvariant(); -+ bool isDelete(); -+ bool isVirtual(); -+ bool addPreInvariant(); -+ bool addPostInvariant(); - DeleteDeclaration *isDeleteDeclaration() { return this; } - }; - ---- a/src/gcc/d/dfrontend/delegatize.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/delegatize.c 2014-04-01 16:32:51.000000000 +0100 -@@ -116,7 +116,7 @@ int lambdaCheckForNestedRef(Expression * - { SymOffExp *se = (SymOffExp *)e; - VarDeclaration *v = se->var->isVarDeclaration(); - if (v) -- v->checkNestedReference(sc, 0); -+ v->checkNestedReference(sc, Loc()); - break; - } - -@@ -124,7 +124,7 @@ int lambdaCheckForNestedRef(Expression * - { VarExp *ve = (VarExp *)e; - VarDeclaration *v = ve->var->isVarDeclaration(); - if (v) -- v->checkNestedReference(sc, 0); -+ v->checkNestedReference(sc, Loc()); - break; - } - -@@ -133,7 +133,7 @@ int lambdaCheckForNestedRef(Expression * - { ThisExp *te = (ThisExp *)e; - VarDeclaration *v = te->var->isVarDeclaration(); - if (v) -- v->checkNestedReference(sc, 0); -+ v->checkNestedReference(sc, Loc()); - break; - } - -@@ -142,7 +142,7 @@ int lambdaCheckForNestedRef(Expression * - VarDeclaration *v = de->declaration->isVarDeclaration(); - if (v) - { -- v->checkNestedReference(sc, 0); -+ v->checkNestedReference(sc, Loc()); - - /* Some expressions cause the frontend to create a temporary. - * For example, structs with cpctors replace the original ---- a/src/gcc/d/dfrontend/doc.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/doc.c 2014-04-01 16:32:51.000000000 +0100 -@@ -44,12 +44,13 @@ struct Escape - const char *escapeChar(unsigned c); - }; - --struct Section -+class Section - { -- unsigned char *name; -+public: -+ utf8_t *name; - size_t namelen; - -- unsigned char *body; -+ utf8_t *body; - size_t bodylen; - - int nooutput; -@@ -57,17 +58,19 @@ struct Section - virtual void write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf); - }; - --struct ParamSection : Section -+class ParamSection : public Section - { -+public: - void write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf); - }; - --struct MacroSection : Section -+class MacroSection : public Section - { -+public: - void write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf); - }; - --typedef ArrayBase
Sections; -+typedef Array
Sections; - - struct DocComment - { -@@ -83,32 +86,35 @@ struct DocComment - summary(NULL), copyright(NULL), macros(NULL), pmacrotable(NULL), pescapetable(NULL) - { } - -- static DocComment *parse(Scope *sc, Dsymbol *s, unsigned char *comment); -- static void parseMacros(Escape **pescapetable, Macro **pmacrotable, unsigned char *m, size_t mlen); -- static void parseEscapes(Escape **pescapetable, unsigned char *textstart, size_t textlen); -+ static DocComment *parse(Scope *sc, Dsymbol *s, utf8_t *comment); -+ static void parseMacros(Escape **pescapetable, Macro **pmacrotable, utf8_t *m, size_t mlen); -+ static void parseEscapes(Escape **pescapetable, utf8_t *textstart, size_t textlen); - -- void parseSections(unsigned char *comment); -+ void parseSections(utf8_t *comment); - void writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf); - }; - - - int cmp(const char *stringz, void *s, size_t slen); - int icmp(const char *stringz, void *s, size_t slen); --int isDitto(unsigned char *comment); --unsigned char *skipwhitespace(unsigned char *p); -+int isDitto(utf8_t *comment); -+utf8_t *skipwhitespace(utf8_t *p); - size_t skiptoident(OutBuffer *buf, size_t i); - size_t skippastident(OutBuffer *buf, size_t i); - size_t skippastURL(OutBuffer *buf, size_t i); - void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset); - void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset, bool anchor = true); - void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset); --Parameter *isFunctionParameter(Dsymbol *s, unsigned char *p, size_t len); -+TypeFunction *isTypeFunction(Dsymbol *s); -+Parameter *isFunctionParameter(Dsymbol *s, utf8_t *p, size_t len); -+TemplateParameter *isTemplateParameter(Dsymbol *s, utf8_t *p, size_t len); -+ -+int isIdStart(utf8_t *p); -+int isIdTail(utf8_t *p); -+int isIndentWS(utf8_t *p); -+int utfStride(utf8_t *p); - --int isIdStart(unsigned char *p); --int isIdTail(unsigned char *p); --int utfStride(unsigned char *p); -- --static unsigned char ddoc_default[] = "\ -+static const char ddoc_default[] = "\ - DDOC = \n\ - \n\ - $(TITLE)\n\ -@@ -140,6 +146,7 @@ LINK2 = $+\n\ - LPAREN= (\n\ - RPAREN= )\n\ - DOLLAR= $\n\ -+DEPRECATED= $0\n\ - \n\ - RED = $0\n\ - BLUE = $0\n\ -@@ -183,6 +190,7 @@ DDOC_CLASS_MEMBERS = $(DDOC_MEMBERS $0) - DDOC_STRUCT_MEMBERS = $(DDOC_MEMBERS $0)\n\ - DDOC_ENUM_MEMBERS = $(DDOC_MEMBERS $0)\n\ - DDOC_TEMPLATE_MEMBERS = $(DDOC_MEMBERS $0)\n\ -+DDOC_ENUM_BASETYPE = $0\n\ - DDOC_PARAMS = $(B Params:)$(BR)\n$(TABLE $0)$(BR)\n\ - DDOC_PARAM_ROW = $(TR $0)\n\ - DDOC_PARAM_ID = $(TD $0)\n\ -@@ -199,11 +207,11 @@ ESCAPES = /toChars(); -- Macro::define(¯otable, (unsigned char *)"SRCFILENAME", 11, (unsigned char *)srcfilename, strlen(srcfilename)); -+ Macro::define(¯otable, (utf8_t *)"SRCFILENAME", 11, (utf8_t *)srcfilename, strlen(srcfilename)); - - char *docfilename = docfile->toChars(); -- Macro::define(¯otable, (unsigned char *)"DOCFILENAME", 11, (unsigned char *)docfilename, strlen(docfilename)); -+ Macro::define(¯otable, (utf8_t *)"DOCFILENAME", 11, (utf8_t *)docfilename, strlen(docfilename)); - - if (dc->copyright) - { - dc->copyright->nooutput = 1; -- Macro::define(¯otable, (unsigned char *)"COPYRIGHT", 9, dc->copyright->body, dc->copyright->bodylen); -+ Macro::define(¯otable, (utf8_t *)"COPYRIGHT", 9, dc->copyright->body, dc->copyright->bodylen); - } - - buf.printf("$(DDOC_COMMENT Generated by Ddoc from %s)\n", srcfile->toChars()); -@@ -297,7 +305,7 @@ void Module::gendocfile() - } - - //printf("BODY= '%.*s'\n", buf.offset, buf.data); -- Macro::define(¯otable, (unsigned char *)"BODY", 4, buf.data, buf.offset); -+ Macro::define(¯otable, (utf8_t *)"BODY", 4, buf.data, buf.offset); - - OutBuffer buf2; - buf2.writestring("$(DDOC)\n"); -@@ -311,10 +319,10 @@ void Module::gendocfile() - { - buf.setsize(0); - buf.reserve(buf2.offset); -- unsigned char *p = buf2.data; -+ utf8_t *p = buf2.data; - for (size_t j = 0; j < buf2.offset; j++) - { -- unsigned char c = p[j]; -+ utf8_t c = p[j]; - if (c == 0xFF && j + 1 < buf2.offset) - { - j++; -@@ -339,13 +347,13 @@ void Module::gendocfile() - assert(docfile); - docfile->setbuffer(buf.data, buf.offset); - docfile->ref = 1; -- FileName::ensurePathToNameExists(docfile->toChars()); -- docfile->writev(); -+ ensurePathToNameExists(Loc(), docfile->toChars()); -+ writeFile(loc, docfile); - #else - /* Remove all the escape sequences from buf2 - */ - { size_t i = 0; -- unsigned char *p = buf2.data; -+ utf8_t *p = buf2.data; - for (size_t j = 0; j < buf2.offset; j++) - { - if (p[j] == 0xFF && j + 1 < buf2.offset) -@@ -362,8 +370,8 @@ void Module::gendocfile() - // Transfer image to file - docfile->setbuffer(buf2.data, buf2.offset); - docfile->ref = 1; -- FileName::ensurePathToNameExists(docfile->toChars()); -- docfile->writev(); -+ ensurePathToNameExists(Loc(), docfile->toChars()); -+ writeFile(loc, docfile); - #endif - } - -@@ -378,7 +386,7 @@ void escapeDdocString(OutBuffer *buf, si - { - for (size_t u = start; u < buf->offset; u++) - { -- unsigned char c = buf->data[u]; -+ utf8_t c = buf->data[u]; - switch(c) - { - case '$': -@@ -408,13 +416,20 @@ void escapeDdocString(OutBuffer *buf, si - - * Fix by replacing unmatched ( with $(LPAREN) and unmatched ) with $(RPAREN). - */ --void escapeStrayParenthesis(OutBuffer *buf, size_t start, Loc loc) -+void escapeStrayParenthesis(OutBuffer *buf, size_t start, Dsymbol *s) - { - unsigned par_open = 0; -+ Loc loc = s->loc; -+ -+ if (Module *m = s->isModule()) -+ { -+ if (m->md) -+ loc = m->md->loc; -+ } - - for (size_t u = start; u < buf->offset; u++) - { -- unsigned char c = buf->data[u]; -+ utf8_t c = buf->data[u]; - switch(c) - { - case '(': -@@ -449,7 +464,7 @@ void escapeStrayParenthesis(OutBuffer *b - { par_open = 0; - for (size_t u = buf->offset; u > start;) - { u--; -- unsigned char c = buf->data[u]; -+ utf8_t c = buf->data[u]; - switch(c) - { - case ')': -@@ -473,8 +488,93 @@ void escapeStrayParenthesis(OutBuffer *b - } - } - -+static bool emitAnchorName(OutBuffer *buf, Dsymbol *s) -+{ -+ if (!s || s->isPackage() || s->isModule()) -+ return false; -+ -+ TemplateDeclaration *td; -+ bool dot; -+ -+ // Add parent names first -+ dot = emitAnchorName(buf, s->parent); -+ // Eponymous template members can share the parent anchor name -+ if (s->parent && (td = s->parent->isTemplateDeclaration()) != NULL && -+ td->onemember == s) -+ return dot; -+ if (dot) -+ buf->writeByte('.'); -+ // Use "this" not "__ctor" -+ if (s->isCtorDeclaration() || ((td = s->isTemplateDeclaration()) != NULL && -+ td->onemember && td->onemember->isCtorDeclaration())) -+ buf->writestring("this"); -+ else -+ { -+ /* We just want the identifier, not overloads like TemplateDeclaration::toChars. -+ * We don't want the template parameter list and constraints. */ -+ buf->writestring(s->Dsymbol::toChars()); -+ } -+ -+ return true; -+} -+ -+static void emitAnchor(OutBuffer *buf, Dsymbol *s) -+{ -+ buf->writestring("$(DDOC_ANCHOR "); -+ emitAnchorName(buf, s); -+ buf->writeByte(')'); -+} -+ - /******************************* emitComment **********************************/ - -+/** Get leading indentation from 'src' which represents lines of code. */ -+static size_t getCodeIndent(const char *src) -+{ -+ while (src && *src == '\n') -+ ++src; // skip until we find the first non-empty line -+ -+ size_t codeIndent = 0; -+ while (src && (*src == ' ' || *src == '\t')) -+ { -+ codeIndent++; -+ src++; -+ } -+ return codeIndent; -+} -+ -+void emitUnittestComment(Scope *sc, Dsymbol *s, size_t ofs) -+{ -+ OutBuffer *buf = sc->docbuf; -+ -+ for (UnitTestDeclaration *utd = s->ddocUnittest; utd; utd = utd->ddocUnittest) -+ { -+ if (utd->protection == PROTprivate || !utd->comment || !utd->fbody) -+ continue; -+ -+ // Strip whitespaces to avoid showing empty summary -+ utf8_t *c = utd->comment; -+ while (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r') ++c; -+ -+ OutBuffer codebuf; -+ codebuf.writestring("$(DDOC_EXAMPLES \n"); -+ size_t o = codebuf.offset; -+ codebuf.writestring((char *)c); -+ -+ if (utd->codedoc) -+ { -+ size_t i = getCodeIndent(utd->codedoc); -+ while (i--) codebuf.writeByte(' '); -+ codebuf.writestring("----\n"); -+ codebuf.writestring(utd->codedoc); -+ codebuf.writestring("----\n"); -+ highlightText(sc, s, &codebuf, o); -+ } -+ -+ codebuf.writestring(")"); -+ buf->insert(buf->offset - ofs, codebuf.data, codebuf.offset); -+ } -+} -+ - /* - * Emit doc comment to documentation file - */ -@@ -505,34 +605,12 @@ void Dsymbol::emitDitto(Scope *sc) - buf->spread(sc->lastoffset, b.offset); - memcpy(buf->data + sc->lastoffset, b.data, b.offset); - sc->lastoffset += b.offset; --} -- --void emitUnittestComment(Scope *sc, Dsymbol *s, UnitTestDeclaration *test) --{ -- static char pre[] = "$(D_CODE \n"; -- OutBuffer *buf = sc->docbuf; -- -- buf->writestring("$(DDOC_SECTION "); -- buf->writestring("$(B Example:)"); -- for (UnitTestDeclaration *utd = test; utd; utd = utd->unittest) -- { -- if (utd->protection == PROTprivate || !utd->comment || !utd->fbody) -- continue; -- -- OutBuffer codebuf; -- const char *body = utd->fbody->toChars(); -- if (strlen(body)) -- { -- codebuf.writestring(pre); -- codebuf.writestring(body); -- codebuf.writestring(")"); -- codebuf.writeByte(0); -- highlightCode2(sc, s, &codebuf, 0); -- buf->writestring(codebuf.toChars()); -- } -- } - -- buf->writestring(")"); -+ Dsymbol *s = this; -+ if (!s->ddocUnittest && parent) -+ s = parent->isTemplateDeclaration(); -+ if (s) -+ emitUnittestComment(sc, s, strlen(ddoc_decl_dd_e)); - } - - void ScopeDsymbol::emitMemberComments(Scope *sc) -@@ -586,6 +664,7 @@ void emitProtection(OutBuffer *buf, PROT - - void Dsymbol::emitComment(Scope *sc) { } - void InvariantDeclaration::emitComment(Scope *sc) { } -+void UnitTestDeclaration::emitComment(Scope *sc) { } - #if DMDV2 - void PostBlitDeclaration::emitComment(Scope *sc) { } - #endif -@@ -593,7 +672,6 @@ void DtorDeclaration::emitComment(Scope - void StaticCtorDeclaration::emitComment(Scope *sc) { } - void StaticDtorDeclaration::emitComment(Scope *sc) { } - void ClassInfoDeclaration::emitComment(Scope *sc) { } --void ModuleInfoDeclaration::emitComment(Scope *sc) { } - void TypeInfoDeclaration::emitComment(Scope *sc) { } - - -@@ -650,8 +728,10 @@ void AggregateDeclaration::emitComment(S - dc->pmacrotable = &sc->module->macrotable; - - buf->writestring(ddoc_decl_s); -- toDocBuffer(buf, sc); -- sc->lastoffset = buf->offset; -+ size_t o = buf->offset; -+ toDocBuffer(buf, sc); -+ highlightCode(sc, this, buf, o); -+ sc->lastoffset = buf->offset; - buf->writestring(ddoc_decl_e); - - buf->writestring(ddoc_decl_dd_s); -@@ -666,7 +746,7 @@ void TemplateDeclaration::emitComment(Sc - if (prot() == PROTprivate) - return; - -- unsigned char *com = comment; -+ utf8_t *com = comment; - int hasmembers = 1; - - Dsymbol *ss = this; -@@ -747,7 +827,9 @@ void EnumDeclaration::emitComment(Scope - dc->pmacrotable = &sc->module->macrotable; - - buf->writestring(ddoc_decl_s); -+ size_t o = buf->offset; - toDocBuffer(buf, sc); -+ highlightCode(sc, this, buf, o); - sc->lastoffset = buf->offset; - buf->writestring(ddoc_decl_e); - -@@ -767,7 +849,6 @@ void EnumMember::emitComment(Scope *sc) - - OutBuffer *buf = sc->docbuf; - DocComment *dc = DocComment::parse(sc, this, comment); -- size_t o; - - if (!dc) - { -@@ -777,7 +858,7 @@ void EnumMember::emitComment(Scope *sc) - dc->pmacrotable = &sc->module->macrotable; - - buf->writestring(ddoc_decl_s); -- o = buf->offset; -+ size_t o = buf->offset; - toDocBuffer(buf, sc); - highlightCode(sc, this, buf, o); - sc->lastoffset = buf->offset; -@@ -788,42 +869,6 @@ void EnumMember::emitComment(Scope *sc) - buf->writestring(ddoc_decl_dd_e); - } - --static bool emitAnchorName(OutBuffer *buf, Dsymbol *s) --{ -- if (!s || s->isPackage() || s->isModule()) -- return false; -- -- TemplateDeclaration *td; -- bool dot; -- -- // Add parent names first -- dot = emitAnchorName(buf, s->parent); -- // Eponymous template members can share the parent anchor name -- if (s->parent && (td = s->parent->isTemplateDeclaration()) != NULL && -- td->onemember == s) -- return dot; -- if (dot) -- buf->writeByte('.'); -- // Use "this" not "__ctor" -- if (s->isCtorDeclaration() || ((td = s->isTemplateDeclaration()) != NULL && -- td->onemember && td->onemember->isCtorDeclaration())) -- buf->writestring("this"); -- else -- { -- /* We just want the identifier, not overloads like TemplateDeclaration::toChars. -- * We don't want the template parameter list and constraints. */ -- buf->writestring(s->Dsymbol::toChars()); -- } -- return true; --} -- --static void emitAnchor(OutBuffer *buf, Dsymbol *s) --{ -- buf->writestring("$(DDOC_ANCHOR "); -- emitAnchorName(buf, s); -- buf->writeByte(')'); --} -- - /******************************* toDocBuffer **********************************/ - - void Dsymbol::toDocBuffer(OutBuffer *buf, Scope *sc) -@@ -851,14 +896,17 @@ void prefix(OutBuffer *buf, Dsymbol *s) - else if (d->isAbstract()) - buf->writestring("abstract "); - -- if (d->isConst()) -- buf->writestring("const "); --#if DMDV2 -- if (d->isImmutable()) -- buf->writestring("immutable "); --#endif -- if (d->isSynchronized()) -- buf->writestring("synchronized "); -+ if (!d->isFuncDeclaration()) // toCBufferWithAttributes handles this -+ { -+ if (d->isConst()) -+ buf->writestring("const "); -+ #if DMDV2 -+ if (d->isImmutable()) -+ buf->writestring("immutable "); -+ #endif -+ if (d->isSynchronized()) -+ buf->writestring("synchronized "); -+ } - } - } - -@@ -867,6 +915,9 @@ void declarationToDocBuffer(Declaration - //printf("declarationToDocBuffer() %s, originalType = %s, td = %s\n", decl->toChars(), decl->originalType ? decl->originalType->toChars() : "--", td ? td->toChars() : "--"); - if (decl->ident) - { -+ if (decl->isDeprecated()) -+ buf->writestring("$(DEPRECATED "); -+ - prefix(buf, decl); - - if (decl->type) -@@ -883,6 +934,20 @@ void declarationToDocBuffer(Declaration - } - else - buf->writestring(decl->ident->toChars()); -+ -+ // emit constraints if declaration is a templated declaration -+ if (td && td->constraint) -+ { -+ HdrGenState hgs; -+ hgs.ddoc = 1; -+ buf->writestring(" if ("); -+ td->constraint->toCBuffer(buf, &hgs); -+ buf->writeByte(')'); -+ } -+ -+ if (decl->isDeprecated()) -+ buf->writestring(")"); -+ - buf->writestring(";\n"); - } - } -@@ -901,7 +966,7 @@ void AliasDeclaration::toDocBuffer(OutBu - buf->writestring("deprecated "); - - emitProtection(buf, protection); -- buf->writestring("alias "); -+ buf->printf("alias %s = ", toChars()); - - if (Dsymbol *s = aliassym) // ident alias - { -@@ -923,8 +988,6 @@ void AliasDeclaration::toDocBuffer(OutBu - } - } - -- buf->writestring(" "); -- buf->writestring(toChars()); - buf->writestring(";\n"); - } - } -@@ -1033,11 +1096,10 @@ void AggregateDeclaration::toDocBuffer(O - { - if (ident) - { -- emitAnchor(buf, this); - #if 0 - emitProtection(buf, protection); - #endif -- buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); -+ buf->printf("%s %s", kind(), toChars()); - buf->writestring(";\n"); - } - } -@@ -1061,8 +1123,7 @@ void StructDeclaration::toDocBuffer(OutB - } - else - { -- emitAnchor(buf, this); -- buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); -+ buf->printf("%s %s", kind(), toChars()); - } - buf->writestring(";\n"); - } -@@ -1087,10 +1148,9 @@ void ClassDeclaration::toDocBuffer(OutBu - } - else - { -- emitAnchor(buf, this); -- if (isAbstract()) -+ if (!isInterfaceDeclaration() && isAbstract()) - buf->writestring("abstract "); -- buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); -+ buf->printf("%s %s", kind(), toChars()); - } - int any = 0; - for (size_t i = 0; i < baseclasses->dim; i++) -@@ -1127,8 +1187,14 @@ void EnumDeclaration::toDocBuffer(OutBuf - { - if (ident) - { -- emitAnchor(buf, this); -- buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); -+ buf->printf("%s %s", kind(), toChars()); -+ if (memtype) -+ { -+ buf->writestring(": $(DDOC_ENUM_BASETYPE "); -+ HdrGenState *hgs = NULL; -+ memtype->toCBuffer(buf, NULL, hgs); -+ buf->writestring(")"); -+ } - buf->writestring(";\n"); - } - } -@@ -1144,7 +1210,7 @@ void EnumMember::toDocBuffer(OutBuffer * - - /********************************* DocComment *********************************/ - --DocComment *DocComment::parse(Scope *sc, Dsymbol *s, unsigned char *comment) -+DocComment *DocComment::parse(Scope *sc, Dsymbol *s, utf8_t *comment) - { - //printf("parse(%s): '%s'\n", s->toChars(), comment); - if (sc->lastdc && isDitto(comment)) -@@ -1181,20 +1247,21 @@ DocComment *DocComment::parse(Scope *sc, - * then (*pcomment)[0 .. idlen] is the identifier. - */ - --void DocComment::parseSections(unsigned char *comment) --{ unsigned char *p; -- unsigned char *pstart; -- unsigned char *pend; -- unsigned char *idstart; -+void DocComment::parseSections(utf8_t *comment) -+{ utf8_t *p; -+ utf8_t *pstart; -+ utf8_t *pend; -+ utf8_t *idstart; - size_t idlen; - -- unsigned char *name = NULL; -+ utf8_t *name = NULL; - size_t namelen = 0; - - //printf("parseSections('%s')\n", comment); - p = comment; - while (*p) - { -+ utf8_t *pstart0 = p; - p = skipwhitespace(p); - pstart = p; - pend = p; -@@ -1210,6 +1277,11 @@ void DocComment::parseSections(unsigned - // Check for start/end of a code section - if (*p == '-') - { -+ if (!inCode) -+ { // restore leading indentation -+ while (pstart0 < pstart && isIndentWS(pstart-1)) --pstart; -+ } -+ - int numdash = 0; - while (*p == '-') - { -@@ -1224,7 +1296,7 @@ void DocComment::parseSections(unsigned - - if (!inCode && isIdStart(p)) - { -- unsigned char *q = p + utfStride(p); -+ utf8_t *q = p + utfStride(p); - while (isIdTail(q)) - q += utfStride(q); - if (*q == ':') // identifier: ends it -@@ -1298,7 +1370,7 @@ void DocComment::parseSections(unsigned - void DocComment::writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf) - { - //printf("DocComment::writeSections()\n"); -- if (sections.dim) -+ if (sections.dim || s->ddocUnittest) - { - buf->writestring("$(DDOC_SECTIONS \n"); - for (size_t i = 0; i < sections.dim; i++) -@@ -1314,13 +1386,13 @@ void DocComment::writeSections(Scope *sc - buf->writestring("$(DDOC_SUMMARY "); - size_t o = buf->offset; - buf->write(sec->body, sec->bodylen); -- escapeStrayParenthesis(buf, o, s->loc); -+ escapeStrayParenthesis(buf, o, s); - highlightText(sc, s, buf, o); - buf->writestring(")\n"); - } - } -- if (s->unittest) -- emitUnittestComment(sc, s, s->unittest); -+ if (s->ddocUnittest) -+ emitUnittestComment(sc, s, 0); - buf->writestring(")\n"); - } - else -@@ -1356,10 +1428,10 @@ void Section::write(DocComment *dc, Scop - buf->writestring("$(DDOC_SECTION_H "); - size_t o = buf->offset; - for (size_t u = 0; u < namelen; u++) -- { unsigned char c = name[u]; -+ { utf8_t c = name[u]; - buf->writeByte((c == '_') ? ' ' : c); - } -- escapeStrayParenthesis(buf, o, s->loc); -+ escapeStrayParenthesis(buf, o, s); - buf->writestring(":)\n"); - } - else -@@ -1369,7 +1441,7 @@ void Section::write(DocComment *dc, Scop - L1: - size_t o = buf->offset; - buf->write(body, bodylen); -- escapeStrayParenthesis(buf, o, s->loc); -+ escapeStrayParenthesis(buf, o, s); - highlightText(sc, s, buf, o); - buf->writestring(")\n"); - } -@@ -1379,20 +1451,20 @@ void Section::write(DocComment *dc, Scop - - void ParamSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf) - { -- unsigned char *p = body; -+ utf8_t *p = body; - size_t len = bodylen; -- unsigned char *pend = p + len; -+ utf8_t *pend = p + len; - -- unsigned char *tempstart; -+ utf8_t *tempstart; - size_t templen; - -- unsigned char *namestart; -+ utf8_t *namestart; - size_t namelen = 0; // !=0 if line continuation - -- unsigned char *textstart; -+ utf8_t *textstart; - size_t textlen; - -- size_t o; -+ size_t o, paramcount = 0; - Parameter *arg; - - buf->writestring("$(DDOC_PARAMS \n"); -@@ -1442,23 +1514,37 @@ void ParamSection::write(DocComment *dc, - - L1: - //printf("param '%.*s' = '%.*s'\n", namelen, namestart, textlen, textstart); -+ ++paramcount; - HdrGenState hgs; - buf->writestring("$(DDOC_PARAM_ROW "); - buf->writestring("$(DDOC_PARAM_ID "); - o = buf->offset; - arg = isFunctionParameter(s, namestart, namelen); - if (arg && arg->type && arg->ident) -+ { - arg->type->toCBuffer(buf, arg->ident, &hgs); -+ } - else -+ { -+ if (isTemplateParameter(s, namestart, namelen)) -+ { -+ // 10236: Don't count template parameters for params check -+ --paramcount; -+ } -+ else if (!arg) -+ { -+ warning(s->loc, "Ddoc: function declaration has no parameter '%.*s'", namelen, namestart); -+ } - buf->write(namestart, namelen); -- escapeStrayParenthesis(buf, o, s->loc); -+ } -+ escapeStrayParenthesis(buf, o, s); - highlightCode(sc, s, buf, o, false); - buf->writestring(")\n"); - - buf->writestring("$(DDOC_PARAM_DESC "); - o = buf->offset; - buf->write(textstart, textlen); -- escapeStrayParenthesis(buf, o, s->loc); -+ escapeStrayParenthesis(buf, o, s); - highlightText(sc, s, buf, o); - buf->writestring(")"); - buf->writestring(")\n"); -@@ -1491,6 +1577,16 @@ void ParamSection::write(DocComment *dc, - if (namelen) - goto L1; // write out last one - buf->writestring(")\n"); -+ -+ TypeFunction *tf = isTypeFunction(s); -+ if (tf) -+ { -+ size_t pcount = tf->parameters ? tf->parameters->dim : 0; -+ if (pcount != paramcount) -+ { -+ warning(s->loc, "Ddoc: parameter count mismatch"); -+ } -+ } - } - - /*************************************************** -@@ -1510,19 +1606,19 @@ void MacroSection::write(DocComment *dc, - * name2 = value2 - */ - --void DocComment::parseMacros(Escape **pescapetable, Macro **pmacrotable, unsigned char *m, size_t mlen) -+void DocComment::parseMacros(Escape **pescapetable, Macro **pmacrotable, utf8_t *m, size_t mlen) - { -- unsigned char *p = m; -+ utf8_t *p = m; - size_t len = mlen; -- unsigned char *pend = p + len; -+ utf8_t *pend = p + len; - -- unsigned char *tempstart; -+ utf8_t *tempstart; - size_t templen; - -- unsigned char *namestart; -+ utf8_t *namestart; - size_t namelen = 0; // !=0 if line continuation - -- unsigned char *textstart; -+ utf8_t *textstart; - size_t textlen; - - while (p < pend) -@@ -1635,7 +1731,7 @@ Ldone: - * by whitespace and/or commas. - */ - --void DocComment::parseEscapes(Escape **pescapetable, unsigned char *textstart, size_t textlen) -+void DocComment::parseEscapes(Escape **pescapetable, utf8_t *textstart, size_t textlen) - { Escape *escapetable = *pescapetable; - - if (!escapetable) -@@ -1644,8 +1740,8 @@ void DocComment::parseEscapes(Escape **p - *pescapetable = escapetable; - } - //printf("parseEscapes('%.*s') pescapetable = %p\n", textlen, textstart, pescapetable); -- unsigned char *p = textstart; -- unsigned char *pend = p + textlen; -+ utf8_t *p = textstart; -+ utf8_t *pend = p + textlen; - - while (1) - { -@@ -1659,9 +1755,9 @@ void DocComment::parseEscapes(Escape **p - } - if (p[0] != '/' || p[2] != '/') - return; -- unsigned char c = p[1]; -+ utf8_t c = p[1]; - p += 3; -- unsigned char *start = p; -+ utf8_t *start = p; - while (1) - { - if (p >= pend) -@@ -1707,11 +1803,11 @@ int icmp(const char *stringz, void *s, s - * Return !=0 if comment consists entirely of "ditto". - */ - --int isDitto(unsigned char *comment) -+int isDitto(utf8_t *comment) - { - if (comment) - { -- unsigned char *p = skipwhitespace(comment); -+ utf8_t *p = skipwhitespace(comment); - - if (Port::memicmp((char *)p, "ditto", 5) == 0 && *skipwhitespace(p + 5) == 0) - return 1; -@@ -1723,7 +1819,7 @@ int isDitto(unsigned char *comment) - * Skip white space. - */ - --unsigned char *skipwhitespace(unsigned char *p) -+utf8_t *skipwhitespace(utf8_t *p) - { - for (; 1; p++) - { switch (*p) -@@ -1752,7 +1848,7 @@ size_t skiptoident(OutBuffer *buf, size_ - { dchar_t c; - - size_t oi = i; -- if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c)) -+ if (utf_decodeChar((utf8_t *)buf->data, buf->offset, &i, &c)) - /* Ignore UTF errors, but still consume input - */ - break; -@@ -1779,7 +1875,7 @@ size_t skippastident(OutBuffer *buf, siz - { dchar_t c; - - size_t oi = i; -- if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c)) -+ if (utf_decodeChar((utf8_t *)buf->data, buf->offset, &i, &c)) - /* Ignore UTF errors, but still consume input - */ - break; -@@ -1807,7 +1903,7 @@ size_t skippastident(OutBuffer *buf, siz - - size_t skippastURL(OutBuffer *buf, size_t i) - { size_t length = buf->offset - i; -- unsigned char *p = &buf->data[i]; -+ utf8_t *p = &buf->data[i]; - size_t j; - unsigned sawdot = 0; - -@@ -1823,7 +1919,7 @@ size_t skippastURL(OutBuffer *buf, size_ - goto Lno; - - for (; j < length; j++) -- { unsigned char c = p[j]; -+ { utf8_t c = p[j]; - if (isalnum(c)) - continue; - if (c == '-' || c == '_' || c == '?' || -@@ -1849,7 +1945,7 @@ Lno: - /**************************************************** - */ - --int isKeyword(unsigned char *p, size_t len) -+int isKeyword(utf8_t *p, size_t len) - { - static const char *table[] = { "true", "false", "null" }; - -@@ -1864,10 +1960,17 @@ int isKeyword(unsigned char *p, size_t l - /**************************************************** - */ - --Parameter *isFunctionParameter(Dsymbol *s, unsigned char *p, size_t len) -+TypeFunction *isTypeFunction(Dsymbol *s) - { - FuncDeclaration *f = s->isFuncDeclaration(); - -+ /* Check whether s refers to an eponymous function template. -+ */ -+ if (f == NULL && s->isTemplateDeclaration() && s->isTemplateDeclaration()->onemember) -+ { -+ f = s->isTemplateDeclaration()->onemember->isFuncDeclaration(); -+ } -+ - /* f->type may be NULL for template members. - */ - if (f && f->type) -@@ -1880,15 +1983,45 @@ Parameter *isFunctionParameter(Dsymbol * - else - tf = (TypeFunction *)f->type; - -- if (tf->parameters) -+ return tf; -+ } -+ return NULL; -+} -+ -+/**************************************************** -+ */ -+ -+Parameter *isFunctionParameter(Dsymbol *s, utf8_t *p, size_t len) -+{ -+ TypeFunction *tf = isTypeFunction(s); -+ if (tf && tf->parameters) -+ { -+ for (size_t k = 0; k < tf->parameters->dim; k++) - { -- for (size_t k = 0; k < tf->parameters->dim; k++) -- { Parameter *arg = (*tf->parameters)[k]; -+ Parameter *arg = (*tf->parameters)[k]; -+ if (arg->ident && cmp(arg->ident->toChars(), p, len) == 0) -+ { -+ return arg; -+ } -+ } -+ } -+ return NULL; -+} - -- if (arg->ident && cmp(arg->ident->toChars(), p, len) == 0) -- { -- return arg; -- } -+/**************************************************** -+ */ -+ -+TemplateParameter *isTemplateParameter(Dsymbol *s, utf8_t *p, size_t len) -+{ -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (td && td->origParameters) -+ { -+ for (size_t k = 0; k < td->origParameters->dim; k++) -+ { -+ TemplateParameter *arg = (*td->origParameters)[k]; -+ if (arg->ident && cmp(arg->ident->toChars(), p, len) == 0) -+ { -+ return arg; - } - } - } -@@ -1904,18 +2037,19 @@ void highlightText(Scope *sc, Dsymbol *s - //printf("highlightText()\n"); - const char *sid = s->ident->toChars(); - FuncDeclaration *f = s->isFuncDeclaration(); -- unsigned char *p; -+ utf8_t *p; - const char *se; - - int leadingBlank = 1; - int inCode = 0; - //int inComment = 0; // in comment - size_t iCodeStart; // start of code section -+ size_t codeIndent = 0; - - size_t iLineStart = offset; - - for (size_t i = offset; i < buf->offset; i++) -- { unsigned char c = buf->data[i]; -+ { utf8_t c = buf->data[i]; - - Lcont: - switch (c) -@@ -1930,7 +2064,7 @@ void highlightText(Scope *sc, Dsymbol *s - { - static char blankline[] = "$(DDOC_BLANKLINE)\n"; - -- i = buf->insert(i, blankline, sizeof(blankline) - 1); -+ i = buf->insert(i, blankline, strlen(blankline)); - } - leadingBlank = 1; - iLineStart = i + 1; -@@ -2083,6 +2217,30 @@ void highlightText(Scope *sc, Dsymbol *s - - codebuf.write(buf->data + iCodeStart, i - iCodeStart); - codebuf.writeByte(0); -+ -+ // Remove leading indentations from all lines -+ bool lineStart = true; -+ utf8_t *endp = codebuf.data + codebuf.offset; -+ for (utf8_t *p = codebuf.data; p < endp; ) -+ { -+ if (lineStart) -+ { -+ size_t j = codeIndent; -+ utf8_t *q = p; -+ while (j-- > 0 && q < endp && isIndentWS(q)) -+ ++q; -+ codebuf.remove(p - codebuf.data, q - p); -+ assert(codebuf.data <= p); -+ assert(p < codebuf.data + codebuf.offset); -+ lineStart = false; -+ endp = codebuf.data + codebuf.offset; // update -+ continue; -+ } -+ if (*p == '\n') -+ lineStart = true; -+ ++p; -+ } -+ - highlightCode2(sc, s, &codebuf, 0); - buf->remove(iCodeStart, i - iCodeStart); - i = buf->insert(iCodeStart, codebuf.data, codebuf.offset); -@@ -2093,7 +2251,8 @@ void highlightText(Scope *sc, Dsymbol *s - { static char pre[] = "$(D_CODE \n"; - - inCode = 1; -- i = buf->insert(i, pre, sizeof(pre) - 1); -+ codeIndent = istart - iLineStart; // save indent count -+ i = buf->insert(i, pre, strlen(pre)); - iCodeStart = i; - i--; // place i on > - leadingBlank = true; -@@ -2172,7 +2331,7 @@ void highlightCode(Scope *sc, Dsymbol *s - - //printf("highlightCode(s = '%s', kind = %s)\n", sid, s->kind()); - for (size_t i = offset; i < buf->offset; i++) -- { unsigned char c = buf->data[i]; -+ { utf8_t c = buf->data[i]; - const char *se; - - se = sc->module->escapetable->escapeChar(c); -@@ -2211,7 +2370,7 @@ void highlightCode(Scope *sc, Dsymbol *s - /**************************************** - */ - --void highlightCode3(Scope *sc, OutBuffer *buf, unsigned char *p, unsigned char *pend) -+void highlightCode3(Scope *sc, OutBuffer *buf, utf8_t *p, utf8_t *pend) - { - for (; p < pend; p++) - { const char *s = sc->module->escapetable->escapeChar(*p); -@@ -2229,15 +2388,18 @@ void highlightCode3(Scope *sc, OutBuffer - - void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset) - { -- char *sid = s->ident->toChars(); -+ const char *sid = s->ident->toChars(); - FuncDeclaration *f = s->isFuncDeclaration(); - unsigned errorsave = global.errors; - Lexer lex(NULL, buf->data, 0, buf->offset - 1, 0, 1); - Token tok; - OutBuffer res; -- unsigned char *lastp = buf->data; -+ utf8_t *lastp = buf->data; - const char *highlight; - -+ if (s->isModule() && ((Module *)s)->isDocFile) -+ sid = ""; -+ - //printf("highlightCode2('%.*s')\n", buf->offset - 1, buf->data); - res.reserve(buf->offset); - while (1) -@@ -2280,10 +2442,16 @@ void highlightCode2(Scope *sc, Dsymbol * - break; - } - if (highlight) -+ { - res.writestring(highlight); -- highlightCode3(sc, &res, tok.ptr, lex.p); -- if (highlight) -+ size_t o = res.offset; -+ highlightCode3(sc, &res, tok.ptr, lex.p); -+ if (tok.value == TOKcomment || tok.value == TOKstring) -+ escapeDdocString(&res, o); // Bugzilla 7656, 7715, and 10519 - res.writeByte(')'); -+ } -+ else -+ highlightCode3(sc, &res, tok.ptr, lex.p); - if (tok.value == TOKeof) - break; - lastp = lex.p; -@@ -2328,7 +2496,7 @@ const char *Escape::escapeChar(unsigned - * Determine if p points to the start of an identifier. - */ - --int isIdStart(unsigned char *p) -+int isIdStart(utf8_t *p) - { - unsigned c = *p; - if (isalpha(c) || c == '_') -@@ -2347,7 +2515,7 @@ int isIdStart(unsigned char *p) - * Determine if p points to the rest of an identifier. - */ - --int isIdTail(unsigned char *p) -+int isIdTail(utf8_t *p) - { - unsigned c = *p; - if (isalnum(c) || c == '_') -@@ -2362,11 +2530,20 @@ int isIdTail(unsigned char *p) - return 0; - } - -+/**************************************** -+ * Determine if p points to the indentation space. -+ */ -+ -+int isIndentWS(utf8_t *p) -+{ -+ return (*p == ' ') || (*p == '\t'); -+} -+ - /***************************************** - * Return number of bytes in UTF character. - */ - --int utfStride(unsigned char *p) -+int utfStride(utf8_t *p) - { - unsigned c = *p; - if (c < 0x80) ---- a/src/gcc/d/dfrontend/dsymbol.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/dsymbol.c 2014-04-01 16:32:51.000000000 +0100 -@@ -45,12 +45,14 @@ Dsymbol::Dsymbol() - this->parent = NULL; - this->csym = NULL; - this->isym = NULL; -- this->loc = 0; -+ this->loc = Loc(); - this->comment = NULL; - this->scope = NULL; -+ this->semanticRun = PASSinit; - this->errors = false; -+ this->depmsg = NULL; - this->userAttributes = NULL; -- this->unittest = NULL; -+ this->ddocUnittest = NULL; - } - - Dsymbol::Dsymbol(Identifier *ident) -@@ -60,25 +62,25 @@ Dsymbol::Dsymbol(Identifier *ident) - this->parent = NULL; - this->csym = NULL; - this->isym = NULL; -- this->loc = 0; -+ this->loc = Loc(); - this->comment = NULL; - this->scope = NULL; -+ this->semanticRun = PASSinit; - this->errors = false; - this->depmsg = NULL; - this->userAttributes = NULL; -- this->unittest = NULL; -+ this->ddocUnittest = NULL; - } - --int Dsymbol::equals(Object *o) --{ Dsymbol *s; -- -+bool Dsymbol::equals(RootObject *o) -+{ - if (this == o) -- return TRUE; -- s = (Dsymbol *)(o); -+ return true; -+ Dsymbol *s = (Dsymbol *)(o); - // Overload sets don't have an ident - if (s && ident && s->ident && ident->equals(s->ident)) -- return TRUE; -- return FALSE; -+ return true; -+ return false; - } - - /************************************** -@@ -98,23 +100,23 @@ Dsymbol *Dsymbol::syntaxCopy(Dsymbol *s) - /************************************** - * Determine if this symbol is only one. - * Returns: -- * FALSE, *ps = NULL: There are 2 or more symbols -- * TRUE, *ps = NULL: There are zero symbols -- * TRUE, *ps = symbol: The one and only one symbol -+ * false, *ps = NULL: There are 2 or more symbols -+ * true, *ps = NULL: There are zero symbols -+ * true, *ps = symbol: The one and only one symbol - */ - --int Dsymbol::oneMember(Dsymbol **ps, Identifier *ident) -+bool Dsymbol::oneMember(Dsymbol **ps, Identifier *ident) - { - //printf("Dsymbol::oneMember()\n"); - *ps = this; -- return TRUE; -+ return true; - } - - /***************************************** - * Same as Dsymbol::oneMember(), but look at an array of Dsymbols. - */ - --int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident) -+bool Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident) - { - //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); - Dsymbol *s = NULL; -@@ -124,46 +126,61 @@ int Dsymbol::oneMembers(Dsymbols *member - for (size_t i = 0; i < members->dim; i++) - { Dsymbol *sx = (*members)[i]; - -- int x = sx->oneMember(ps, ident); -+ bool x = sx->oneMember(ps, ident); - //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); - if (!x) - { - //printf("\tfalse 1\n"); - assert(*ps == NULL); -- return FALSE; -+ return false; - } - if (*ps) - { -- if (ident) -- { -- if (!(*ps)->ident || !(*ps)->ident->equals(ident)) -- continue; -- } -+ assert(ident); -+ if (!(*ps)->ident || !(*ps)->ident->equals(ident)) -+ continue; - if (!s) - s = *ps; - else if (s->isOverloadable() && (*ps)->isOverloadable()) -- ; // keep head of overload set -+ { -+ // keep head of overload set -+ FuncDeclaration *f1 = s->isFuncDeclaration(); -+ FuncDeclaration *f2 = (*ps)->isFuncDeclaration(); -+ if (f1 && f2) -+ { -+ assert(!f1->isFuncAliasDeclaration()); -+ assert(!f2->isFuncAliasDeclaration()); -+ for (; f1 != f2; f1 = f1->overnext0) -+ { -+ if (f1->overnext0 == NULL) -+ { -+ f1->overnext0 = f2; -+ break; -+ } -+ } -+ } -+ } - else // more than one symbol - { *ps = NULL; - //printf("\tfalse 2\n"); -- return FALSE; -+ return false; - } - } - } - } - *ps = s; // s is the one symbol, NULL if none - //printf("\ttrue\n"); -- return TRUE; -+ return true; - } - - /***************************************** - * Is Dsymbol a variable that contains pointers? - */ - --int Dsymbol::hasPointers() -+bool Dsymbol::hasPointers() - { - //printf("Dsymbol::hasPointers() %s\n", toChars()); -- return 0; -+ return false; - } - - bool Dsymbol::hasStaticCtorOrDtor() -@@ -176,6 +193,11 @@ void Dsymbol::setFieldOffset(AggregateDe - { - } - -+Identifier *Dsymbol::getIdent() -+{ -+ return ident; -+} -+ - char *Dsymbol::toChars() - { - return ident ? ident->toChars() : (char *)"__anonymous"; -@@ -301,9 +323,9 @@ TemplateInstance *Dsymbol::isSpeculative - return NULL; - } - --int Dsymbol::isAnonymous() -+bool Dsymbol::isAnonymous() - { -- return ident ? 0 : 1; -+ return ident == NULL; - } - - /************************************* -@@ -329,10 +351,6 @@ void Dsymbol::importAll(Scope *sc) - * Does semantic analysis on the public face of declarations. - */ - --void Dsymbol::semantic0(Scope *sc) --{ --} -- - void Dsymbol::semantic(Scope *sc) - { - error("%p has no semantic routine", this); -@@ -400,8 +418,7 @@ void *symbol_search_fp(void *arg, const - assert(id); - - Dsymbol *s = (Dsymbol *)arg; -- Module::clearCache(); -- return s->search(0, id, 4|2); -+ return (void *)s->search(Loc(), id, 4|2); - } - - Dsymbol *Dsymbol::search_correct(Identifier *ident) -@@ -409,7 +426,7 @@ Dsymbol *Dsymbol::search_correct(Identif - if (global.gag) - return NULL; // don't do it for speculative compiles; too time consuming - -- return (Dsymbol *)speller(ident->toChars(), &symbol_search_fp, this, idchars); -+ return (Dsymbol *)speller(ident->toChars(), &symbol_search_fp, (void *)this, idchars); - } - - /*************************************** -@@ -419,7 +436,7 @@ Dsymbol *Dsymbol::search_correct(Identif - * symbol found, NULL if not - */ - --Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, Identifier *id) -+Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, RootObject *id) - { - //printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident->toChars()); - Dsymbol *s = toAlias(); -@@ -428,7 +445,7 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope - switch (id->dyncast()) - { - case DYNCAST_IDENTIFIER: -- sm = s->search(loc, id, 0); -+ sm = s->search(loc, (Identifier *)id, 0); - break; - - case DYNCAST_DSYMBOL: -@@ -436,7 +453,7 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope - //printf("\ttemplate instance id\n"); - Dsymbol *st = (Dsymbol *)id; - TemplateInstance *ti = st->isTemplateInstance(); -- id = ti->name; -+ Identifier *id = ti->name; - sm = s->search(loc, id, 0); - if (!sm) - { -@@ -469,10 +486,10 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope - return sm; - } - --int Dsymbol::overloadInsert(Dsymbol *s) -+bool Dsymbol::overloadInsert(Dsymbol *s) - { - //printf("Dsymbol::overloadInsert('%s')\n", s->toChars()); -- return FALSE; -+ return false; - } - - void Dsymbol::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -486,9 +503,9 @@ unsigned Dsymbol::size(Loc loc) - return 0; - } - --int Dsymbol::isforwardRef() -+bool Dsymbol::isforwardRef() - { -- return FALSE; -+ return false; - } - - AggregateDeclaration *Dsymbol::isThis() -@@ -523,30 +540,30 @@ void Dsymbol::defineRef(Dsymbol *s) - assert(0); - } - --int Dsymbol::isExport() -+bool Dsymbol::isExport() - { -- return FALSE; -+ return false; - } - --int Dsymbol::isImportedSymbol() -+bool Dsymbol::isImportedSymbol() - { -- return FALSE; -+ return false; - } - --int Dsymbol::isDeprecated() -+bool Dsymbol::isDeprecated() - { -- return FALSE; -+ return false; - } - - #if DMDV2 --int Dsymbol::isOverloadable() -+bool Dsymbol::isOverloadable() - { -- return 0; -+ return false; - } - --int Dsymbol::hasOverloads() -+bool Dsymbol::hasOverloads() - { -- return 0; -+ return false; - } - #endif - -@@ -568,9 +585,9 @@ Type *Dsymbol::getType() - return NULL; - } - --int Dsymbol::needThis() -+bool Dsymbol::needThis() - { -- return FALSE; -+ return false; - } - - int Dsymbol::apply(Dsymbol_apply_ft_t fp, void *param) -@@ -593,7 +610,7 @@ int Dsymbol::addMember(Scope *sc, ScopeD - s2 = sd->symtab->lookup(ident); - if (!s2->overloadInsert(this)) - { -- sd->multiplyDefined(0, this, s2); -+ sd->multiplyDefined(Loc(), this, s2); - } - } - if (sd->isAggregateDeclaration() || sd->isEnumDeclaration()) -@@ -728,7 +745,7 @@ Module *Dsymbol::getAccessModule() - if (m) - return m; - TemplateInstance *ti = s->isTemplateInstance(); -- if (ti && ti->isnested) -+ if (ti && ti->enclosing) - /* Because of local template instantiation, the parent isn't where the access - * rights come from - it's the template declaration - */ -@@ -742,7 +759,7 @@ Module *Dsymbol::getAccessModule() - /************************************* - */ - --enum PROT Dsymbol::prot() -+PROT Dsymbol::prot() - { - return PROTpublic; - } -@@ -776,7 +793,7 @@ Dsymbols *Dsymbol::arraySyntaxCopy(Dsymb - * Ignore NULL comments. - */ - --void Dsymbol::addComment(unsigned char *comment) -+void Dsymbol::addComment(utf8_t *comment) - { - //if (comment) - //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); -@@ -794,8 +811,8 @@ void Dsymbol::addComment(unsigned char * - /********************************* OverloadSet ****************************/ - - #if DMDV2 --OverloadSet::OverloadSet() -- : Dsymbol() -+OverloadSet::OverloadSet(Identifier *ident) -+ : Dsymbol(ident) - { - } - -@@ -844,35 +861,44 @@ Dsymbol *ScopeDsymbol::syntaxCopy(Dsymbo - return sd; - } - -+/***************************************** -+ * This function is #1 on the list of functions that eat cpu time. -+ * Be very, very careful about slowing it down. -+ */ -+ - Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) - { - //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); - //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; - - // Look in symbols declared in this module -- Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; -- //printf("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0); -- if (s) -+ Dsymbol *s1 = symtab ? symtab->lookup(ident) : NULL; -+ //printf("\ts1 = %p, imports = %p, %d\n", s1, imports, imports ? imports->dim : 0); -+ if (s1) - { -- //printf("\ts = '%s.%s'\n",toChars(),s->toChars()); -+ //printf("\ts = '%s.%s'\n",toChars(),s1->toChars()); -+ return s1; - } -- else if (imports) -+ else if (!imports) -+ return NULL; -+ else - { -+ Dsymbol *s = NULL; - OverloadSet *a = NULL; - - // Look in imported modules - for (size_t i = 0; i < imports->dim; i++) -- { Dsymbol *ss = (*imports)[i]; -- Dsymbol *s2; -- -+ { - // If private import, don't search it - if (flags & 1 && prots[i] == PROTprivate) - continue; - -+ Dsymbol *ss = (*imports)[i]; -+ - //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport()); - /* Don't find private members if ss is a module - */ -- s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); -+ Dsymbol *s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); - if (!s) - s = s2; - else if (s2 && s != s2) -@@ -904,12 +930,23 @@ Dsymbol *ScopeDsymbol::search(Loc loc, I - ) - ) - { -+ /* Bugzilla 8668: -+ * Public selective import adds AliasDeclaration in module. -+ * To make an overload set, resolve aliases in here and -+ * get actual overload roots which accessible via s and s2. -+ */ -+ s = s->toAlias(); -+ s2 = s2->toAlias(); -+ - /* If both s2 and s are overloadable (though we only - * need to check s once) - */ - if (s2->isOverloadable() && (a || s->isOverloadable())) - { if (!a) -- a = new OverloadSet(); -+ { -+ a = new OverloadSet(s->ident); -+ a->parent = this; -+ } - /* Don't add to a[] if s2 is alias of previous sym - */ - for (size_t j = 0; j < a->a.dim; j++) -@@ -946,33 +983,17 @@ Dsymbol *ScopeDsymbol::search(Loc loc, I - - if (s) - { -- if (!(flags & 2)) -- { Declaration *d = s->isDeclaration(); -- if (d && d->protection == PROTprivate && -- !d->parent->isTemplateMixin()) -- error(loc, "%s is private", d->toPrettyChars()); -- -- AggregateDeclaration *ad = s->isAggregateDeclaration(); -- if (ad && ad->protection == PROTprivate && -- !ad->parent->isTemplateMixin()) -- error(loc, "%s is private", ad->toPrettyChars()); -- -- EnumDeclaration *ed = s->isEnumDeclaration(); -- if (ed && ed->protection == PROTprivate && -- !ed->parent->isTemplateMixin()) -- error(loc, "%s is private", ed->toPrettyChars()); -- -- TemplateDeclaration *td = s->isTemplateDeclaration(); -- if (td && td->protection == PROTprivate && -- !td->parent->isTemplateMixin()) -- error(loc, "%s is private", td->toPrettyChars()); -+ if (!(flags & 2) && s->prot() == PROTprivate && !s->parent->isTemplateMixin()) -+ { -+ if (!s->isImport()) -+ error(loc, "%s %s is private", s->kind(), s->toPrettyChars()); - } - } -+ return s; - } -- return s; - } - --void ScopeDsymbol::importScope(Dsymbol *s, enum PROT protection) -+void ScopeDsymbol::importScope(Dsymbol *s, PROT protection) - { - //printf("%s->ScopeDsymbol::importScope(%s, %d)\n", toChars(), s->toChars(), protection); - -@@ -999,7 +1020,7 @@ void ScopeDsymbol::importScope(Dsymbol * - } - } - --int ScopeDsymbol::isforwardRef() -+bool ScopeDsymbol::isforwardRef() - { - return (members == NULL); - } -@@ -1054,7 +1075,7 @@ Dsymbol *ScopeDsymbol::nameCollision(Dsy - return sprev; - } - } -- multiplyDefined(0, s, sprev); -+ multiplyDefined(Loc(), s, sprev); - return sprev; - } - -@@ -1205,7 +1226,7 @@ FuncDeclaration *ScopeDsymbol::findGetMe - - Type *tret = NULL; - tfgetmembers = new TypeFunction(arguments, tret, 0, LINKd); -- tfgetmembers = (TypeFunction *)tfgetmembers->semantic(0, &sc); -+ tfgetmembers = (TypeFunction *)tfgetmembers->semantic(Loc(), &sc); - } - if (fdx) - fdx = fdx->overloadExactMatch(tfgetmembers); -@@ -1229,7 +1250,24 @@ WithScopeSymbol::WithScopeSymbol(WithSta - Dsymbol *WithScopeSymbol::search(Loc loc, Identifier *ident, int flags) - { - // Acts as proxy to the with class declaration -- return withstate->exp->type->toDsymbol(NULL)->search(loc, ident, 0); -+ Dsymbol *s = NULL; -+ Expression *eold = NULL; -+ for (Expression *e = withstate->exp; e != eold; e = resolveAliasThis(scope, e)) -+ { -+ Type *t = e->type->toBasetype(); -+ if (t->ty == Taarray) -+ s = ((TypeAArray *)t)->getImpl(); -+ else -+ s = t->toDsymbol(NULL); -+ if (s) -+ { -+ s = s->search(loc, ident, 0); -+ if (s) -+ return s; -+ } -+ eold = e; -+ } -+ return NULL; - } - - /****************************** ArrayScopeSymbol ******************************/ -@@ -1275,8 +1313,8 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - { /* $ gives the number of elements in the tuple - */ - VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); -- Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); -- v->init = new ExpInitializer(0, e); -+ Expression *e = new IntegerExp(Loc(), td->objects->dim, Type::tsize_t); -+ v->init = new ExpInitializer(Loc(), e); - v->storage_class |= STCstatic | STCconst; - v->semantic(sc); - return v; -@@ -1286,8 +1324,8 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - { /* $ gives the number of type entries in the type tuple - */ - VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); -- Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); -- v->init = new ExpInitializer(0, e); -+ Expression *e = new IntegerExp(Loc(), type->arguments->dim, Type::tsize_t); -+ v->init = new ExpInitializer(Loc(), e); - v->storage_class |= STCstatic | STCconst; - v->semantic(sc); - return v; -@@ -1351,8 +1389,8 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - { /* It is for an expression tuple, so the - * length will be a const. - */ -- Expression *e = new IntegerExp(0, ((TupleExp *)ce)->exps->dim, Type::tsize_t); -- v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, new ExpInitializer(0, e)); -+ Expression *e = new IntegerExp(Loc(), ((TupleExp *)ce)->exps->dim, Type::tsize_t); -+ v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, new ExpInitializer(Loc(), e)); - v->storage_class |= STCstatic | STCconst; - } - else if (ce->type && (t = ce->type->toBasetype()) != NULL && -@@ -1376,29 +1414,6 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - return NULL; - s = s->toAlias(); - -- if (ce->hasSideEffect()) -- { -- /* Even if opDollar is needed, 'ce' should be evaluate only once. So -- * Rewrite: -- * ce.opIndex( ... use of $ ... ) -- * ce.opSlice( ... use of $ ... ) -- * as: -- * (ref __dop = ce, __dop).opIndex( ... __dop.opDollar ...) -- * (ref __dop = ce, __dop).opSlice( ... __dop.opDollar ...) -- */ -- Identifier *id = Lexer::uniqueId("__dop"); -- ExpInitializer *ei = new ExpInitializer(loc, ce); -- VarDeclaration *v = new VarDeclaration(loc, NULL, id, ei); -- v->storage_class |= STCctfe | STCforeach | STCref; -- DeclarationExp *de = new DeclarationExp(loc, v); -- VarExp *ve = new VarExp(loc, v); -- v->semantic(sc); -- de->type = ce->type; -- ve->type = ce->type; -- ((UnaExp *)exp)->e1 = new CommaExp(loc, de, ve); -- ce = ve; -- } -- - Expression *e = NULL; - // Check for multi-dimensional opDollar(dim) template. - if (TemplateDeclaration *td = s->isTemplateDeclaration()) -@@ -1414,7 +1429,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - } - - Objects *tdargs = new Objects(); -- Expression *edim = new IntegerExp(0, dim, Type::tsize_t); -+ Expression *edim = new IntegerExp(Loc(), dim, Type::tsize_t); - edim = edim->semantic(sc); - tdargs->push(edim); - -@@ -1444,7 +1459,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - t = e->type->toBasetype(); - if (t && t->ty == Tfunction) - e = new CallExp(e->loc, e); -- v = new VarDeclaration(loc, NULL, Id::dollar, new ExpInitializer(0, e)); -+ v = new VarDeclaration(loc, NULL, Id::dollar, new ExpInitializer(Loc(), e)); - } - else - { /* For arrays, $ will either be a compile-time constant -@@ -1452,7 +1467,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - * or a variable (in which case an expression is created in - * toir.c). - */ -- VoidInitializer *e = new VoidInitializer(0); -+ VoidInitializer *e = new VoidInitializer(Loc()); - e->type = Type::tsize_t; - v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, e); - v->storage_class |= STCctfe; // it's never a true static variable -@@ -1470,90 +1485,42 @@ Dsymbol *ArrayScopeSymbol::search(Loc lo - - DsymbolTable::DsymbolTable() - { --#if STRINGTABLE -- tab = new StringTable; -- tab->init(); --#else - tab = NULL; --#endif --} -- --DsymbolTable::~DsymbolTable() --{ --#if STRINGTABLE -- delete tab; --#endif - } - - Dsymbol *DsymbolTable::lookup(Identifier *ident) - { --#if STRINGTABLE --#ifdef DEBUG -- assert(ident); -- assert(tab); --#endif -- //printf("DsymbolTable::lookup(%s)\n", (char*)ident->string); -- StringValue *sv = tab->lookup((char*)ident->string, ident->len); -- return (Dsymbol *)(sv ? sv->ptrvalue : NULL); --#else - //printf("DsymbolTable::lookup(%s)\n", (char*)ident->string); - return (Dsymbol *)_aaGetRvalue(tab, ident); --#endif - } - - Dsymbol *DsymbolTable::insert(Dsymbol *s) - { - //printf("DsymbolTable::insert(this = %p, '%s')\n", this, s->ident->toChars()); - Identifier *ident = s->ident; --#if STRINGTABLE --#ifdef DEBUG -- assert(ident); -- assert(tab); --#endif -- StringValue *sv = tab->insert(ident->toChars(), ident->len); -- if (!sv) -- return NULL; // already in table -- sv->ptrvalue = s; -- return s; --#else - Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident); - if (*ps) - return NULL; // already in table - *ps = s; - return s; --#endif - } - - Dsymbol *DsymbolTable::insert(Identifier *ident, Dsymbol *s) - { - //printf("DsymbolTable::insert()\n"); --#if STRINGTABLE -- StringValue *sv = tab->insert(ident->toChars(), ident->len); -- if (!sv) -- return NULL; // already in table -- sv->ptrvalue = s; -- return s; --#else - Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident); - if (*ps) - return NULL; // already in table - *ps = s; - return s; --#endif - } - - Dsymbol *DsymbolTable::update(Dsymbol *s) - { - Identifier *ident = s->ident; --#if STRINGTABLE -- StringValue *sv = tab->update(ident->toChars(), ident->len); -- sv->ptrvalue = s; -- return s; --#else - Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident); - *ps = s; - return s; --#endif - } - - ---- a/src/gcc/d/dfrontend/dsymbol.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/dsymbol.h 2014-04-01 16:32:51.000000000 +0100 -@@ -21,56 +21,56 @@ - #include "mars.h" - #include "arraytypes.h" - --struct Identifier; -+class Identifier; - struct Scope; --struct DsymbolTable; --struct Declaration; --struct ThisDeclaration; --struct TupleDeclaration; --struct TypedefDeclaration; --struct AliasDeclaration; --struct AggregateDeclaration; --struct EnumDeclaration; --struct ClassDeclaration; --struct InterfaceDeclaration; --struct StructDeclaration; --struct UnionDeclaration; --struct FuncDeclaration; --struct FuncAliasDeclaration; --struct FuncLiteralDeclaration; --struct CtorDeclaration; --struct PostBlitDeclaration; --struct DtorDeclaration; --struct StaticCtorDeclaration; --struct StaticDtorDeclaration; --struct SharedStaticCtorDeclaration; --struct SharedStaticDtorDeclaration; --struct InvariantDeclaration; --struct UnitTestDeclaration; --struct NewDeclaration; --struct VarDeclaration; --struct AttribDeclaration; -+class DsymbolTable; -+class Declaration; -+class ThisDeclaration; -+class TypeInfoDeclaration; -+class TupleDeclaration; -+class TypedefDeclaration; -+class AliasDeclaration; -+class AggregateDeclaration; -+class EnumDeclaration; -+class ClassDeclaration; -+class InterfaceDeclaration; -+class StructDeclaration; -+class UnionDeclaration; -+class FuncDeclaration; -+class FuncAliasDeclaration; -+class FuncLiteralDeclaration; -+class CtorDeclaration; -+class PostBlitDeclaration; -+class DtorDeclaration; -+class StaticCtorDeclaration; -+class StaticDtorDeclaration; -+class SharedStaticCtorDeclaration; -+class SharedStaticDtorDeclaration; -+class InvariantDeclaration; -+class UnitTestDeclaration; -+class NewDeclaration; -+class VarDeclaration; -+class AttribDeclaration; - struct Symbol; --struct Package; --struct Module; --struct Import; --struct Type; --struct TypeTuple; --struct WithStatement; --struct LabelDsymbol; --struct ScopeDsymbol; --struct TemplateDeclaration; --struct TemplateInstance; --struct TemplateMixin; --struct EnumMember; --struct ScopeDsymbol; --struct WithScopeSymbol; --struct ArrayScopeSymbol; --struct SymbolDeclaration; --struct Expression; --struct DeleteDeclaration; -+class Package; -+class Module; -+class Import; -+class Type; -+class TypeTuple; -+class WithStatement; -+class LabelDsymbol; -+class ScopeDsymbol; -+class TemplateDeclaration; -+class TemplateInstance; -+class TemplateMixin; -+class EnumMember; -+class WithScopeSymbol; -+class ArrayScopeSymbol; -+class SymbolDeclaration; -+class Expression; -+class DeleteDeclaration; - struct HdrGenState; --struct OverloadSet; -+class OverloadSet; - struct AA; - struct JsonOut; - #ifdef IN_GCC -@@ -103,35 +103,40 @@ enum PASS - PASSinit, // initial state - PASSsemantic, // semantic() started - PASSsemanticdone, // semantic() done -- PASSsemantic2, // semantic2() run -+ PASSsemantic2, // semantic2() started -+ PASSsemantic2done, // semantic2() done - PASSsemantic3, // semantic3() started - PASSsemantic3done, // semantic3() done -+ PASSinline, // inline started -+ PASSinlinedone, // inline done - PASSobj, // toObjFile() run - }; - - typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *); - --struct Dsymbol : Object -+class Dsymbol : public RootObject - { -+public: - Identifier *ident; - Dsymbol *parent; - Symbol *csym; // symbol for code generator - Symbol *isym; // import version of csym -- unsigned char *comment; // documentation comment for this Dsymbol -+ utf8_t *comment; // documentation comment for this Dsymbol - Loc loc; // where defined - Scope *scope; // !=NULL means context to use for semantic() - bool errors; // this symbol failed to pass semantic() -+ PASS semanticRun; - char *depmsg; // customized deprecation message - Expressions *userAttributes; // user defined attributes from UserAttributeDeclaration -- UnitTestDeclaration *unittest; // !=NULL means there's a unittest associated with this symbol -+ UnitTestDeclaration *ddocUnittest; // !=NULL means there's a ddoc unittest associated with this symbol (only use this with ddoc) - - Dsymbol(); - Dsymbol(Identifier *); - char *toChars(); - Loc& getLoc(); - char *locToChars(); -- int equals(Object *o); -- int isAnonymous(); -+ bool equals(RootObject *o); -+ bool isAnonymous(); - void error(Loc loc, const char *format, ...); - void error(const char *format, ...); - void deprecation(Loc loc, const char *format, ...); -@@ -144,11 +149,13 @@ struct Dsymbol : Object - Dsymbol *toParent2(); - TemplateInstance *inTemplateInstance(); - TemplateInstance *isSpeculative(); -+ Ungag ungagSpeculative(); - - int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol() - - static Dsymbols *arraySyntaxCopy(Dsymbols *a); - -+ virtual Identifier *getIdent(); - virtual const char *toPrettyChars(); - virtual const char *kind(); - virtual Dsymbol *toAlias(); // resolve real symbol -@@ -156,51 +163,49 @@ struct Dsymbol : Object - virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum); - virtual void setScope(Scope *sc); - virtual void importAll(Scope *sc); -- virtual void semantic0(Scope *sc); - virtual void semantic(Scope *sc); - virtual void semantic2(Scope *sc); - virtual void semantic3(Scope *sc); - virtual void inlineScan(); - virtual Dsymbol *search(Loc loc, Identifier *ident, int flags); - Dsymbol *search_correct(Identifier *id); -- Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id); -- virtual int overloadInsert(Dsymbol *s); -- char *toHChars(); -+ Dsymbol *searchX(Loc loc, Scope *sc, RootObject *id); -+ virtual bool overloadInsert(Dsymbol *s); - virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs); - virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - virtual void toDocBuffer(OutBuffer *buf, Scope *sc); - virtual void toJson(JsonOut *json); - virtual void jsonProperties(JsonOut *json); - virtual unsigned size(Loc loc); -- virtual int isforwardRef(); -+ virtual bool isforwardRef(); - virtual void defineRef(Dsymbol *s); - virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member - AggregateDeclaration *isAggregateMember(); // are we a member of an aggregate? - AggregateDeclaration *isAggregateMember2(); // are we a member of an aggregate? - ClassDeclaration *isClassMember(); // are we a member of a class? -- virtual int isExport(); // is Dsymbol exported? -- virtual int isImportedSymbol(); // is Dsymbol imported? -- virtual int isDeprecated(); // is Dsymbol deprecated? -+ virtual bool isExport(); // is Dsymbol exported? -+ virtual bool isImportedSymbol(); // is Dsymbol imported? -+ virtual bool isDeprecated(); // is Dsymbol deprecated? - #if DMDV2 -- virtual int isOverloadable(); -- virtual int hasOverloads(); -+ virtual bool isOverloadable(); -+ virtual bool hasOverloads(); - #endif - virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol? - virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration? - virtual Type *getType(); // is this a type? -- virtual char *mangle(bool isv = false); -- virtual int needThis(); // need a 'this' pointer? -- virtual enum PROT prot(); -+ virtual const char *mangle(bool isv = false); -+ virtual bool needThis(); // need a 'this' pointer? -+ virtual PROT prot(); - virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees -- virtual int oneMember(Dsymbol **ps, Identifier *ident); -- static int oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident = NULL); -+ virtual bool oneMember(Dsymbol **ps, Identifier *ident); -+ static bool oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident); - virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); -- virtual int hasPointers(); -+ virtual bool hasPointers(); - virtual bool hasStaticCtorOrDtor(); - virtual void addLocalClass(ClassDeclarations *) { } - virtual void checkCtorConstInit() { } - -- virtual void addComment(unsigned char *comment); -+ virtual void addComment(utf8_t *comment); - virtual void emitComment(Scope *sc); - void emitDitto(Scope *sc); - -@@ -224,6 +229,7 @@ struct Dsymbol : Object - virtual TemplateMixin *isTemplateMixin() { return NULL; } - virtual Declaration *isDeclaration() { return NULL; } - virtual ThisDeclaration *isThisDeclaration() { return NULL; } -+ virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; } - virtual TupleDeclaration *isTupleDeclaration() { return NULL; } - virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; } - virtual AliasDeclaration *isAliasDeclaration() { return NULL; } -@@ -259,8 +265,9 @@ struct Dsymbol : Object - - // Dsymbol that generates a scope - --struct ScopeDsymbol : Dsymbol -+class ScopeDsymbol : public Dsymbol - { -+public: - Dsymbols *members; // all Dsymbol's in this scope - DsymbolTable *symtab; // members[] sorted into table - -@@ -271,8 +278,8 @@ struct ScopeDsymbol : Dsymbol - ScopeDsymbol(Identifier *id); - Dsymbol *syntaxCopy(Dsymbol *s); - Dsymbol *search(Loc loc, Identifier *ident, int flags); -- void importScope(Dsymbol *s, enum PROT protection); -- int isforwardRef(); -+ void importScope(Dsymbol *s, PROT protection); -+ bool isforwardRef(); - void defineRef(Dsymbol *s); - static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2); - Dsymbol *nameCollision(Dsymbol *s); -@@ -294,8 +301,9 @@ struct ScopeDsymbol : Dsymbol - - // With statement scope - --struct WithScopeSymbol : ScopeDsymbol -+class WithScopeSymbol : public ScopeDsymbol - { -+public: - WithStatement *withstate; - - WithScopeSymbol(WithStatement *withstate); -@@ -306,8 +314,9 @@ struct WithScopeSymbol : ScopeDsymbol - - // Array Index/Slice scope - --struct ArrayScopeSymbol : ScopeDsymbol -+class ArrayScopeSymbol : public ScopeDsymbol - { -+public: - Expression *exp; // IndexExp or SliceExp - TypeTuple *type; // for tuple[length] - TupleDeclaration *td; // for tuples of objects -@@ -324,11 +333,12 @@ struct ArrayScopeSymbol : ScopeDsymbol - // Overload Sets - - #if DMDV2 --struct OverloadSet : Dsymbol -+class OverloadSet : public Dsymbol - { -+public: - Dsymbols a; // array of Dsymbols - -- OverloadSet(); -+ OverloadSet(Identifier *ident); - void push(Dsymbol *s); - OverloadSet *isOverloadSet() { return this; } - const char *kind(); -@@ -337,12 +347,12 @@ struct OverloadSet : Dsymbol - - // Table of Dsymbol's - --struct DsymbolTable : Object -+class DsymbolTable : public RootObject - { -+public: - AA *tab; - - DsymbolTable(); -- ~DsymbolTable(); - - // Look up Identifier. Return Dsymbol if found, NULL if not. - Dsymbol *lookup(Identifier *ident); ---- a/src/gcc/d/dfrontend/entity.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/entity.c 2014-04-01 16:32:51.000000000 +0100 -@@ -11,6 +11,8 @@ - #include - #include - -+#include "port.h" -+ - /********************************************* - * Convert from named entity to its encoding. - * For reference: -@@ -25,2344 +27,2344 @@ struct NameId - }; - - static NameId namesA[]={ -- "Aacgr", 0x00386, // GREEK CAPITAL LETTER ALPHA WITH TONOS -- "aacgr", 0x003AC, // GREEK SMALL LETTER ALPHA WITH TONOS -- "Aacute", 0x000C1, // LATIN CAPITAL LETTER A WITH ACUTE -- "aacute", 0x000E1, // LATIN SMALL LETTER A WITH ACUTE -- "Abreve", 0x00102, // LATIN CAPITAL LETTER A WITH BREVE -- "abreve", 0x00103, // LATIN SMALL LETTER A WITH BREVE -- "ac", 0x0223E, // INVERTED LAZY S -- "acd", 0x0223F, // SINE WAVE --// "acE", 0x0223E;0x00333, // INVERTED LAZY S with double underline -- "Acirc", 0x000C2, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX -- "acirc", 0x000E2, // LATIN SMALL LETTER A WITH CIRCUMFLEX -- "acute", 0x000B4, // ACUTE ACCENT -- "Acy", 0x00410, // CYRILLIC CAPITAL LETTER A -- "acy", 0x00430, // CYRILLIC SMALL LETTER A -- "AElig", 0x000C6, // LATIN CAPITAL LETTER AE -- "aelig", 0x000E6, // LATIN SMALL LETTER AE -- "af", 0x02061, // FUNCTION APPLICATION -- "Afr", 0x1D504, // MATHEMATICAL FRAKTUR CAPITAL A -- "afr", 0x1D51E, // MATHEMATICAL FRAKTUR SMALL A -- "Agr", 0x00391, // GREEK CAPITAL LETTER ALPHA -- "agr", 0x003B1, // GREEK SMALL LETTER ALPHA -- "Agrave", 0x000C0, // LATIN CAPITAL LETTER A WITH GRAVE -- "agrave", 0x000E0, // LATIN SMALL LETTER A WITH GRAVE -- "alefsym", 0x02135, // ALEF SYMBOL -- "aleph", 0x02135, // ALEF SYMBOL -- "Alpha", 0x00391, // GREEK CAPITAL LETTER ALPHA -- "alpha", 0x003B1, // GREEK SMALL LETTER ALPHA -- "Amacr", 0x00100, // LATIN CAPITAL LETTER A WITH MACRON -- "amacr", 0x00101, // LATIN SMALL LETTER A WITH MACRON -- "amalg", 0x02A3F, // AMALGAMATION OR COPRODUCT -- "amp", 0x00026, // AMPERSAND -- "AMP", 0x00026, // AMPERSAND -- "and", 0x02227, // LOGICAL AND -- "And", 0x02A53, // DOUBLE LOGICAL AND -- "andand", 0x02A55, // TWO INTERSECTING LOGICAL AND -- "andd", 0x02A5C, // LOGICAL AND WITH HORIZONTAL DASH -- "andslope", 0x02A58, // SLOPING LARGE AND -- "andv", 0x02A5A, // LOGICAL AND WITH MIDDLE STEM -- "ang", 0x02220, // ANGLE -- "ange", 0x029A4, // ANGLE WITH UNDERBAR -- "angle", 0x02220, // ANGLE -- "angmsd", 0x02221, // MEASURED ANGLE -- "angmsdaa", 0x029A8, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT -- "angmsdab", 0x029A9, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT -- "angmsdac", 0x029AA, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT -- "angmsdad", 0x029AB, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT -- "angmsdae", 0x029AC, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP -- "angmsdaf", 0x029AD, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP -- "angmsdag", 0x029AE, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN -- "angmsdah", 0x029AF, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN -- "angrt", 0x0221F, // RIGHT ANGLE -- "angrtvb", 0x022BE, // RIGHT ANGLE WITH ARC -- "angrtvbd", 0x0299D, // MEASURED RIGHT ANGLE WITH DOT -- "angsph", 0x02222, // SPHERICAL ANGLE -- "angst", 0x000C5, // LATIN CAPITAL LETTER A WITH RING ABOVE -- "angzarr", 0x0237C, // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW -- "Aogon", 0x00104, // LATIN CAPITAL LETTER A WITH OGONEK -- "aogon", 0x00105, // LATIN SMALL LETTER A WITH OGONEK -- "Aopf", 0x1D538, // MATHEMATICAL DOUBLE-STRUCK CAPITAL A -- "aopf", 0x1D552, // MATHEMATICAL DOUBLE-STRUCK SMALL A -- "ap", 0x02248, // ALMOST EQUAL TO -- "apacir", 0x02A6F, // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT -- "ape", 0x0224A, // ALMOST EQUAL OR EQUAL TO -- "apE", 0x02A70, // APPROXIMATELY EQUAL OR EQUAL TO -- "apid", 0x0224B, // TRIPLE TILDE -- "apos", 0x00027, // APOSTROPHE -- "ApplyFunction", 0x02061, // FUNCTION APPLICATION -- "approx", 0x02248, // ALMOST EQUAL TO -- "approxeq", 0x0224A, // ALMOST EQUAL OR EQUAL TO -- "Aring", 0x000C5, // LATIN CAPITAL LETTER A WITH RING ABOVE -- "aring", 0x000E5, // LATIN SMALL LETTER A WITH RING ABOVE -- "Ascr", 0x1D49C, // MATHEMATICAL SCRIPT CAPITAL A -- "ascr", 0x1D4B6, // MATHEMATICAL SCRIPT SMALL A -- "Assign", 0x02254, // COLON EQUALS -- "ast", 0x0002A, // ASTERISK -- "asymp", 0x02248, // ALMOST EQUAL TO -- "asympeq", 0x0224D, // EQUIVALENT TO -- "Atilde", 0x000C3, // LATIN CAPITAL LETTER A WITH TILDE -- "atilde", 0x000E3, // LATIN SMALL LETTER A WITH TILDE -- "Auml", 0x000C4, // LATIN CAPITAL LETTER A WITH DIAERESIS -- "auml", 0x000E4, // LATIN SMALL LETTER A WITH DIAERESIS -- "awconint", 0x02233, // ANTICLOCKWISE CONTOUR INTEGRAL -- "awint", 0x02A11, // ANTICLOCKWISE INTEGRATION -- NULL, 0 -+ {"Aacgr", 0x00386}, // GREEK CAPITAL LETTER ALPHA WITH TONOS -+ {"aacgr", 0x003AC}, // GREEK SMALL LETTER ALPHA WITH TONOS -+ {"Aacute", 0x000C1}, // LATIN CAPITAL LETTER A WITH ACUTE -+ {"aacute", 0x000E1}, // LATIN SMALL LETTER A WITH ACUTE -+ {"Abreve", 0x00102}, // LATIN CAPITAL LETTER A WITH BREVE -+ {"abreve", 0x00103}, // LATIN SMALL LETTER A WITH BREVE -+ {"ac", 0x0223E}, // INVERTED LAZY S -+ {"acd", 0x0223F}, // SINE WAVE -+// {"acE", 0x0223E;0x00333}, // INVERTED LAZY S with double underline -+ {"Acirc", 0x000C2}, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX -+ {"acirc", 0x000E2}, // LATIN SMALL LETTER A WITH CIRCUMFLEX -+ {"acute", 0x000B4}, // ACUTE ACCENT -+ {"Acy", 0x00410}, // CYRILLIC CAPITAL LETTER A -+ {"acy", 0x00430}, // CYRILLIC SMALL LETTER A -+ {"AElig", 0x000C6}, // LATIN CAPITAL LETTER AE -+ {"aelig", 0x000E6}, // LATIN SMALL LETTER AE -+ {"af", 0x02061}, // FUNCTION APPLICATION -+ {"Afr", 0x1D504}, // MATHEMATICAL FRAKTUR CAPITAL A -+ {"afr", 0x1D51E}, // MATHEMATICAL FRAKTUR SMALL A -+ {"Agr", 0x00391}, // GREEK CAPITAL LETTER ALPHA -+ {"agr", 0x003B1}, // GREEK SMALL LETTER ALPHA -+ {"Agrave", 0x000C0}, // LATIN CAPITAL LETTER A WITH GRAVE -+ {"agrave", 0x000E0}, // LATIN SMALL LETTER A WITH GRAVE -+ {"alefsym", 0x02135}, // ALEF SYMBOL -+ {"aleph", 0x02135}, // ALEF SYMBOL -+ {"Alpha", 0x00391}, // GREEK CAPITAL LETTER ALPHA -+ {"alpha", 0x003B1}, // GREEK SMALL LETTER ALPHA -+ {"Amacr", 0x00100}, // LATIN CAPITAL LETTER A WITH MACRON -+ {"amacr", 0x00101}, // LATIN SMALL LETTER A WITH MACRON -+ {"amalg", 0x02A3F}, // AMALGAMATION OR COPRODUCT -+ {"amp", 0x00026}, // AMPERSAND -+ {"AMP", 0x00026}, // AMPERSAND -+ {"and", 0x02227}, // LOGICAL AND -+ {"And", 0x02A53}, // DOUBLE LOGICAL AND -+ {"andand", 0x02A55}, // TWO INTERSECTING LOGICAL AND -+ {"andd", 0x02A5C}, // LOGICAL AND WITH HORIZONTAL DASH -+ {"andslope", 0x02A58}, // SLOPING LARGE AND -+ {"andv", 0x02A5A}, // LOGICAL AND WITH MIDDLE STEM -+ {"ang", 0x02220}, // ANGLE -+ {"ange", 0x029A4}, // ANGLE WITH UNDERBAR -+ {"angle", 0x02220}, // ANGLE -+ {"angmsd", 0x02221}, // MEASURED ANGLE -+ {"angmsdaa", 0x029A8}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT -+ {"angmsdab", 0x029A9}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT -+ {"angmsdac", 0x029AA}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT -+ {"angmsdad", 0x029AB}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT -+ {"angmsdae", 0x029AC}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP -+ {"angmsdaf", 0x029AD}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP -+ {"angmsdag", 0x029AE}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN -+ {"angmsdah", 0x029AF}, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN -+ {"angrt", 0x0221F}, // RIGHT ANGLE -+ {"angrtvb", 0x022BE}, // RIGHT ANGLE WITH ARC -+ {"angrtvbd", 0x0299D}, // MEASURED RIGHT ANGLE WITH DOT -+ {"angsph", 0x02222}, // SPHERICAL ANGLE -+ {"angst", 0x000C5}, // LATIN CAPITAL LETTER A WITH RING ABOVE -+ {"angzarr", 0x0237C}, // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW -+ {"Aogon", 0x00104}, // LATIN CAPITAL LETTER A WITH OGONEK -+ {"aogon", 0x00105}, // LATIN SMALL LETTER A WITH OGONEK -+ {"Aopf", 0x1D538}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL A -+ {"aopf", 0x1D552}, // MATHEMATICAL DOUBLE-STRUCK SMALL A -+ {"ap", 0x02248}, // ALMOST EQUAL TO -+ {"apacir", 0x02A6F}, // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT -+ {"ape", 0x0224A}, // ALMOST EQUAL OR EQUAL TO -+ {"apE", 0x02A70}, // APPROXIMATELY EQUAL OR EQUAL TO -+ {"apid", 0x0224B}, // TRIPLE TILDE -+ {"apos", 0x00027}, // APOSTROPHE -+ {"ApplyFunction", 0x02061}, // FUNCTION APPLICATION -+ {"approx", 0x02248}, // ALMOST EQUAL TO -+ {"approxeq", 0x0224A}, // ALMOST EQUAL OR EQUAL TO -+ {"Aring", 0x000C5}, // LATIN CAPITAL LETTER A WITH RING ABOVE -+ {"aring", 0x000E5}, // LATIN SMALL LETTER A WITH RING ABOVE -+ {"Ascr", 0x1D49C}, // MATHEMATICAL SCRIPT CAPITAL A -+ {"ascr", 0x1D4B6}, // MATHEMATICAL SCRIPT SMALL A -+ {"Assign", 0x02254}, // COLON EQUALS -+ {"ast", 0x0002A}, // ASTERISK -+ {"asymp", 0x02248}, // ALMOST EQUAL TO -+ {"asympeq", 0x0224D}, // EQUIVALENT TO -+ {"Atilde", 0x000C3}, // LATIN CAPITAL LETTER A WITH TILDE -+ {"atilde", 0x000E3}, // LATIN SMALL LETTER A WITH TILDE -+ {"Auml", 0x000C4}, // LATIN CAPITAL LETTER A WITH DIAERESIS -+ {"auml", 0x000E4}, // LATIN SMALL LETTER A WITH DIAERESIS -+ {"awconint", 0x02233}, // ANTICLOCKWISE CONTOUR INTEGRAL -+ {"awint", 0x02A11}, // ANTICLOCKWISE INTEGRATION -+ {NULL, 0} - }; - - static NameId namesB[]={ -- "backcong", 0x0224C, // ALL EQUAL TO -- "backepsilon", 0x003F6, // GREEK REVERSED LUNATE EPSILON SYMBOL -- "backprime", 0x02035, // REVERSED PRIME -- "backsim", 0x0223D, // REVERSED TILDE -- "backsimeq", 0x022CD, // REVERSED TILDE EQUALS -- "Backslash", 0x02216, // SET MINUS --// "b.alpha", 0x1D6C2, // MATHEMATICAL BOLD SMALL ALPHA -- "Barv", 0x02AE7, // SHORT DOWN TACK WITH OVERBAR -- "barvee", 0x022BD, // NOR -- "barwed", 0x02305, // PROJECTIVE -- "Barwed", 0x02306, // PERSPECTIVE -- "barwedge", 0x02305, // PROJECTIVE --// "b.beta", 0x1D6C3, // MATHEMATICAL BOLD SMALL BETA -- "bbrk", 0x023B5, // BOTTOM SQUARE BRACKET -- "bbrktbrk", 0x023B6, // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET --// "b.chi", 0x1D6D8, // MATHEMATICAL BOLD SMALL CHI -- "bcong", 0x0224C, // ALL EQUAL TO -- "Bcy", 0x00411, // CYRILLIC CAPITAL LETTER BE -- "bcy", 0x00431, // CYRILLIC SMALL LETTER BE --// "b.Delta", 0x1D6AB, // MATHEMATICAL BOLD CAPITAL DELTA --// "b.delta", 0x1D6C5, // MATHEMATICAL BOLD SMALL DELTA -- "bdquo", 0x0201E, // DOUBLE LOW-9 QUOTATION MARK -- "becaus", 0x02235, // BECAUSE -- "because", 0x02235, // BECAUSE -- "Because", 0x02235, // BECAUSE -- "bemptyv", 0x029B0, // REVERSED EMPTY SET -- "bepsi", 0x003F6, // GREEK REVERSED LUNATE EPSILON SYMBOL --// "b.epsi", 0x1D6C6, // MATHEMATICAL BOLD SMALL EPSILON --// "b.epsiv", 0x1D6DC, // MATHEMATICAL BOLD EPSILON SYMBOL -- "bernou", 0x0212C, // SCRIPT CAPITAL B -- "Bernoullis", 0x0212C, // SCRIPT CAPITAL B -- "Beta", 0x00392, // GREEK CAPITAL LETTER BETA -- "beta", 0x003B2, // GREEK SMALL LETTER BETA --// "b.eta", 0x1D6C8, // MATHEMATICAL BOLD SMALL ETA -- "beth", 0x02136, // BET SYMBOL -- "between", 0x0226C, // BETWEEN -- "Bfr", 0x1D505, // MATHEMATICAL FRAKTUR CAPITAL B -- "bfr", 0x1D51F, // MATHEMATICAL FRAKTUR SMALL B --// "b.Gamma", 0x1D6AA, // MATHEMATICAL BOLD CAPITAL GAMMA --// "b.gamma", 0x1D6C4, // MATHEMATICAL BOLD SMALL GAMMA --// "b.Gammad", 0x1D7CA, // MATHEMATICAL BOLD CAPITAL DIGAMMA --// "b.gammad", 0x1D7CB, // MATHEMATICAL BOLD SMALL DIGAMMA -- "Bgr", 0x00392, // GREEK CAPITAL LETTER BETA -- "bgr", 0x003B2, // GREEK SMALL LETTER BETA -- "bigcap", 0x022C2, // N-ARY INTERSECTION -- "bigcirc", 0x025EF, // LARGE CIRCLE -- "bigcup", 0x022C3, // N-ARY UNION -- "bigodot", 0x02A00, // N-ARY CIRCLED DOT OPERATOR -- "bigoplus", 0x02A01, // N-ARY CIRCLED PLUS OPERATOR -- "bigotimes", 0x02A02, // N-ARY CIRCLED TIMES OPERATOR -- "bigsqcup", 0x02A06, // N-ARY SQUARE UNION OPERATOR -- "bigstar", 0x02605, // BLACK STAR -- "bigtriangledown", 0x025BD, // WHITE DOWN-POINTING TRIANGLE -- "bigtriangleup", 0x025B3, // WHITE UP-POINTING TRIANGLE -- "biguplus", 0x02A04, // N-ARY UNION OPERATOR WITH PLUS -- "bigvee", 0x022C1, // N-ARY LOGICAL OR -- "bigwedge", 0x022C0, // N-ARY LOGICAL AND --// "b.iota", 0x1D6CA, // MATHEMATICAL BOLD SMALL IOTA --// "b.kappa", 0x1D6CB, // MATHEMATICAL BOLD SMALL KAPPA --// "b.kappav", 0x1D6DE, // MATHEMATICAL BOLD KAPPA SYMBOL -- "bkarow", 0x0290D, // RIGHTWARDS DOUBLE DASH ARROW -- "blacklozenge", 0x029EB, // BLACK LOZENGE -- "blacksquare", 0x025AA, // BLACK SMALL SQUARE -- "blacktriangle", 0x025B4, // BLACK UP-POINTING SMALL TRIANGLE -- "blacktriangledown", 0x025BE, // BLACK DOWN-POINTING SMALL TRIANGLE -- "blacktriangleleft", 0x025C2, // BLACK LEFT-POINTING SMALL TRIANGLE -- "blacktriangleright", 0x025B8, // BLACK RIGHT-POINTING SMALL TRIANGLE --// "b.Lambda", 0x1D6B2, // MATHEMATICAL BOLD CAPITAL LAMDA --// "b.lambda", 0x1D6CC, // MATHEMATICAL BOLD SMALL LAMDA -- "blank", 0x02423, // OPEN BOX -- "blk12", 0x02592, // MEDIUM SHADE -- "blk14", 0x02591, // LIGHT SHADE -- "blk34", 0x02593, // DARK SHADE -- "block", 0x02588, // FULL BLOCK --// "b.mu", 0x1D6CD, // MATHEMATICAL BOLD SMALL MU --// "bne", 0x0003D;0x020E5, // EQUALS SIGN with reverse slash --// "bnequiv", 0x02261;0x020E5, // IDENTICAL TO with reverse slash -- "bnot", 0x02310, // REVERSED NOT SIGN -- "bNot", 0x02AED, // REVERSED DOUBLE STROKE NOT SIGN --// "b.nu", 0x1D6CE, // MATHEMATICAL BOLD SMALL NU --// "b.Omega", 0x1D6C0, // MATHEMATICAL BOLD CAPITAL OMEGA --// "b.omega", 0x1D6DA, // MATHEMATICAL BOLD SMALL OMEGA -- "Bopf", 0x1D539, // MATHEMATICAL DOUBLE-STRUCK CAPITAL B -- "bopf", 0x1D553, // MATHEMATICAL DOUBLE-STRUCK SMALL B -- "bot", 0x022A5, // UP TACK -- "bottom", 0x022A5, // UP TACK -- "bowtie", 0x022C8, // BOWTIE -- "boxbox", 0x029C9, // TWO JOINED SQUARES -- "boxdl", 0x02510, // BOX DRAWINGS LIGHT DOWN AND LEFT -- "boxdL", 0x02555, // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE -- "boxDl", 0x02556, // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE -- "boxDL", 0x02557, // BOX DRAWINGS DOUBLE DOWN AND LEFT -- "boxdr", 0x0250C, // BOX DRAWINGS LIGHT DOWN AND RIGHT -- "boxdR", 0x02552, // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE -- "boxDr", 0x02553, // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE -- "boxDR", 0x02554, // BOX DRAWINGS DOUBLE DOWN AND RIGHT -- "boxh", 0x02500, // BOX DRAWINGS LIGHT HORIZONTAL -- "boxH", 0x02550, // BOX DRAWINGS DOUBLE HORIZONTAL -- "boxhd", 0x0252C, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL -- "boxHd", 0x02564, // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE -- "boxhD", 0x02565, // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE -- "boxHD", 0x02566, // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL -- "boxhu", 0x02534, // BOX DRAWINGS LIGHT UP AND HORIZONTAL -- "boxHu", 0x02567, // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE -- "boxhU", 0x02568, // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE -- "boxHU", 0x02569, // BOX DRAWINGS DOUBLE UP AND HORIZONTAL -- "boxminus", 0x0229F, // SQUARED MINUS -- "boxplus", 0x0229E, // SQUARED PLUS -- "boxtimes", 0x022A0, // SQUARED TIMES -- "boxul", 0x02518, // BOX DRAWINGS LIGHT UP AND LEFT -- "boxuL", 0x0255B, // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE -- "boxUl", 0x0255C, // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE -- "boxUL", 0x0255D, // BOX DRAWINGS DOUBLE UP AND LEFT -- "boxur", 0x02514, // BOX DRAWINGS LIGHT UP AND RIGHT -- "boxuR", 0x02558, // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE -- "boxUr", 0x02559, // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE -- "boxUR", 0x0255A, // BOX DRAWINGS DOUBLE UP AND RIGHT -- "boxv", 0x02502, // BOX DRAWINGS LIGHT VERTICAL -- "boxV", 0x02551, // BOX DRAWINGS DOUBLE VERTICAL -- "boxvh", 0x0253C, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL -- "boxvH", 0x0256A, // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE -- "boxVh", 0x0256B, // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE -- "boxVH", 0x0256C, // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL -- "boxvl", 0x02524, // BOX DRAWINGS LIGHT VERTICAL AND LEFT -- "boxvL", 0x02561, // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE -- "boxVl", 0x02562, // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE -- "boxVL", 0x02563, // BOX DRAWINGS DOUBLE VERTICAL AND LEFT -- "boxvr", 0x0251C, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT -- "boxvR", 0x0255E, // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE -- "boxVr", 0x0255F, // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE -- "boxVR", 0x02560, // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT --// "b.Phi", 0x1D6BD, // MATHEMATICAL BOLD CAPITAL PHI --// "b.phi", 0x1D6D7, // MATHEMATICAL BOLD SMALL PHI --// "b.phiv", 0x1D6DF, // MATHEMATICAL BOLD PHI SYMBOL --// "b.Pi", 0x1D6B7, // MATHEMATICAL BOLD CAPITAL PI --// "b.pi", 0x1D6D1, // MATHEMATICAL BOLD SMALL PI --// "b.piv", 0x1D6E1, // MATHEMATICAL BOLD PI SYMBOL -- "bprime", 0x02035, // REVERSED PRIME --// "b.Psi", 0x1D6BF, // MATHEMATICAL BOLD CAPITAL PSI --// "b.psi", 0x1D6D9, // MATHEMATICAL BOLD SMALL PSI -- "breve", 0x002D8, // BREVE -- "Breve", 0x002D8, // BREVE --// "b.rho", 0x1D6D2, // MATHEMATICAL BOLD SMALL RHO --// "b.rhov", 0x1D6E0, // MATHEMATICAL BOLD RHO SYMBOL -- "brvbar", 0x000A6, // BROKEN BAR -- "Bscr", 0x0212C, // SCRIPT CAPITAL B -- "bscr", 0x1D4B7, // MATHEMATICAL SCRIPT SMALL B -- "bsemi", 0x0204F, // REVERSED SEMICOLON --// "b.Sigma", 0x1D6BA, // MATHEMATICAL BOLD CAPITAL SIGMA --// "b.sigma", 0x1D6D4, // MATHEMATICAL BOLD SMALL SIGMA --// "b.sigmav", 0x1D6D3, // MATHEMATICAL BOLD SMALL FINAL SIGMA -- "bsim", 0x0223D, // REVERSED TILDE -- "bsime", 0x022CD, // REVERSED TILDE EQUALS -- "bsol", 0x0005C, // REVERSE SOLIDUS -- "bsolb", 0x029C5, // SQUARED FALLING DIAGONAL SLASH -- "bsolhsub", 0x027C8, // REVERSE SOLIDUS PRECEDING SUBSET --// "b.tau", 0x1D6D5, // MATHEMATICAL BOLD SMALL TAU --// "b.Theta", 0x1D6AF, // MATHEMATICAL BOLD CAPITAL THETA --// "b.thetas", 0x1D6C9, // MATHEMATICAL BOLD SMALL THETA --// "b.thetav", 0x1D6DD, // MATHEMATICAL BOLD THETA SYMBOL -- "bull", 0x02022, // BULLET -- "bullet", 0x02022, // BULLET -- "bump", 0x0224E, // GEOMETRICALLY EQUIVALENT TO -- "bumpe", 0x0224F, // DIFFERENCE BETWEEN -- "bumpE", 0x02AAE, // EQUALS SIGN WITH BUMPY ABOVE -- "Bumpeq", 0x0224E, // GEOMETRICALLY EQUIVALENT TO -- "bumpeq", 0x0224F, // DIFFERENCE BETWEEN --// "b.Upsi", 0x1D6BC, // MATHEMATICAL BOLD CAPITAL UPSILON --// "b.upsi", 0x1D6D6, // MATHEMATICAL BOLD SMALL UPSILON --// "b.Xi", 0x1D6B5, // MATHEMATICAL BOLD CAPITAL XI --// "b.xi", 0x1D6CF, // MATHEMATICAL BOLD SMALL XI --// "b.zeta", 0x1D6C7, // MATHEMATICAL BOLD SMALL ZETA -- NULL, 0 -+ {"backcong", 0x0224C}, // ALL EQUAL TO -+ {"backepsilon", 0x003F6}, // GREEK REVERSED LUNATE EPSILON SYMBOL -+ {"backprime", 0x02035}, // REVERSED PRIME -+ {"backsim", 0x0223D}, // REVERSED TILDE -+ {"backsimeq", 0x022CD}, // REVERSED TILDE EQUALS -+ {"Backslash", 0x02216}, // SET MINUS -+// "b.alpha", 0x1D6C2}, // MATHEMATICAL BOLD SMALL ALPHA -+ {"Barv", 0x02AE7}, // SHORT DOWN TACK WITH OVERBAR -+ {"barvee", 0x022BD}, // NOR -+ {"barwed", 0x02305}, // PROJECTIVE -+ {"Barwed", 0x02306}, // PERSPECTIVE -+ {"barwedge", 0x02305}, // PROJECTIVE -+// "b.beta", 0x1D6C3}, // MATHEMATICAL BOLD SMALL BETA -+ {"bbrk", 0x023B5}, // BOTTOM SQUARE BRACKET -+ {"bbrktbrk", 0x023B6}, // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET -+// "b.chi", 0x1D6D8}, // MATHEMATICAL BOLD SMALL CHI -+ {"bcong", 0x0224C}, // ALL EQUAL TO -+ {"Bcy", 0x00411}, // CYRILLIC CAPITAL LETTER BE -+ {"bcy", 0x00431}, // CYRILLIC SMALL LETTER BE -+// "b.Delta", 0x1D6AB}, // MATHEMATICAL BOLD CAPITAL DELTA -+// "b.delta", 0x1D6C5}, // MATHEMATICAL BOLD SMALL DELTA -+ {"bdquo", 0x0201E}, // DOUBLE LOW-9 QUOTATION MARK -+ {"becaus", 0x02235}, // BECAUSE -+ {"because", 0x02235}, // BECAUSE -+ {"Because", 0x02235}, // BECAUSE -+ {"bemptyv", 0x029B0}, // REVERSED EMPTY SET -+ {"bepsi", 0x003F6}, // GREEK REVERSED LUNATE EPSILON SYMBOL -+// "b.epsi", 0x1D6C6}, // MATHEMATICAL BOLD SMALL EPSILON -+// "b.epsiv", 0x1D6DC}, // MATHEMATICAL BOLD EPSILON SYMBOL -+ {"bernou", 0x0212C}, // SCRIPT CAPITAL B -+ {"Bernoullis", 0x0212C}, // SCRIPT CAPITAL B -+ {"Beta", 0x00392}, // GREEK CAPITAL LETTER BETA -+ {"beta", 0x003B2}, // GREEK SMALL LETTER BETA -+// "b.eta", 0x1D6C8}, // MATHEMATICAL BOLD SMALL ETA -+ {"beth", 0x02136}, // BET SYMBOL -+ {"between", 0x0226C}, // BETWEEN -+ {"Bfr", 0x1D505}, // MATHEMATICAL FRAKTUR CAPITAL B -+ {"bfr", 0x1D51F}, // MATHEMATICAL FRAKTUR SMALL B -+// "b.Gamma", 0x1D6AA}, // MATHEMATICAL BOLD CAPITAL GAMMA -+// "b.gamma", 0x1D6C4}, // MATHEMATICAL BOLD SMALL GAMMA -+// "b.Gammad", 0x1D7CA}, // MATHEMATICAL BOLD CAPITAL DIGAMMA -+// "b.gammad", 0x1D7CB}, // MATHEMATICAL BOLD SMALL DIGAMMA -+ {"Bgr", 0x00392}, // GREEK CAPITAL LETTER BETA -+ {"bgr", 0x003B2}, // GREEK SMALL LETTER BETA -+ {"bigcap", 0x022C2}, // N-ARY INTERSECTION -+ {"bigcirc", 0x025EF}, // LARGE CIRCLE -+ {"bigcup", 0x022C3}, // N-ARY UNION -+ {"bigodot", 0x02A00}, // N-ARY CIRCLED DOT OPERATOR -+ {"bigoplus", 0x02A01}, // N-ARY CIRCLED PLUS OPERATOR -+ {"bigotimes", 0x02A02}, // N-ARY CIRCLED TIMES OPERATOR -+ {"bigsqcup", 0x02A06}, // N-ARY SQUARE UNION OPERATOR -+ {"bigstar", 0x02605}, // BLACK STAR -+ {"bigtriangledown", 0x025BD}, // WHITE DOWN-POINTING TRIANGLE -+ {"bigtriangleup", 0x025B3}, // WHITE UP-POINTING TRIANGLE -+ {"biguplus", 0x02A04}, // N-ARY UNION OPERATOR WITH PLUS -+ {"bigvee", 0x022C1}, // N-ARY LOGICAL OR -+ {"bigwedge", 0x022C0}, // N-ARY LOGICAL AND -+// "b.iota", 0x1D6CA}, // MATHEMATICAL BOLD SMALL IOTA -+// "b.kappa", 0x1D6CB}, // MATHEMATICAL BOLD SMALL KAPPA -+// "b.kappav", 0x1D6DE}, // MATHEMATICAL BOLD KAPPA SYMBOL -+ {"bkarow", 0x0290D}, // RIGHTWARDS DOUBLE DASH ARROW -+ {"blacklozenge", 0x029EB}, // BLACK LOZENGE -+ {"blacksquare", 0x025AA}, // BLACK SMALL SQUARE -+ {"blacktriangle", 0x025B4}, // BLACK UP-POINTING SMALL TRIANGLE -+ {"blacktriangledown", 0x025BE}, // BLACK DOWN-POINTING SMALL TRIANGLE -+ {"blacktriangleleft", 0x025C2}, // BLACK LEFT-POINTING SMALL TRIANGLE -+ {"blacktriangleright", 0x025B8}, // BLACK RIGHT-POINTING SMALL TRIANGLE -+// "b.Lambda", 0x1D6B2}, // MATHEMATICAL BOLD CAPITAL LAMDA -+// "b.lambda", 0x1D6CC}, // MATHEMATICAL BOLD SMALL LAMDA -+ {"blank", 0x02423}, // OPEN BOX -+ {"blk12", 0x02592}, // MEDIUM SHADE -+ {"blk14", 0x02591}, // LIGHT SHADE -+ {"blk34", 0x02593}, // DARK SHADE -+ {"block", 0x02588}, // FULL BLOCK -+// "b.mu", 0x1D6CD}, // MATHEMATICAL BOLD SMALL MU -+// "bne", 0x0003D;0x020E5}, // EQUALS SIGN with reverse slash -+// "bnequiv", 0x02261;0x020E5}, // IDENTICAL TO with reverse slash -+ {"bnot", 0x02310}, // REVERSED NOT SIGN -+ {"bNot", 0x02AED}, // REVERSED DOUBLE STROKE NOT SIGN -+// "b.nu", 0x1D6CE}, // MATHEMATICAL BOLD SMALL NU -+// "b.Omega", 0x1D6C0}, // MATHEMATICAL BOLD CAPITAL OMEGA -+// "b.omega", 0x1D6DA}, // MATHEMATICAL BOLD SMALL OMEGA -+ {"Bopf", 0x1D539}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL B -+ {"bopf", 0x1D553}, // MATHEMATICAL DOUBLE-STRUCK SMALL B -+ {"bot", 0x022A5}, // UP TACK -+ {"bottom", 0x022A5}, // UP TACK -+ {"bowtie", 0x022C8}, // BOWTIE -+ {"boxbox", 0x029C9}, // TWO JOINED SQUARES -+ {"boxdl", 0x02510}, // BOX DRAWINGS LIGHT DOWN AND LEFT -+ {"boxdL", 0x02555}, // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE -+ {"boxDl", 0x02556}, // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE -+ {"boxDL", 0x02557}, // BOX DRAWINGS DOUBLE DOWN AND LEFT -+ {"boxdr", 0x0250C}, // BOX DRAWINGS LIGHT DOWN AND RIGHT -+ {"boxdR", 0x02552}, // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE -+ {"boxDr", 0x02553}, // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE -+ {"boxDR", 0x02554}, // BOX DRAWINGS DOUBLE DOWN AND RIGHT -+ {"boxh", 0x02500}, // BOX DRAWINGS LIGHT HORIZONTAL -+ {"boxH", 0x02550}, // BOX DRAWINGS DOUBLE HORIZONTAL -+ {"boxhd", 0x0252C}, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL -+ {"boxHd", 0x02564}, // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE -+ {"boxhD", 0x02565}, // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE -+ {"boxHD", 0x02566}, // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL -+ {"boxhu", 0x02534}, // BOX DRAWINGS LIGHT UP AND HORIZONTAL -+ {"boxHu", 0x02567}, // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE -+ {"boxhU", 0x02568}, // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE -+ {"boxHU", 0x02569}, // BOX DRAWINGS DOUBLE UP AND HORIZONTAL -+ {"boxminus", 0x0229F}, // SQUARED MINUS -+ {"boxplus", 0x0229E}, // SQUARED PLUS -+ {"boxtimes", 0x022A0}, // SQUARED TIMES -+ {"boxul", 0x02518}, // BOX DRAWINGS LIGHT UP AND LEFT -+ {"boxuL", 0x0255B}, // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE -+ {"boxUl", 0x0255C}, // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE -+ {"boxUL", 0x0255D}, // BOX DRAWINGS DOUBLE UP AND LEFT -+ {"boxur", 0x02514}, // BOX DRAWINGS LIGHT UP AND RIGHT -+ {"boxuR", 0x02558}, // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE -+ {"boxUr", 0x02559}, // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE -+ {"boxUR", 0x0255A}, // BOX DRAWINGS DOUBLE UP AND RIGHT -+ {"boxv", 0x02502}, // BOX DRAWINGS LIGHT VERTICAL -+ {"boxV", 0x02551}, // BOX DRAWINGS DOUBLE VERTICAL -+ {"boxvh", 0x0253C}, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL -+ {"boxvH", 0x0256A}, // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE -+ {"boxVh", 0x0256B}, // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE -+ {"boxVH", 0x0256C}, // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL -+ {"boxvl", 0x02524}, // BOX DRAWINGS LIGHT VERTICAL AND LEFT -+ {"boxvL", 0x02561}, // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE -+ {"boxVl", 0x02562}, // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE -+ {"boxVL", 0x02563}, // BOX DRAWINGS DOUBLE VERTICAL AND LEFT -+ {"boxvr", 0x0251C}, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT -+ {"boxvR", 0x0255E}, // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE -+ {"boxVr", 0x0255F}, // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE -+ {"boxVR", 0x02560}, // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT -+// "b.Phi", 0x1D6BD}, // MATHEMATICAL BOLD CAPITAL PHI -+// "b.phi", 0x1D6D7}, // MATHEMATICAL BOLD SMALL PHI -+// "b.phiv", 0x1D6DF}, // MATHEMATICAL BOLD PHI SYMBOL -+// "b.Pi", 0x1D6B7}, // MATHEMATICAL BOLD CAPITAL PI -+// "b.pi", 0x1D6D1}, // MATHEMATICAL BOLD SMALL PI -+// "b.piv", 0x1D6E1}, // MATHEMATICAL BOLD PI SYMBOL -+ {"bprime", 0x02035}, // REVERSED PRIME -+// "b.Psi", 0x1D6BF}, // MATHEMATICAL BOLD CAPITAL PSI -+// "b.psi", 0x1D6D9}, // MATHEMATICAL BOLD SMALL PSI -+ {"breve", 0x002D8}, // BREVE -+ {"Breve", 0x002D8}, // BREVE -+// "b.rho", 0x1D6D2}, // MATHEMATICAL BOLD SMALL RHO -+// "b.rhov", 0x1D6E0}, // MATHEMATICAL BOLD RHO SYMBOL -+ {"brvbar", 0x000A6}, // BROKEN BAR -+ {"Bscr", 0x0212C}, // SCRIPT CAPITAL B -+ {"bscr", 0x1D4B7}, // MATHEMATICAL SCRIPT SMALL B -+ {"bsemi", 0x0204F}, // REVERSED SEMICOLON -+// "b.Sigma", 0x1D6BA}, // MATHEMATICAL BOLD CAPITAL SIGMA -+// "b.sigma", 0x1D6D4}, // MATHEMATICAL BOLD SMALL SIGMA -+// "b.sigmav", 0x1D6D3}, // MATHEMATICAL BOLD SMALL FINAL SIGMA -+ {"bsim", 0x0223D}, // REVERSED TILDE -+ {"bsime", 0x022CD}, // REVERSED TILDE EQUALS -+ {"bsol", 0x0005C}, // REVERSE SOLIDUS -+ {"bsolb", 0x029C5}, // SQUARED FALLING DIAGONAL SLASH -+ {"bsolhsub", 0x027C8}, // REVERSE SOLIDUS PRECEDING SUBSET -+// "b.tau", 0x1D6D5}, // MATHEMATICAL BOLD SMALL TAU -+// "b.Theta", 0x1D6AF}, // MATHEMATICAL BOLD CAPITAL THETA -+// "b.thetas", 0x1D6C9}, // MATHEMATICAL BOLD SMALL THETA -+// "b.thetav", 0x1D6DD}, // MATHEMATICAL BOLD THETA SYMBOL -+ {"bull", 0x02022}, // BULLET -+ {"bullet", 0x02022}, // BULLET -+ {"bump", 0x0224E}, // GEOMETRICALLY EQUIVALENT TO -+ {"bumpe", 0x0224F}, // DIFFERENCE BETWEEN -+ {"bumpE", 0x02AAE}, // EQUALS SIGN WITH BUMPY ABOVE -+ {"Bumpeq", 0x0224E}, // GEOMETRICALLY EQUIVALENT TO -+ {"bumpeq", 0x0224F}, // DIFFERENCE BETWEEN -+// "b.Upsi", 0x1D6BC}, // MATHEMATICAL BOLD CAPITAL UPSILON -+// "b.upsi", 0x1D6D6}, // MATHEMATICAL BOLD SMALL UPSILON -+// "b.Xi", 0x1D6B5}, // MATHEMATICAL BOLD CAPITAL XI -+// "b.xi", 0x1D6CF}, // MATHEMATICAL BOLD SMALL XI -+// "b.zeta", 0x1D6C7}, // MATHEMATICAL BOLD SMALL ZETA -+ {NULL, 0} - }; - - static NameId namesC[]={ -- "Cacute", 0x00106, // LATIN CAPITAL LETTER C WITH ACUTE -- "cacute", 0x00107, // LATIN SMALL LETTER C WITH ACUTE -- "cap", 0x02229, // INTERSECTION -- "Cap", 0x022D2, // DOUBLE INTERSECTION -- "capand", 0x02A44, // INTERSECTION WITH LOGICAL AND -- "capbrcup", 0x02A49, // INTERSECTION ABOVE BAR ABOVE UNION -- "capcap", 0x02A4B, // INTERSECTION BESIDE AND JOINED WITH INTERSECTION -- "capcup", 0x02A47, // INTERSECTION ABOVE UNION -- "capdot", 0x02A40, // INTERSECTION WITH DOT -- "CapitalDifferentialD", 0x02145, // DOUBLE-STRUCK ITALIC CAPITAL D --// "caps", 0x02229;0x0FE00, // INTERSECTION with serifs -- "caret", 0x02041, // CARET INSERTION POINT -- "caron", 0x002C7, // CARON -- "Cayleys", 0x0212D, // BLACK-LETTER CAPITAL C -- "ccaps", 0x02A4D, // CLOSED INTERSECTION WITH SERIFS -- "Ccaron", 0x0010C, // LATIN CAPITAL LETTER C WITH CARON -- "ccaron", 0x0010D, // LATIN SMALL LETTER C WITH CARON -- "Ccedil", 0x000C7, // LATIN CAPITAL LETTER C WITH CEDILLA -- "ccedil", 0x000E7, // LATIN SMALL LETTER C WITH CEDILLA -- "Ccirc", 0x00108, // LATIN CAPITAL LETTER C WITH CIRCUMFLEX -- "ccirc", 0x00109, // LATIN SMALL LETTER C WITH CIRCUMFLEX -- "Cconint", 0x02230, // VOLUME INTEGRAL -- "ccups", 0x02A4C, // CLOSED UNION WITH SERIFS -- "ccupssm", 0x02A50, // CLOSED UNION WITH SERIFS AND SMASH PRODUCT -- "Cdot", 0x0010A, // LATIN CAPITAL LETTER C WITH DOT ABOVE -- "cdot", 0x0010B, // LATIN SMALL LETTER C WITH DOT ABOVE -- "cedil", 0x000B8, // CEDILLA -- "Cedilla", 0x000B8, // CEDILLA -- "cemptyv", 0x029B2, // EMPTY SET WITH SMALL CIRCLE ABOVE -- "cent", 0x000A2, // CENT SIGN -- "centerdot", 0x000B7, // MIDDLE DOT -- "CenterDot", 0x000B7, // MIDDLE DOT -- "Cfr", 0x0212D, // BLACK-LETTER CAPITAL C -- "cfr", 0x1D520, // MATHEMATICAL FRAKTUR SMALL C -- "CHcy", 0x00427, // CYRILLIC CAPITAL LETTER CHE -- "chcy", 0x00447, // CYRILLIC SMALL LETTER CHE -- "check", 0x02713, // CHECK MARK -- "checkmark", 0x02713, // CHECK MARK -- "Chi", 0x003A7, // GREEK CAPITAL LETTER CHI -- "chi", 0x003C7, // GREEK SMALL LETTER CHI -- "cir", 0x025CB, // WHITE CIRCLE -- "circ", 0x002C6, // MODIFIER LETTER CIRCUMFLEX ACCENT -- "circeq", 0x02257, // RING EQUAL TO -- "circlearrowleft", 0x021BA, // ANTICLOCKWISE OPEN CIRCLE ARROW -- "circlearrowright", 0x021BB, // CLOCKWISE OPEN CIRCLE ARROW -- "circledast", 0x0229B, // CIRCLED ASTERISK OPERATOR -- "circledcirc", 0x0229A, // CIRCLED RING OPERATOR -- "circleddash", 0x0229D, // CIRCLED DASH -- "CircleDot", 0x02299, // CIRCLED DOT OPERATOR -- "circledR", 0x000AE, // REGISTERED SIGN -- "circledS", 0x024C8, // CIRCLED LATIN CAPITAL LETTER S -- "CircleMinus", 0x02296, // CIRCLED MINUS -- "CirclePlus", 0x02295, // CIRCLED PLUS -- "CircleTimes", 0x02297, // CIRCLED TIMES -- "cire", 0x02257, // RING EQUAL TO -- "cirE", 0x029C3, // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT -- "cirfnint", 0x02A10, // CIRCULATION FUNCTION -- "cirmid", 0x02AEF, // VERTICAL LINE WITH CIRCLE ABOVE -- "cirscir", 0x029C2, // CIRCLE WITH SMALL CIRCLE TO THE RIGHT -- "ClockwiseContourIntegral", 0x02232, // CLOCKWISE CONTOUR INTEGRAL -- "CloseCurlyDoubleQuote", 0x0201D, // RIGHT DOUBLE QUOTATION MARK -- "CloseCurlyQuote", 0x02019, // RIGHT SINGLE QUOTATION MARK -- "clubs", 0x02663, // BLACK CLUB SUIT -- "clubsuit", 0x02663, // BLACK CLUB SUIT -- "colon", 0x0003A, // COLON -- "Colon", 0x02237, // PROPORTION -- "colone", 0x02254, // COLON EQUALS -- "Colone", 0x02A74, // DOUBLE COLON EQUAL -- "coloneq", 0x02254, // COLON EQUALS -- "comma", 0x0002C, // COMMA -- "commat", 0x00040, // COMMERCIAL AT -- "comp", 0x02201, // COMPLEMENT -- "compfn", 0x02218, // RING OPERATOR -- "complement", 0x02201, // COMPLEMENT -- "complexes", 0x02102, // DOUBLE-STRUCK CAPITAL C -- "cong", 0x02245, // APPROXIMATELY EQUAL TO -- "congdot", 0x02A6D, // CONGRUENT WITH DOT ABOVE -- "Congruent", 0x02261, // IDENTICAL TO -- "conint", 0x0222E, // CONTOUR INTEGRAL -- "Conint", 0x0222F, // SURFACE INTEGRAL -- "ContourIntegral", 0x0222E, // CONTOUR INTEGRAL -- "Copf", 0x02102, // DOUBLE-STRUCK CAPITAL C -- "copf", 0x1D554, // MATHEMATICAL DOUBLE-STRUCK SMALL C -- "coprod", 0x02210, // N-ARY COPRODUCT -- "Coproduct", 0x02210, // N-ARY COPRODUCT -- "copy", 0x000A9, // COPYRIGHT SIGN -- "COPY", 0x000A9, // COPYRIGHT SIGN -- "copysr", 0x02117, // SOUND RECORDING COPYRIGHT -- "CounterClockwiseContourIntegral", 0x02233, // ANTICLOCKWISE CONTOUR INTEGRAL -- "crarr", 0x021B5, // DOWNWARDS ARROW WITH CORNER LEFTWARDS -- "cross", 0x02717, // BALLOT X -- "Cross", 0x02A2F, // VECTOR OR CROSS PRODUCT -- "Cscr", 0x1D49E, // MATHEMATICAL SCRIPT CAPITAL C -- "cscr", 0x1D4B8, // MATHEMATICAL SCRIPT SMALL C -- "csub", 0x02ACF, // CLOSED SUBSET -- "csube", 0x02AD1, // CLOSED SUBSET OR EQUAL TO -- "csup", 0x02AD0, // CLOSED SUPERSET -- "csupe", 0x02AD2, // CLOSED SUPERSET OR EQUAL TO -- "ctdot", 0x022EF, // MIDLINE HORIZONTAL ELLIPSIS -- "cudarrl", 0x02938, // RIGHT-SIDE ARC CLOCKWISE ARROW -- "cudarrr", 0x02935, // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS -- "cuepr", 0x022DE, // EQUAL TO OR PRECEDES -- "cuesc", 0x022DF, // EQUAL TO OR SUCCEEDS -- "cularr", 0x021B6, // ANTICLOCKWISE TOP SEMICIRCLE ARROW -- "cularrp", 0x0293D, // TOP ARC ANTICLOCKWISE ARROW WITH PLUS -- "cup", 0x0222A, // UNION -- "Cup", 0x022D3, // DOUBLE UNION -- "cupbrcap", 0x02A48, // UNION ABOVE BAR ABOVE INTERSECTION -- "CupCap", 0x0224D, // EQUIVALENT TO -- "cupcap", 0x02A46, // UNION ABOVE INTERSECTION -- "cupcup", 0x02A4A, // UNION BESIDE AND JOINED WITH UNION -- "cupdot", 0x0228D, // MULTISET MULTIPLICATION -- "cupor", 0x02A45, // UNION WITH LOGICAL OR --// "cups", 0x0222A;0x0FE00, // UNION with serifs -- "curarr", 0x021B7, // CLOCKWISE TOP SEMICIRCLE ARROW -- "curarrm", 0x0293C, // TOP ARC CLOCKWISE ARROW WITH MINUS -- "curlyeqprec", 0x022DE, // EQUAL TO OR PRECEDES -- "curlyeqsucc", 0x022DF, // EQUAL TO OR SUCCEEDS -- "curlyvee", 0x022CE, // CURLY LOGICAL OR -- "curlywedge", 0x022CF, // CURLY LOGICAL AND -- "curren", 0x000A4, // CURRENCY SIGN -- "curvearrowleft", 0x021B6, // ANTICLOCKWISE TOP SEMICIRCLE ARROW -- "curvearrowright", 0x021B7, // CLOCKWISE TOP SEMICIRCLE ARROW -- "cuvee", 0x022CE, // CURLY LOGICAL OR -- "cuwed", 0x022CF, // CURLY LOGICAL AND -- "cwconint", 0x02232, // CLOCKWISE CONTOUR INTEGRAL -- "cwint", 0x02231, // CLOCKWISE INTEGRAL -- "cylcty", 0x0232D, // CYLINDRICITY -- NULL, 0 -+ {"Cacute", 0x00106}, // LATIN CAPITAL LETTER C WITH ACUTE -+ {"cacute", 0x00107}, // LATIN SMALL LETTER C WITH ACUTE -+ {"cap", 0x02229}, // INTERSECTION -+ {"Cap", 0x022D2}, // DOUBLE INTERSECTION -+ {"capand", 0x02A44}, // INTERSECTION WITH LOGICAL AND -+ {"capbrcup", 0x02A49}, // INTERSECTION ABOVE BAR ABOVE UNION -+ {"capcap", 0x02A4B}, // INTERSECTION BESIDE AND JOINED WITH INTERSECTION -+ {"capcup", 0x02A47}, // INTERSECTION ABOVE UNION -+ {"capdot", 0x02A40}, // INTERSECTION WITH DOT -+ {"CapitalDifferentialD", 0x02145}, // DOUBLE-STRUCK ITALIC CAPITAL D -+// "caps", 0x02229;0x0FE00}, // INTERSECTION with serifs -+ {"caret", 0x02041}, // CARET INSERTION POINT -+ {"caron", 0x002C7}, // CARON -+ {"Cayleys", 0x0212D}, // BLACK-LETTER CAPITAL C -+ {"ccaps", 0x02A4D}, // CLOSED INTERSECTION WITH SERIFS -+ {"Ccaron", 0x0010C}, // LATIN CAPITAL LETTER C WITH CARON -+ {"ccaron", 0x0010D}, // LATIN SMALL LETTER C WITH CARON -+ {"Ccedil", 0x000C7}, // LATIN CAPITAL LETTER C WITH CEDILLA -+ {"ccedil", 0x000E7}, // LATIN SMALL LETTER C WITH CEDILLA -+ {"Ccirc", 0x00108}, // LATIN CAPITAL LETTER C WITH CIRCUMFLEX -+ {"ccirc", 0x00109}, // LATIN SMALL LETTER C WITH CIRCUMFLEX -+ {"Cconint", 0x02230}, // VOLUME INTEGRAL -+ {"ccups", 0x02A4C}, // CLOSED UNION WITH SERIFS -+ {"ccupssm", 0x02A50}, // CLOSED UNION WITH SERIFS AND SMASH PRODUCT -+ {"Cdot", 0x0010A}, // LATIN CAPITAL LETTER C WITH DOT ABOVE -+ {"cdot", 0x0010B}, // LATIN SMALL LETTER C WITH DOT ABOVE -+ {"cedil", 0x000B8}, // CEDILLA -+ {"Cedilla", 0x000B8}, // CEDILLA -+ {"cemptyv", 0x029B2}, // EMPTY SET WITH SMALL CIRCLE ABOVE -+ {"cent", 0x000A2}, // CENT SIGN -+ {"centerdot", 0x000B7}, // MIDDLE DOT -+ {"CenterDot", 0x000B7}, // MIDDLE DOT -+ {"Cfr", 0x0212D}, // BLACK-LETTER CAPITAL C -+ {"cfr", 0x1D520}, // MATHEMATICAL FRAKTUR SMALL C -+ {"CHcy", 0x00427}, // CYRILLIC CAPITAL LETTER CHE -+ {"chcy", 0x00447}, // CYRILLIC SMALL LETTER CHE -+ {"check", 0x02713}, // CHECK MARK -+ {"checkmark", 0x02713}, // CHECK MARK -+ {"Chi", 0x003A7}, // GREEK CAPITAL LETTER CHI -+ {"chi", 0x003C7}, // GREEK SMALL LETTER CHI -+ {"cir", 0x025CB}, // WHITE CIRCLE -+ {"circ", 0x002C6}, // MODIFIER LETTER CIRCUMFLEX ACCENT -+ {"circeq", 0x02257}, // RING EQUAL TO -+ {"circlearrowleft", 0x021BA}, // ANTICLOCKWISE OPEN CIRCLE ARROW -+ {"circlearrowright", 0x021BB}, // CLOCKWISE OPEN CIRCLE ARROW -+ {"circledast", 0x0229B}, // CIRCLED ASTERISK OPERATOR -+ {"circledcirc", 0x0229A}, // CIRCLED RING OPERATOR -+ {"circleddash", 0x0229D}, // CIRCLED DASH -+ {"CircleDot", 0x02299}, // CIRCLED DOT OPERATOR -+ {"circledR", 0x000AE}, // REGISTERED SIGN -+ {"circledS", 0x024C8}, // CIRCLED LATIN CAPITAL LETTER S -+ {"CircleMinus", 0x02296}, // CIRCLED MINUS -+ {"CirclePlus", 0x02295}, // CIRCLED PLUS -+ {"CircleTimes", 0x02297}, // CIRCLED TIMES -+ {"cire", 0x02257}, // RING EQUAL TO -+ {"cirE", 0x029C3}, // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT -+ {"cirfnint", 0x02A10}, // CIRCULATION FUNCTION -+ {"cirmid", 0x02AEF}, // VERTICAL LINE WITH CIRCLE ABOVE -+ {"cirscir", 0x029C2}, // CIRCLE WITH SMALL CIRCLE TO THE RIGHT -+ {"ClockwiseContourIntegral", 0x02232}, // CLOCKWISE CONTOUR INTEGRAL -+ {"CloseCurlyDoubleQuote", 0x0201D}, // RIGHT DOUBLE QUOTATION MARK -+ {"CloseCurlyQuote", 0x02019}, // RIGHT SINGLE QUOTATION MARK -+ {"clubs", 0x02663}, // BLACK CLUB SUIT -+ {"clubsuit", 0x02663}, // BLACK CLUB SUIT -+ {"colon", 0x0003A}, // COLON -+ {"Colon", 0x02237}, // PROPORTION -+ {"colone", 0x02254}, // COLON EQUALS -+ {"Colone", 0x02A74}, // DOUBLE COLON EQUAL -+ {"coloneq", 0x02254}, // COLON EQUALS -+ {"comma", 0x0002C}, // COMMA -+ {"commat", 0x00040}, // COMMERCIAL AT -+ {"comp", 0x02201}, // COMPLEMENT -+ {"compfn", 0x02218}, // RING OPERATOR -+ {"complement", 0x02201}, // COMPLEMENT -+ {"complexes", 0x02102}, // DOUBLE-STRUCK CAPITAL C -+ {"cong", 0x02245}, // APPROXIMATELY EQUAL TO -+ {"congdot", 0x02A6D}, // CONGRUENT WITH DOT ABOVE -+ {"Congruent", 0x02261}, // IDENTICAL TO -+ {"conint", 0x0222E}, // CONTOUR INTEGRAL -+ {"Conint", 0x0222F}, // SURFACE INTEGRAL -+ {"ContourIntegral", 0x0222E}, // CONTOUR INTEGRAL -+ {"Copf", 0x02102}, // DOUBLE-STRUCK CAPITAL C -+ {"copf", 0x1D554}, // MATHEMATICAL DOUBLE-STRUCK SMALL C -+ {"coprod", 0x02210}, // N-ARY COPRODUCT -+ {"Coproduct", 0x02210}, // N-ARY COPRODUCT -+ {"copy", 0x000A9}, // COPYRIGHT SIGN -+ {"COPY", 0x000A9}, // COPYRIGHT SIGN -+ {"copysr", 0x02117}, // SOUND RECORDING COPYRIGHT -+ {"CounterClockwiseContourIntegral", 0x02233}, // ANTICLOCKWISE CONTOUR INTEGRAL -+ {"crarr", 0x021B5}, // DOWNWARDS ARROW WITH CORNER LEFTWARDS -+ {"cross", 0x02717}, // BALLOT X -+ {"Cross", 0x02A2F}, // VECTOR OR CROSS PRODUCT -+ {"Cscr", 0x1D49E}, // MATHEMATICAL SCRIPT CAPITAL C -+ {"cscr", 0x1D4B8}, // MATHEMATICAL SCRIPT SMALL C -+ {"csub", 0x02ACF}, // CLOSED SUBSET -+ {"csube", 0x02AD1}, // CLOSED SUBSET OR EQUAL TO -+ {"csup", 0x02AD0}, // CLOSED SUPERSET -+ {"csupe", 0x02AD2}, // CLOSED SUPERSET OR EQUAL TO -+ {"ctdot", 0x022EF}, // MIDLINE HORIZONTAL ELLIPSIS -+ {"cudarrl", 0x02938}, // RIGHT-SIDE ARC CLOCKWISE ARROW -+ {"cudarrr", 0x02935}, // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS -+ {"cuepr", 0x022DE}, // EQUAL TO OR PRECEDES -+ {"cuesc", 0x022DF}, // EQUAL TO OR SUCCEEDS -+ {"cularr", 0x021B6}, // ANTICLOCKWISE TOP SEMICIRCLE ARROW -+ {"cularrp", 0x0293D}, // TOP ARC ANTICLOCKWISE ARROW WITH PLUS -+ {"cup", 0x0222A}, // UNION -+ {"Cup", 0x022D3}, // DOUBLE UNION -+ {"cupbrcap", 0x02A48}, // UNION ABOVE BAR ABOVE INTERSECTION -+ {"CupCap", 0x0224D}, // EQUIVALENT TO -+ {"cupcap", 0x02A46}, // UNION ABOVE INTERSECTION -+ {"cupcup", 0x02A4A}, // UNION BESIDE AND JOINED WITH UNION -+ {"cupdot", 0x0228D}, // MULTISET MULTIPLICATION -+ {"cupor", 0x02A45}, // UNION WITH LOGICAL OR -+// "cups", 0x0222A;0x0FE00}, // UNION with serifs -+ {"curarr", 0x021B7}, // CLOCKWISE TOP SEMICIRCLE ARROW -+ {"curarrm", 0x0293C}, // TOP ARC CLOCKWISE ARROW WITH MINUS -+ {"curlyeqprec", 0x022DE}, // EQUAL TO OR PRECEDES -+ {"curlyeqsucc", 0x022DF}, // EQUAL TO OR SUCCEEDS -+ {"curlyvee", 0x022CE}, // CURLY LOGICAL OR -+ {"curlywedge", 0x022CF}, // CURLY LOGICAL AND -+ {"curren", 0x000A4}, // CURRENCY SIGN -+ {"curvearrowleft", 0x021B6}, // ANTICLOCKWISE TOP SEMICIRCLE ARROW -+ {"curvearrowright", 0x021B7}, // CLOCKWISE TOP SEMICIRCLE ARROW -+ {"cuvee", 0x022CE}, // CURLY LOGICAL OR -+ {"cuwed", 0x022CF}, // CURLY LOGICAL AND -+ {"cwconint", 0x02232}, // CLOCKWISE CONTOUR INTEGRAL -+ {"cwint", 0x02231}, // CLOCKWISE INTEGRAL -+ {"cylcty", 0x0232D}, // CYLINDRICITY -+ {NULL, 0} - }; - - static NameId namesD[]={ -- "dagger", 0x02020, // DAGGER -- "Dagger", 0x02021, // DOUBLE DAGGER -- "daleth", 0x02138, // DALET SYMBOL -- "darr", 0x02193, // DOWNWARDS ARROW -- "Darr", 0x021A1, // DOWNWARDS TWO HEADED ARROW -- "dArr", 0x021D3, // DOWNWARDS DOUBLE ARROW -- "dash", 0x02010, // HYPHEN -- "dashv", 0x022A3, // LEFT TACK -- "Dashv", 0x02AE4, // VERTICAL BAR DOUBLE LEFT TURNSTILE -- "dbkarow", 0x0290F, // RIGHTWARDS TRIPLE DASH ARROW -- "dblac", 0x002DD, // DOUBLE ACUTE ACCENT -- "Dcaron", 0x0010E, // LATIN CAPITAL LETTER D WITH CARON -- "dcaron", 0x0010F, // LATIN SMALL LETTER D WITH CARON -- "Dcy", 0x00414, // CYRILLIC CAPITAL LETTER DE -- "dcy", 0x00434, // CYRILLIC SMALL LETTER DE -- "DD", 0x02145, // DOUBLE-STRUCK ITALIC CAPITAL D -- "dd", 0x02146, // DOUBLE-STRUCK ITALIC SMALL D -- "ddagger", 0x02021, // DOUBLE DAGGER -- "ddarr", 0x021CA, // DOWNWARDS PAIRED ARROWS -- "DDotrahd", 0x02911, // RIGHTWARDS ARROW WITH DOTTED STEM -- "ddotseq", 0x02A77, // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW -- "deg", 0x000B0, // DEGREE SIGN -- "Del", 0x02207, // NABLA -- "Delta", 0x00394, // GREEK CAPITAL LETTER DELTA -- "delta", 0x003B4, // GREEK SMALL LETTER DELTA -- "demptyv", 0x029B1, // EMPTY SET WITH OVERBAR -- "dfisht", 0x0297F, // DOWN FISH TAIL -- "Dfr", 0x1D507, // MATHEMATICAL FRAKTUR CAPITAL D -- "dfr", 0x1D521, // MATHEMATICAL FRAKTUR SMALL D -- "Dgr", 0x00394, // GREEK CAPITAL LETTER DELTA -- "dgr", 0x003B4, // GREEK SMALL LETTER DELTA -- "dHar", 0x02965, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -- "dharl", 0x021C3, // DOWNWARDS HARPOON WITH BARB LEFTWARDS -- "dharr", 0x021C2, // DOWNWARDS HARPOON WITH BARB RIGHTWARDS -- "DiacriticalAcute", 0x000B4, // ACUTE ACCENT -- "DiacriticalDot", 0x002D9, // DOT ABOVE -- "DiacriticalDoubleAcute", 0x002DD, // DOUBLE ACUTE ACCENT -- "DiacriticalGrave", 0x00060, // GRAVE ACCENT -- "DiacriticalTilde", 0x002DC, // SMALL TILDE -- "diam", 0x022C4, // DIAMOND OPERATOR -- "diamond", 0x022C4, // DIAMOND OPERATOR -- "Diamond", 0x022C4, // DIAMOND OPERATOR -- "diamondsuit", 0x02666, // BLACK DIAMOND SUIT -- "diams", 0x02666, // BLACK DIAMOND SUIT -- "die", 0x000A8, // DIAERESIS -- "DifferentialD", 0x02146, // DOUBLE-STRUCK ITALIC SMALL D -- "digamma", 0x003DD, // GREEK SMALL LETTER DIGAMMA -- "disin", 0x022F2, // ELEMENT OF WITH LONG HORIZONTAL STROKE -- "div", 0x000F7, // DIVISION SIGN -- "divide", 0x000F7, // DIVISION SIGN -- "divideontimes", 0x022C7, // DIVISION TIMES -- "divonx", 0x022C7, // DIVISION TIMES -- "DJcy", 0x00402, // CYRILLIC CAPITAL LETTER DJE -- "djcy", 0x00452, // CYRILLIC SMALL LETTER DJE -- "dlcorn", 0x0231E, // BOTTOM LEFT CORNER -- "dlcrop", 0x0230D, // BOTTOM LEFT CROP -- "dollar", 0x00024, // DOLLAR SIGN -- "Dopf", 0x1D53B, // MATHEMATICAL DOUBLE-STRUCK CAPITAL D -- "dopf", 0x1D555, // MATHEMATICAL DOUBLE-STRUCK SMALL D -- "Dot", 0x000A8, // DIAERESIS -- "dot", 0x002D9, // DOT ABOVE -- "DotDot", 0x020DC, // COMBINING FOUR DOTS ABOVE -- "doteq", 0x02250, // APPROACHES THE LIMIT -- "doteqdot", 0x02251, // GEOMETRICALLY EQUAL TO -- "DotEqual", 0x02250, // APPROACHES THE LIMIT -- "dotminus", 0x02238, // DOT MINUS -- "dotplus", 0x02214, // DOT PLUS -- "dotsquare", 0x022A1, // SQUARED DOT OPERATOR -- "doublebarwedge", 0x02306, // PERSPECTIVE -- "DoubleContourIntegral", 0x0222F, // SURFACE INTEGRAL -- "DoubleDot", 0x000A8, // DIAERESIS -- "DoubleDownArrow", 0x021D3, // DOWNWARDS DOUBLE ARROW -- "DoubleLeftArrow", 0x021D0, // LEFTWARDS DOUBLE ARROW -- "DoubleLeftRightArrow", 0x021D4, // LEFT RIGHT DOUBLE ARROW -- "DoubleLeftTee", 0x02AE4, // VERTICAL BAR DOUBLE LEFT TURNSTILE -- "DoubleLongLeftArrow", 0x027F8, // LONG LEFTWARDS DOUBLE ARROW -- "DoubleLongLeftRightArrow", 0x027FA, // LONG LEFT RIGHT DOUBLE ARROW -- "DoubleLongRightArrow", 0x027F9, // LONG RIGHTWARDS DOUBLE ARROW -- "DoubleRightArrow", 0x021D2, // RIGHTWARDS DOUBLE ARROW -- "DoubleRightTee", 0x022A8, // TRUE -- "DoubleUpArrow", 0x021D1, // UPWARDS DOUBLE ARROW -- "DoubleUpDownArrow", 0x021D5, // UP DOWN DOUBLE ARROW -- "DoubleVerticalBar", 0x02225, // PARALLEL TO -- "downarrow", 0x02193, // DOWNWARDS ARROW -- "DownArrow", 0x02193, // DOWNWARDS ARROW -- "Downarrow", 0x021D3, // DOWNWARDS DOUBLE ARROW -- "DownArrowBar", 0x02913, // DOWNWARDS ARROW TO BAR -- "DownArrowUpArrow", 0x021F5, // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW -- "DownBreve", 0x00311, // COMBINING INVERTED BREVE -- "downdownarrows", 0x021CA, // DOWNWARDS PAIRED ARROWS -- "downharpoonleft", 0x021C3, // DOWNWARDS HARPOON WITH BARB LEFTWARDS -- "downharpoonright", 0x021C2, // DOWNWARDS HARPOON WITH BARB RIGHTWARDS -- "DownLeftRightVector", 0x02950, // LEFT BARB DOWN RIGHT BARB DOWN HARPOON -- "DownLeftTeeVector", 0x0295E, // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR -- "DownLeftVector", 0x021BD, // LEFTWARDS HARPOON WITH BARB DOWNWARDS -- "DownLeftVectorBar", 0x02956, // LEFTWARDS HARPOON WITH BARB DOWN TO BAR -- "DownRightTeeVector", 0x0295F, // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR -- "DownRightVector", 0x021C1, // RIGHTWARDS HARPOON WITH BARB DOWNWARDS -- "DownRightVectorBar", 0x02957, // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR -- "DownTee", 0x022A4, // DOWN TACK -- "DownTeeArrow", 0x021A7, // DOWNWARDS ARROW FROM BAR -- "drbkarow", 0x02910, // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW -- "drcorn", 0x0231F, // BOTTOM RIGHT CORNER -- "drcrop", 0x0230C, // BOTTOM RIGHT CROP -- "Dscr", 0x1D49F, // MATHEMATICAL SCRIPT CAPITAL D -- "dscr", 0x1D4B9, // MATHEMATICAL SCRIPT SMALL D -- "DScy", 0x00405, // CYRILLIC CAPITAL LETTER DZE -- "dscy", 0x00455, // CYRILLIC SMALL LETTER DZE -- "dsol", 0x029F6, // SOLIDUS WITH OVERBAR -- "Dstrok", 0x00110, // LATIN CAPITAL LETTER D WITH STROKE -- "dstrok", 0x00111, // LATIN SMALL LETTER D WITH STROKE -- "dtdot", 0x022F1, // DOWN RIGHT DIAGONAL ELLIPSIS -- "dtri", 0x025BF, // WHITE DOWN-POINTING SMALL TRIANGLE -- "dtrif", 0x025BE, // BLACK DOWN-POINTING SMALL TRIANGLE -- "duarr", 0x021F5, // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW -- "duhar", 0x0296F, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -- "dwangle", 0x029A6, // OBLIQUE ANGLE OPENING UP -- "DZcy", 0x0040F, // CYRILLIC CAPITAL LETTER DZHE -- "dzcy", 0x0045F, // CYRILLIC SMALL LETTER DZHE -- "dzigrarr", 0x027FF, // LONG RIGHTWARDS SQUIGGLE ARROW -- NULL, 0 -+ {"dagger", 0x02020}, // DAGGER -+ {"Dagger", 0x02021}, // DOUBLE DAGGER -+ {"daleth", 0x02138}, // DALET SYMBOL -+ {"darr", 0x02193}, // DOWNWARDS ARROW -+ {"Darr", 0x021A1}, // DOWNWARDS TWO HEADED ARROW -+ {"dArr", 0x021D3}, // DOWNWARDS DOUBLE ARROW -+ {"dash", 0x02010}, // HYPHEN -+ {"dashv", 0x022A3}, // LEFT TACK -+ {"Dashv", 0x02AE4}, // VERTICAL BAR DOUBLE LEFT TURNSTILE -+ {"dbkarow", 0x0290F}, // RIGHTWARDS TRIPLE DASH ARROW -+ {"dblac", 0x002DD}, // DOUBLE ACUTE ACCENT -+ {"Dcaron", 0x0010E}, // LATIN CAPITAL LETTER D WITH CARON -+ {"dcaron", 0x0010F}, // LATIN SMALL LETTER D WITH CARON -+ {"Dcy", 0x00414}, // CYRILLIC CAPITAL LETTER DE -+ {"dcy", 0x00434}, // CYRILLIC SMALL LETTER DE -+ {"DD", 0x02145}, // DOUBLE-STRUCK ITALIC CAPITAL D -+ {"dd", 0x02146}, // DOUBLE-STRUCK ITALIC SMALL D -+ {"ddagger", 0x02021}, // DOUBLE DAGGER -+ {"ddarr", 0x021CA}, // DOWNWARDS PAIRED ARROWS -+ {"DDotrahd", 0x02911}, // RIGHTWARDS ARROW WITH DOTTED STEM -+ {"ddotseq", 0x02A77}, // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW -+ {"deg", 0x000B0}, // DEGREE SIGN -+ {"Del", 0x02207}, // NABLA -+ {"Delta", 0x00394}, // GREEK CAPITAL LETTER DELTA -+ {"delta", 0x003B4}, // GREEK SMALL LETTER DELTA -+ {"demptyv", 0x029B1}, // EMPTY SET WITH OVERBAR -+ {"dfisht", 0x0297F}, // DOWN FISH TAIL -+ {"Dfr", 0x1D507}, // MATHEMATICAL FRAKTUR CAPITAL D -+ {"dfr", 0x1D521}, // MATHEMATICAL FRAKTUR SMALL D -+ {"Dgr", 0x00394}, // GREEK CAPITAL LETTER DELTA -+ {"dgr", 0x003B4}, // GREEK SMALL LETTER DELTA -+ {"dHar", 0x02965}, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -+ {"dharl", 0x021C3}, // DOWNWARDS HARPOON WITH BARB LEFTWARDS -+ {"dharr", 0x021C2}, // DOWNWARDS HARPOON WITH BARB RIGHTWARDS -+ {"DiacriticalAcute", 0x000B4}, // ACUTE ACCENT -+ {"DiacriticalDot", 0x002D9}, // DOT ABOVE -+ {"DiacriticalDoubleAcute", 0x002DD}, // DOUBLE ACUTE ACCENT -+ {"DiacriticalGrave", 0x00060}, // GRAVE ACCENT -+ {"DiacriticalTilde", 0x002DC}, // SMALL TILDE -+ {"diam", 0x022C4}, // DIAMOND OPERATOR -+ {"diamond", 0x022C4}, // DIAMOND OPERATOR -+ {"Diamond", 0x022C4}, // DIAMOND OPERATOR -+ {"diamondsuit", 0x02666}, // BLACK DIAMOND SUIT -+ {"diams", 0x02666}, // BLACK DIAMOND SUIT -+ {"die", 0x000A8}, // DIAERESIS -+ {"DifferentialD", 0x02146}, // DOUBLE-STRUCK ITALIC SMALL D -+ {"digamma", 0x003DD}, // GREEK SMALL LETTER DIGAMMA -+ {"disin", 0x022F2}, // ELEMENT OF WITH LONG HORIZONTAL STROKE -+ {"div", 0x000F7}, // DIVISION SIGN -+ {"divide", 0x000F7}, // DIVISION SIGN -+ {"divideontimes", 0x022C7}, // DIVISION TIMES -+ {"divonx", 0x022C7}, // DIVISION TIMES -+ {"DJcy", 0x00402}, // CYRILLIC CAPITAL LETTER DJE -+ {"djcy", 0x00452}, // CYRILLIC SMALL LETTER DJE -+ {"dlcorn", 0x0231E}, // BOTTOM LEFT CORNER -+ {"dlcrop", 0x0230D}, // BOTTOM LEFT CROP -+ {"dollar", 0x00024}, // DOLLAR SIGN -+ {"Dopf", 0x1D53B}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL D -+ {"dopf", 0x1D555}, // MATHEMATICAL DOUBLE-STRUCK SMALL D -+ {"Dot", 0x000A8}, // DIAERESIS -+ {"dot", 0x002D9}, // DOT ABOVE -+ {"DotDot", 0x020DC}, // COMBINING FOUR DOTS ABOVE -+ {"doteq", 0x02250}, // APPROACHES THE LIMIT -+ {"doteqdot", 0x02251}, // GEOMETRICALLY EQUAL TO -+ {"DotEqual", 0x02250}, // APPROACHES THE LIMIT -+ {"dotminus", 0x02238}, // DOT MINUS -+ {"dotplus", 0x02214}, // DOT PLUS -+ {"dotsquare", 0x022A1}, // SQUARED DOT OPERATOR -+ {"doublebarwedge", 0x02306}, // PERSPECTIVE -+ {"DoubleContourIntegral", 0x0222F}, // SURFACE INTEGRAL -+ {"DoubleDot", 0x000A8}, // DIAERESIS -+ {"DoubleDownArrow", 0x021D3}, // DOWNWARDS DOUBLE ARROW -+ {"DoubleLeftArrow", 0x021D0}, // LEFTWARDS DOUBLE ARROW -+ {"DoubleLeftRightArrow", 0x021D4}, // LEFT RIGHT DOUBLE ARROW -+ {"DoubleLeftTee", 0x02AE4}, // VERTICAL BAR DOUBLE LEFT TURNSTILE -+ {"DoubleLongLeftArrow", 0x027F8}, // LONG LEFTWARDS DOUBLE ARROW -+ {"DoubleLongLeftRightArrow", 0x027FA}, // LONG LEFT RIGHT DOUBLE ARROW -+ {"DoubleLongRightArrow", 0x027F9}, // LONG RIGHTWARDS DOUBLE ARROW -+ {"DoubleRightArrow", 0x021D2}, // RIGHTWARDS DOUBLE ARROW -+ {"DoubleRightTee", 0x022A8}, // TRUE -+ {"DoubleUpArrow", 0x021D1}, // UPWARDS DOUBLE ARROW -+ {"DoubleUpDownArrow", 0x021D5}, // UP DOWN DOUBLE ARROW -+ {"DoubleVerticalBar", 0x02225}, // PARALLEL TO -+ {"downarrow", 0x02193}, // DOWNWARDS ARROW -+ {"DownArrow", 0x02193}, // DOWNWARDS ARROW -+ {"Downarrow", 0x021D3}, // DOWNWARDS DOUBLE ARROW -+ {"DownArrowBar", 0x02913}, // DOWNWARDS ARROW TO BAR -+ {"DownArrowUpArrow", 0x021F5}, // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW -+ {"DownBreve", 0x00311}, // COMBINING INVERTED BREVE -+ {"downdownarrows", 0x021CA}, // DOWNWARDS PAIRED ARROWS -+ {"downharpoonleft", 0x021C3}, // DOWNWARDS HARPOON WITH BARB LEFTWARDS -+ {"downharpoonright", 0x021C2}, // DOWNWARDS HARPOON WITH BARB RIGHTWARDS -+ {"DownLeftRightVector", 0x02950}, // LEFT BARB DOWN RIGHT BARB DOWN HARPOON -+ {"DownLeftTeeVector", 0x0295E}, // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR -+ {"DownLeftVector", 0x021BD}, // LEFTWARDS HARPOON WITH BARB DOWNWARDS -+ {"DownLeftVectorBar", 0x02956}, // LEFTWARDS HARPOON WITH BARB DOWN TO BAR -+ {"DownRightTeeVector", 0x0295F}, // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR -+ {"DownRightVector", 0x021C1}, // RIGHTWARDS HARPOON WITH BARB DOWNWARDS -+ {"DownRightVectorBar", 0x02957}, // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR -+ {"DownTee", 0x022A4}, // DOWN TACK -+ {"DownTeeArrow", 0x021A7}, // DOWNWARDS ARROW FROM BAR -+ {"drbkarow", 0x02910}, // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW -+ {"drcorn", 0x0231F}, // BOTTOM RIGHT CORNER -+ {"drcrop", 0x0230C}, // BOTTOM RIGHT CROP -+ {"Dscr", 0x1D49F}, // MATHEMATICAL SCRIPT CAPITAL D -+ {"dscr", 0x1D4B9}, // MATHEMATICAL SCRIPT SMALL D -+ {"DScy", 0x00405}, // CYRILLIC CAPITAL LETTER DZE -+ {"dscy", 0x00455}, // CYRILLIC SMALL LETTER DZE -+ {"dsol", 0x029F6}, // SOLIDUS WITH OVERBAR -+ {"Dstrok", 0x00110}, // LATIN CAPITAL LETTER D WITH STROKE -+ {"dstrok", 0x00111}, // LATIN SMALL LETTER D WITH STROKE -+ {"dtdot", 0x022F1}, // DOWN RIGHT DIAGONAL ELLIPSIS -+ {"dtri", 0x025BF}, // WHITE DOWN-POINTING SMALL TRIANGLE -+ {"dtrif", 0x025BE}, // BLACK DOWN-POINTING SMALL TRIANGLE -+ {"duarr", 0x021F5}, // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW -+ {"duhar", 0x0296F}, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -+ {"dwangle", 0x029A6}, // OBLIQUE ANGLE OPENING UP -+ {"DZcy", 0x0040F}, // CYRILLIC CAPITAL LETTER DZHE -+ {"dzcy", 0x0045F}, // CYRILLIC SMALL LETTER DZHE -+ {"dzigrarr", 0x027FF}, // LONG RIGHTWARDS SQUIGGLE ARROW -+ {NULL, 0} - }; - - static NameId namesE[]={ -- "Eacgr", 0x00388, // GREEK CAPITAL LETTER EPSILON WITH TONOS -- "eacgr", 0x003AD, // GREEK SMALL LETTER EPSILON WITH TONOS -- "Eacute", 0x000C9, // LATIN CAPITAL LETTER E WITH ACUTE -- "eacute", 0x000E9, // LATIN SMALL LETTER E WITH ACUTE -- "easter", 0x02A6E, // EQUALS WITH ASTERISK -- "Ecaron", 0x0011A, // LATIN CAPITAL LETTER E WITH CARON -- "ecaron", 0x0011B, // LATIN SMALL LETTER E WITH CARON -- "ecir", 0x02256, // RING IN EQUAL TO -- "Ecirc", 0x000CA, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX -- "ecirc", 0x000EA, // LATIN SMALL LETTER E WITH CIRCUMFLEX -- "ecolon", 0x02255, // EQUALS COLON -- "Ecy", 0x0042D, // CYRILLIC CAPITAL LETTER E -- "ecy", 0x0044D, // CYRILLIC SMALL LETTER E -- "eDDot", 0x02A77, // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW -- "Edot", 0x00116, // LATIN CAPITAL LETTER E WITH DOT ABOVE -- "edot", 0x00117, // LATIN SMALL LETTER E WITH DOT ABOVE -- "eDot", 0x02251, // GEOMETRICALLY EQUAL TO -- "ee", 0x02147, // DOUBLE-STRUCK ITALIC SMALL E -- "EEacgr", 0x00389, // GREEK CAPITAL LETTER ETA WITH TONOS -- "eeacgr", 0x003AE, // GREEK SMALL LETTER ETA WITH TONOS -- "EEgr", 0x00397, // GREEK CAPITAL LETTER ETA -- "eegr", 0x003B7, // GREEK SMALL LETTER ETA -- "efDot", 0x02252, // APPROXIMATELY EQUAL TO OR THE IMAGE OF -- "Efr", 0x1D508, // MATHEMATICAL FRAKTUR CAPITAL E -- "efr", 0x1D522, // MATHEMATICAL FRAKTUR SMALL E -- "eg", 0x02A9A, // DOUBLE-LINE EQUAL TO OR GREATER-THAN -- "Egr", 0x00395, // GREEK CAPITAL LETTER EPSILON -- "egr", 0x003B5, // GREEK SMALL LETTER EPSILON -- "Egrave", 0x000C8, // LATIN CAPITAL LETTER E WITH GRAVE -- "egrave", 0x000E8, // LATIN SMALL LETTER E WITH GRAVE -- "egs", 0x02A96, // SLANTED EQUAL TO OR GREATER-THAN -- "egsdot", 0x02A98, // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE -- "el", 0x02A99, // DOUBLE-LINE EQUAL TO OR LESS-THAN -- "Element", 0x02208, // ELEMENT OF -- "elinters", 0x023E7, // ELECTRICAL INTERSECTION -- "ell", 0x02113, // SCRIPT SMALL L -- "els", 0x02A95, // SLANTED EQUAL TO OR LESS-THAN -- "elsdot", 0x02A97, // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE -- "Emacr", 0x00112, // LATIN CAPITAL LETTER E WITH MACRON -- "emacr", 0x00113, // LATIN SMALL LETTER E WITH MACRON -- "empty", 0x02205, // EMPTY SET -- "emptyset", 0x02205, // EMPTY SET -- "EmptySmallSquare", 0x025FB, // WHITE MEDIUM SQUARE -- "emptyv", 0x02205, // EMPTY SET -- "EmptyVerySmallSquare", 0x025AB, // WHITE SMALL SQUARE -- "emsp", 0x02003, // EM SPACE -- "emsp13", 0x02004, // THREE-PER-EM SPACE -- "emsp14", 0x02005, // FOUR-PER-EM SPACE -- "ENG", 0x0014A, // LATIN CAPITAL LETTER ENG -- "eng", 0x0014B, // LATIN SMALL LETTER ENG -- "ensp", 0x02002, // EN SPACE -- "Eogon", 0x00118, // LATIN CAPITAL LETTER E WITH OGONEK -- "eogon", 0x00119, // LATIN SMALL LETTER E WITH OGONEK -- "Eopf", 0x1D53C, // MATHEMATICAL DOUBLE-STRUCK CAPITAL E -- "eopf", 0x1D556, // MATHEMATICAL DOUBLE-STRUCK SMALL E -- "epar", 0x022D5, // EQUAL AND PARALLEL TO -- "eparsl", 0x029E3, // EQUALS SIGN AND SLANTED PARALLEL -- "eplus", 0x02A71, // EQUALS SIGN ABOVE PLUS SIGN -- "epsi", 0x003B5, // GREEK SMALL LETTER EPSILON -- "Epsilon", 0x00395, // GREEK CAPITAL LETTER EPSILON -- "epsilon", 0x003B5, // GREEK SMALL LETTER EPSILON -- "epsiv", 0x003F5, // GREEK LUNATE EPSILON SYMBOL -- "eqcirc", 0x02256, // RING IN EQUAL TO -- "eqcolon", 0x02255, // EQUALS COLON -- "eqsim", 0x02242, // MINUS TILDE -- "eqslantgtr", 0x02A96, // SLANTED EQUAL TO OR GREATER-THAN -- "eqslantless", 0x02A95, // SLANTED EQUAL TO OR LESS-THAN -- "Equal", 0x02A75, // TWO CONSECUTIVE EQUALS SIGNS -- "equals", 0x0003D, // EQUALS SIGN -- "EqualTilde", 0x02242, // MINUS TILDE -- "equest", 0x0225F, // QUESTIONED EQUAL TO -- "Equilibrium", 0x021CC, // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -- "equiv", 0x02261, // IDENTICAL TO -- "equivDD", 0x02A78, // EQUIVALENT WITH FOUR DOTS ABOVE -- "eqvparsl", 0x029E5, // IDENTICAL TO AND SLANTED PARALLEL -- "erarr", 0x02971, // EQUALS SIGN ABOVE RIGHTWARDS ARROW -- "erDot", 0x02253, // IMAGE OF OR APPROXIMATELY EQUAL TO -- "escr", 0x0212F, // SCRIPT SMALL E -- "Escr", 0x02130, // SCRIPT CAPITAL E -- "esdot", 0x02250, // APPROACHES THE LIMIT -- "esim", 0x02242, // MINUS TILDE -- "Esim", 0x02A73, // EQUALS SIGN ABOVE TILDE OPERATOR -- "Eta", 0x00397, // GREEK CAPITAL LETTER ETA -- "eta", 0x003B7, // GREEK SMALL LETTER ETA -- "ETH", 0x000D0, // LATIN CAPITAL LETTER ETH -- "eth", 0x000F0, // LATIN SMALL LETTER ETH -- "Euml", 0x000CB, // LATIN CAPITAL LETTER E WITH DIAERESIS -- "euml", 0x000EB, // LATIN SMALL LETTER E WITH DIAERESIS -- "euro", 0x020AC, // EURO SIGN -- "excl", 0x00021, // EXCLAMATION MARK -- "exist", 0x02203, // THERE EXISTS -- "Exists", 0x02203, // THERE EXISTS -- "expectation", 0x02130, // SCRIPT CAPITAL E -- "exponentiale", 0x02147, // DOUBLE-STRUCK ITALIC SMALL E -- "ExponentialE", 0x02147, // DOUBLE-STRUCK ITALIC SMALL E -- NULL, 0 -+ {"Eacgr", 0x00388}, // GREEK CAPITAL LETTER EPSILON WITH TONOS -+ {"eacgr", 0x003AD}, // GREEK SMALL LETTER EPSILON WITH TONOS -+ {"Eacute", 0x000C9}, // LATIN CAPITAL LETTER E WITH ACUTE -+ {"eacute", 0x000E9}, // LATIN SMALL LETTER E WITH ACUTE -+ {"easter", 0x02A6E}, // EQUALS WITH ASTERISK -+ {"Ecaron", 0x0011A}, // LATIN CAPITAL LETTER E WITH CARON -+ {"ecaron", 0x0011B}, // LATIN SMALL LETTER E WITH CARON -+ {"ecir", 0x02256}, // RING IN EQUAL TO -+ {"Ecirc", 0x000CA}, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX -+ {"ecirc", 0x000EA}, // LATIN SMALL LETTER E WITH CIRCUMFLEX -+ {"ecolon", 0x02255}, // EQUALS COLON -+ {"Ecy", 0x0042D}, // CYRILLIC CAPITAL LETTER E -+ {"ecy", 0x0044D}, // CYRILLIC SMALL LETTER E -+ {"eDDot", 0x02A77}, // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW -+ {"Edot", 0x00116}, // LATIN CAPITAL LETTER E WITH DOT ABOVE -+ {"edot", 0x00117}, // LATIN SMALL LETTER E WITH DOT ABOVE -+ {"eDot", 0x02251}, // GEOMETRICALLY EQUAL TO -+ {"ee", 0x02147}, // DOUBLE-STRUCK ITALIC SMALL E -+ {"EEacgr", 0x00389}, // GREEK CAPITAL LETTER ETA WITH TONOS -+ {"eeacgr", 0x003AE}, // GREEK SMALL LETTER ETA WITH TONOS -+ {"EEgr", 0x00397}, // GREEK CAPITAL LETTER ETA -+ {"eegr", 0x003B7}, // GREEK SMALL LETTER ETA -+ {"efDot", 0x02252}, // APPROXIMATELY EQUAL TO OR THE IMAGE OF -+ {"Efr", 0x1D508}, // MATHEMATICAL FRAKTUR CAPITAL E -+ {"efr", 0x1D522}, // MATHEMATICAL FRAKTUR SMALL E -+ {"eg", 0x02A9A}, // DOUBLE-LINE EQUAL TO OR GREATER-THAN -+ {"Egr", 0x00395}, // GREEK CAPITAL LETTER EPSILON -+ {"egr", 0x003B5}, // GREEK SMALL LETTER EPSILON -+ {"Egrave", 0x000C8}, // LATIN CAPITAL LETTER E WITH GRAVE -+ {"egrave", 0x000E8}, // LATIN SMALL LETTER E WITH GRAVE -+ {"egs", 0x02A96}, // SLANTED EQUAL TO OR GREATER-THAN -+ {"egsdot", 0x02A98}, // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE -+ {"el", 0x02A99}, // DOUBLE-LINE EQUAL TO OR LESS-THAN -+ {"Element", 0x02208}, // ELEMENT OF -+ {"elinters", 0x023E7}, // ELECTRICAL INTERSECTION -+ {"ell", 0x02113}, // SCRIPT SMALL L -+ {"els", 0x02A95}, // SLANTED EQUAL TO OR LESS-THAN -+ {"elsdot", 0x02A97}, // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE -+ {"Emacr", 0x00112}, // LATIN CAPITAL LETTER E WITH MACRON -+ {"emacr", 0x00113}, // LATIN SMALL LETTER E WITH MACRON -+ {"empty", 0x02205}, // EMPTY SET -+ {"emptyset", 0x02205}, // EMPTY SET -+ {"EmptySmallSquare", 0x025FB}, // WHITE MEDIUM SQUARE -+ {"emptyv", 0x02205}, // EMPTY SET -+ {"EmptyVerySmallSquare", 0x025AB}, // WHITE SMALL SQUARE -+ {"emsp", 0x02003}, // EM SPACE -+ {"emsp13", 0x02004}, // THREE-PER-EM SPACE -+ {"emsp14", 0x02005}, // FOUR-PER-EM SPACE -+ {"ENG", 0x0014A}, // LATIN CAPITAL LETTER ENG -+ {"eng", 0x0014B}, // LATIN SMALL LETTER ENG -+ {"ensp", 0x02002}, // EN SPACE -+ {"Eogon", 0x00118}, // LATIN CAPITAL LETTER E WITH OGONEK -+ {"eogon", 0x00119}, // LATIN SMALL LETTER E WITH OGONEK -+ {"Eopf", 0x1D53C}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL E -+ {"eopf", 0x1D556}, // MATHEMATICAL DOUBLE-STRUCK SMALL E -+ {"epar", 0x022D5}, // EQUAL AND PARALLEL TO -+ {"eparsl", 0x029E3}, // EQUALS SIGN AND SLANTED PARALLEL -+ {"eplus", 0x02A71}, // EQUALS SIGN ABOVE PLUS SIGN -+ {"epsi", 0x003B5}, // GREEK SMALL LETTER EPSILON -+ {"Epsilon", 0x00395}, // GREEK CAPITAL LETTER EPSILON -+ {"epsilon", 0x003B5}, // GREEK SMALL LETTER EPSILON -+ {"epsiv", 0x003F5}, // GREEK LUNATE EPSILON SYMBOL -+ {"eqcirc", 0x02256}, // RING IN EQUAL TO -+ {"eqcolon", 0x02255}, // EQUALS COLON -+ {"eqsim", 0x02242}, // MINUS TILDE -+ {"eqslantgtr", 0x02A96}, // SLANTED EQUAL TO OR GREATER-THAN -+ {"eqslantless", 0x02A95}, // SLANTED EQUAL TO OR LESS-THAN -+ {"Equal", 0x02A75}, // TWO CONSECUTIVE EQUALS SIGNS -+ {"equals", 0x0003D}, // EQUALS SIGN -+ {"EqualTilde", 0x02242}, // MINUS TILDE -+ {"equest", 0x0225F}, // QUESTIONED EQUAL TO -+ {"Equilibrium", 0x021CC}, // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -+ {"equiv", 0x02261}, // IDENTICAL TO -+ {"equivDD", 0x02A78}, // EQUIVALENT WITH FOUR DOTS ABOVE -+ {"eqvparsl", 0x029E5}, // IDENTICAL TO AND SLANTED PARALLEL -+ {"erarr", 0x02971}, // EQUALS SIGN ABOVE RIGHTWARDS ARROW -+ {"erDot", 0x02253}, // IMAGE OF OR APPROXIMATELY EQUAL TO -+ {"escr", 0x0212F}, // SCRIPT SMALL E -+ {"Escr", 0x02130}, // SCRIPT CAPITAL E -+ {"esdot", 0x02250}, // APPROACHES THE LIMIT -+ {"esim", 0x02242}, // MINUS TILDE -+ {"Esim", 0x02A73}, // EQUALS SIGN ABOVE TILDE OPERATOR -+ {"Eta", 0x00397}, // GREEK CAPITAL LETTER ETA -+ {"eta", 0x003B7}, // GREEK SMALL LETTER ETA -+ {"ETH", 0x000D0}, // LATIN CAPITAL LETTER ETH -+ {"eth", 0x000F0}, // LATIN SMALL LETTER ETH -+ {"Euml", 0x000CB}, // LATIN CAPITAL LETTER E WITH DIAERESIS -+ {"euml", 0x000EB}, // LATIN SMALL LETTER E WITH DIAERESIS -+ {"euro", 0x020AC}, // EURO SIGN -+ {"excl", 0x00021}, // EXCLAMATION MARK -+ {"exist", 0x02203}, // THERE EXISTS -+ {"Exists", 0x02203}, // THERE EXISTS -+ {"expectation", 0x02130}, // SCRIPT CAPITAL E -+ {"exponentiale", 0x02147}, // DOUBLE-STRUCK ITALIC SMALL E -+ {"ExponentialE", 0x02147}, // DOUBLE-STRUCK ITALIC SMALL E -+ {NULL, 0} - }; - - static NameId namesF[]={ -- "fallingdotseq", 0x02252, // APPROXIMATELY EQUAL TO OR THE IMAGE OF -- "Fcy", 0x00424, // CYRILLIC CAPITAL LETTER EF -- "fcy", 0x00444, // CYRILLIC SMALL LETTER EF -- "female", 0x02640, // FEMALE SIGN -- "ffilig", 0x0FB03, // LATIN SMALL LIGATURE FFI -- "fflig", 0x0FB00, // LATIN SMALL LIGATURE FF -- "ffllig", 0x0FB04, // LATIN SMALL LIGATURE FFL -- "Ffr", 0x1D509, // MATHEMATICAL FRAKTUR CAPITAL F -- "ffr", 0x1D523, // MATHEMATICAL FRAKTUR SMALL F -- "filig", 0x0FB01, // LATIN SMALL LIGATURE FI -- "FilledSmallSquare", 0x025FC, // BLACK MEDIUM SQUARE -- "FilledVerySmallSquare", 0x025AA, // BLACK SMALL SQUARE --// "fjlig", 0x00066;0x0006A, // fj ligature -- "flat", 0x0266D, // MUSIC FLAT SIGN -- "fllig", 0x0FB02, // LATIN SMALL LIGATURE FL -- "fltns", 0x025B1, // WHITE PARALLELOGRAM -- "fnof", 0x00192, // LATIN SMALL LETTER F WITH HOOK -- "Fopf", 0x1D53D, // MATHEMATICAL DOUBLE-STRUCK CAPITAL F -- "fopf", 0x1D557, // MATHEMATICAL DOUBLE-STRUCK SMALL F -- "forall", 0x02200, // FOR ALL -- "ForAll", 0x02200, // FOR ALL -- "fork", 0x022D4, // PITCHFORK -- "forkv", 0x02AD9, // ELEMENT OF OPENING DOWNWARDS -- "Fouriertrf", 0x02131, // SCRIPT CAPITAL F -- "fpartint", 0x02A0D, // FINITE PART INTEGRAL -- "frac12", 0x000BD, // VULGAR FRACTION ONE HALF -- "frac13", 0x02153, // VULGAR FRACTION ONE THIRD -- "frac14", 0x000BC, // VULGAR FRACTION ONE QUARTER -- "frac15", 0x02155, // VULGAR FRACTION ONE FIFTH -- "frac16", 0x02159, // VULGAR FRACTION ONE SIXTH -- "frac18", 0x0215B, // VULGAR FRACTION ONE EIGHTH -- "frac23", 0x02154, // VULGAR FRACTION TWO THIRDS -- "frac25", 0x02156, // VULGAR FRACTION TWO FIFTHS -- "frac34", 0x000BE, // VULGAR FRACTION THREE QUARTERS -- "frac35", 0x02157, // VULGAR FRACTION THREE FIFTHS -- "frac38", 0x0215C, // VULGAR FRACTION THREE EIGHTHS -- "frac45", 0x02158, // VULGAR FRACTION FOUR FIFTHS -- "frac56", 0x0215A, // VULGAR FRACTION FIVE SIXTHS -- "frac58", 0x0215D, // VULGAR FRACTION FIVE EIGHTHS -- "frac78", 0x0215E, // VULGAR FRACTION SEVEN EIGHTHS -- "frasl", 0x02044, // FRACTION SLASH -- "frown", 0x02322, // FROWN -- "Fscr", 0x02131, // SCRIPT CAPITAL F -- "fscr", 0x1D4BB, // MATHEMATICAL SCRIPT SMALL F -- NULL, 0 -+ {"fallingdotseq", 0x02252}, // APPROXIMATELY EQUAL TO OR THE IMAGE OF -+ {"Fcy", 0x00424}, // CYRILLIC CAPITAL LETTER EF -+ {"fcy", 0x00444}, // CYRILLIC SMALL LETTER EF -+ {"female", 0x02640}, // FEMALE SIGN -+ {"ffilig", 0x0FB03}, // LATIN SMALL LIGATURE FFI -+ {"fflig", 0x0FB00}, // LATIN SMALL LIGATURE FF -+ {"ffllig", 0x0FB04}, // LATIN SMALL LIGATURE FFL -+ {"Ffr", 0x1D509}, // MATHEMATICAL FRAKTUR CAPITAL F -+ {"ffr", 0x1D523}, // MATHEMATICAL FRAKTUR SMALL F -+ {"filig", 0x0FB01}, // LATIN SMALL LIGATURE FI -+ {"FilledSmallSquare", 0x025FC}, // BLACK MEDIUM SQUARE -+ {"FilledVerySmallSquare", 0x025AA}, // BLACK SMALL SQUARE -+// "fjlig", 0x00066;0x0006A}, // fj ligature -+ {"flat", 0x0266D}, // MUSIC FLAT SIGN -+ {"fllig", 0x0FB02}, // LATIN SMALL LIGATURE FL -+ {"fltns", 0x025B1}, // WHITE PARALLELOGRAM -+ {"fnof", 0x00192}, // LATIN SMALL LETTER F WITH HOOK -+ {"Fopf", 0x1D53D}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL F -+ {"fopf", 0x1D557}, // MATHEMATICAL DOUBLE-STRUCK SMALL F -+ {"forall", 0x02200}, // FOR ALL -+ {"ForAll", 0x02200}, // FOR ALL -+ {"fork", 0x022D4}, // PITCHFORK -+ {"forkv", 0x02AD9}, // ELEMENT OF OPENING DOWNWARDS -+ {"Fouriertrf", 0x02131}, // SCRIPT CAPITAL F -+ {"fpartint", 0x02A0D}, // FINITE PART INTEGRAL -+ {"frac12", 0x000BD}, // VULGAR FRACTION ONE HALF -+ {"frac13", 0x02153}, // VULGAR FRACTION ONE THIRD -+ {"frac14", 0x000BC}, // VULGAR FRACTION ONE QUARTER -+ {"frac15", 0x02155}, // VULGAR FRACTION ONE FIFTH -+ {"frac16", 0x02159}, // VULGAR FRACTION ONE SIXTH -+ {"frac18", 0x0215B}, // VULGAR FRACTION ONE EIGHTH -+ {"frac23", 0x02154}, // VULGAR FRACTION TWO THIRDS -+ {"frac25", 0x02156}, // VULGAR FRACTION TWO FIFTHS -+ {"frac34", 0x000BE}, // VULGAR FRACTION THREE QUARTERS -+ {"frac35", 0x02157}, // VULGAR FRACTION THREE FIFTHS -+ {"frac38", 0x0215C}, // VULGAR FRACTION THREE EIGHTHS -+ {"frac45", 0x02158}, // VULGAR FRACTION FOUR FIFTHS -+ {"frac56", 0x0215A}, // VULGAR FRACTION FIVE SIXTHS -+ {"frac58", 0x0215D}, // VULGAR FRACTION FIVE EIGHTHS -+ {"frac78", 0x0215E}, // VULGAR FRACTION SEVEN EIGHTHS -+ {"frasl", 0x02044}, // FRACTION SLASH -+ {"frown", 0x02322}, // FROWN -+ {"Fscr", 0x02131}, // SCRIPT CAPITAL F -+ {"fscr", 0x1D4BB}, // MATHEMATICAL SCRIPT SMALL F -+ {NULL, 0} - }; - - static NameId namesG[]={ -- "gacute", 0x001F5, // LATIN SMALL LETTER G WITH ACUTE -- "Gamma", 0x00393, // GREEK CAPITAL LETTER GAMMA -- "gamma", 0x003B3, // GREEK SMALL LETTER GAMMA -- "Gammad", 0x003DC, // GREEK LETTER DIGAMMA -- "gammad", 0x003DD, // GREEK SMALL LETTER DIGAMMA -- "gap", 0x02A86, // GREATER-THAN OR APPROXIMATE -- "Gbreve", 0x0011E, // LATIN CAPITAL LETTER G WITH BREVE -- "gbreve", 0x0011F, // LATIN SMALL LETTER G WITH BREVE -- "Gcedil", 0x00122, // LATIN CAPITAL LETTER G WITH CEDILLA -- "Gcirc", 0x0011C, // LATIN CAPITAL LETTER G WITH CIRCUMFLEX -- "gcirc", 0x0011D, // LATIN SMALL LETTER G WITH CIRCUMFLEX -- "Gcy", 0x00413, // CYRILLIC CAPITAL LETTER GHE -- "gcy", 0x00433, // CYRILLIC SMALL LETTER GHE -- "Gdot", 0x00120, // LATIN CAPITAL LETTER G WITH DOT ABOVE -- "gdot", 0x00121, // LATIN SMALL LETTER G WITH DOT ABOVE -- "ge", 0x02265, // GREATER-THAN OR EQUAL TO -- "gE", 0x02267, // GREATER-THAN OVER EQUAL TO -- "gel", 0x022DB, // GREATER-THAN EQUAL TO OR LESS-THAN -- "gEl", 0x02A8C, // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN -- "geq", 0x02265, // GREATER-THAN OR EQUAL TO -- "geqq", 0x02267, // GREATER-THAN OVER EQUAL TO -- "geqslant", 0x02A7E, // GREATER-THAN OR SLANTED EQUAL TO -- "ges", 0x02A7E, // GREATER-THAN OR SLANTED EQUAL TO -- "gescc", 0x02AA9, // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL -- "gesdot", 0x02A80, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE -- "gesdoto", 0x02A82, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE -- "gesdotol", 0x02A84, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT --// "gesl", 0x022DB;0x0FE00, // GREATER-THAN slanted EQUAL TO OR LESS-THAN -- "gesles", 0x02A94, // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL -- "Gfr", 0x1D50A, // MATHEMATICAL FRAKTUR CAPITAL G -- "gfr", 0x1D524, // MATHEMATICAL FRAKTUR SMALL G -- "gg", 0x0226B, // MUCH GREATER-THAN -- "Gg", 0x022D9, // VERY MUCH GREATER-THAN -- "ggg", 0x022D9, // VERY MUCH GREATER-THAN -- "Ggr", 0x00393, // GREEK CAPITAL LETTER GAMMA -- "ggr", 0x003B3, // GREEK SMALL LETTER GAMMA -- "gimel", 0x02137, // GIMEL SYMBOL -- "GJcy", 0x00403, // CYRILLIC CAPITAL LETTER GJE -- "gjcy", 0x00453, // CYRILLIC SMALL LETTER GJE -- "gl", 0x02277, // GREATER-THAN OR LESS-THAN -- "gla", 0x02AA5, // GREATER-THAN BESIDE LESS-THAN -- "glE", 0x02A92, // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL -- "glj", 0x02AA4, // GREATER-THAN OVERLAPPING LESS-THAN -- "gnap", 0x02A8A, // GREATER-THAN AND NOT APPROXIMATE -- "gnapprox", 0x02A8A, // GREATER-THAN AND NOT APPROXIMATE -- "gnE", 0x02269, // GREATER-THAN BUT NOT EQUAL TO -- "gne", 0x02A88, // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO -- "gneq", 0x02A88, // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO -- "gneqq", 0x02269, // GREATER-THAN BUT NOT EQUAL TO -- "gnsim", 0x022E7, // GREATER-THAN BUT NOT EQUIVALENT TO -- "Gopf", 0x1D53E, // MATHEMATICAL DOUBLE-STRUCK CAPITAL G -- "gopf", 0x1D558, // MATHEMATICAL DOUBLE-STRUCK SMALL G -- "grave", 0x00060, // GRAVE ACCENT -- "GreaterEqual", 0x02265, // GREATER-THAN OR EQUAL TO -- "GreaterEqualLess", 0x022DB, // GREATER-THAN EQUAL TO OR LESS-THAN -- "GreaterFullEqual", 0x02267, // GREATER-THAN OVER EQUAL TO -- "GreaterGreater", 0x02AA2, // DOUBLE NESTED GREATER-THAN -- "GreaterLess", 0x02277, // GREATER-THAN OR LESS-THAN -- "GreaterSlantEqual", 0x02A7E, // GREATER-THAN OR SLANTED EQUAL TO -- "GreaterTilde", 0x02273, // GREATER-THAN OR EQUIVALENT TO -- "gscr", 0x0210A, // SCRIPT SMALL G -- "Gscr", 0x1D4A2, // MATHEMATICAL SCRIPT CAPITAL G -- "gsim", 0x02273, // GREATER-THAN OR EQUIVALENT TO -- "gsime", 0x02A8E, // GREATER-THAN ABOVE SIMILAR OR EQUAL -- "gsiml", 0x02A90, // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN -- "gt", 0x0003E, // GREATER-THAN SIGN -- "GT", 0x0003E, // GREATER-THAN SIGN -- "Gt", 0x0226B, // MUCH GREATER-THAN -- "gtcc", 0x02AA7, // GREATER-THAN CLOSED BY CURVE -- "gtcir", 0x02A7A, // GREATER-THAN WITH CIRCLE INSIDE -- "gtdot", 0x022D7, // GREATER-THAN WITH DOT -- "gtlPar", 0x02995, // DOUBLE LEFT ARC GREATER-THAN BRACKET -- "gtquest", 0x02A7C, // GREATER-THAN WITH QUESTION MARK ABOVE -- "gtrapprox", 0x02A86, // GREATER-THAN OR APPROXIMATE -- "gtrarr", 0x02978, // GREATER-THAN ABOVE RIGHTWARDS ARROW -- "gtrdot", 0x022D7, // GREATER-THAN WITH DOT -- "gtreqless", 0x022DB, // GREATER-THAN EQUAL TO OR LESS-THAN -- "gtreqqless", 0x02A8C, // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN -- "gtrless", 0x02277, // GREATER-THAN OR LESS-THAN -- "gtrsim", 0x02273, // GREATER-THAN OR EQUIVALENT TO --// "gvertneqq", 0x02269;0x0FE00, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke --// "gvnE", 0x02269;0x0FE00, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke -- NULL, 0 -+ {"gacute", 0x001F5}, // LATIN SMALL LETTER G WITH ACUTE -+ {"Gamma", 0x00393}, // GREEK CAPITAL LETTER GAMMA -+ {"gamma", 0x003B3}, // GREEK SMALL LETTER GAMMA -+ {"Gammad", 0x003DC}, // GREEK LETTER DIGAMMA -+ {"gammad", 0x003DD}, // GREEK SMALL LETTER DIGAMMA -+ {"gap", 0x02A86}, // GREATER-THAN OR APPROXIMATE -+ {"Gbreve", 0x0011E}, // LATIN CAPITAL LETTER G WITH BREVE -+ {"gbreve", 0x0011F}, // LATIN SMALL LETTER G WITH BREVE -+ {"Gcedil", 0x00122}, // LATIN CAPITAL LETTER G WITH CEDILLA -+ {"Gcirc", 0x0011C}, // LATIN CAPITAL LETTER G WITH CIRCUMFLEX -+ {"gcirc", 0x0011D}, // LATIN SMALL LETTER G WITH CIRCUMFLEX -+ {"Gcy", 0x00413}, // CYRILLIC CAPITAL LETTER GHE -+ {"gcy", 0x00433}, // CYRILLIC SMALL LETTER GHE -+ {"Gdot", 0x00120}, // LATIN CAPITAL LETTER G WITH DOT ABOVE -+ {"gdot", 0x00121}, // LATIN SMALL LETTER G WITH DOT ABOVE -+ {"ge", 0x02265}, // GREATER-THAN OR EQUAL TO -+ {"gE", 0x02267}, // GREATER-THAN OVER EQUAL TO -+ {"gel", 0x022DB}, // GREATER-THAN EQUAL TO OR LESS-THAN -+ {"gEl", 0x02A8C}, // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN -+ {"geq", 0x02265}, // GREATER-THAN OR EQUAL TO -+ {"geqq", 0x02267}, // GREATER-THAN OVER EQUAL TO -+ {"geqslant", 0x02A7E}, // GREATER-THAN OR SLANTED EQUAL TO -+ {"ges", 0x02A7E}, // GREATER-THAN OR SLANTED EQUAL TO -+ {"gescc", 0x02AA9}, // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL -+ {"gesdot", 0x02A80}, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE -+ {"gesdoto", 0x02A82}, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE -+ {"gesdotol", 0x02A84}, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT -+// "gesl", 0x022DB;0x0FE00}, // GREATER-THAN slanted EQUAL TO OR LESS-THAN -+ {"gesles", 0x02A94}, // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL -+ {"Gfr", 0x1D50A}, // MATHEMATICAL FRAKTUR CAPITAL G -+ {"gfr", 0x1D524}, // MATHEMATICAL FRAKTUR SMALL G -+ {"gg", 0x0226B}, // MUCH GREATER-THAN -+ {"Gg", 0x022D9}, // VERY MUCH GREATER-THAN -+ {"ggg", 0x022D9}, // VERY MUCH GREATER-THAN -+ {"Ggr", 0x00393}, // GREEK CAPITAL LETTER GAMMA -+ {"ggr", 0x003B3}, // GREEK SMALL LETTER GAMMA -+ {"gimel", 0x02137}, // GIMEL SYMBOL -+ {"GJcy", 0x00403}, // CYRILLIC CAPITAL LETTER GJE -+ {"gjcy", 0x00453}, // CYRILLIC SMALL LETTER GJE -+ {"gl", 0x02277}, // GREATER-THAN OR LESS-THAN -+ {"gla", 0x02AA5}, // GREATER-THAN BESIDE LESS-THAN -+ {"glE", 0x02A92}, // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL -+ {"glj", 0x02AA4}, // GREATER-THAN OVERLAPPING LESS-THAN -+ {"gnap", 0x02A8A}, // GREATER-THAN AND NOT APPROXIMATE -+ {"gnapprox", 0x02A8A}, // GREATER-THAN AND NOT APPROXIMATE -+ {"gnE", 0x02269}, // GREATER-THAN BUT NOT EQUAL TO -+ {"gne", 0x02A88}, // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO -+ {"gneq", 0x02A88}, // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO -+ {"gneqq", 0x02269}, // GREATER-THAN BUT NOT EQUAL TO -+ {"gnsim", 0x022E7}, // GREATER-THAN BUT NOT EQUIVALENT TO -+ {"Gopf", 0x1D53E}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL G -+ {"gopf", 0x1D558}, // MATHEMATICAL DOUBLE-STRUCK SMALL G -+ {"grave", 0x00060}, // GRAVE ACCENT -+ {"GreaterEqual", 0x02265}, // GREATER-THAN OR EQUAL TO -+ {"GreaterEqualLess", 0x022DB}, // GREATER-THAN EQUAL TO OR LESS-THAN -+ {"GreaterFullEqual", 0x02267}, // GREATER-THAN OVER EQUAL TO -+ {"GreaterGreater", 0x02AA2}, // DOUBLE NESTED GREATER-THAN -+ {"GreaterLess", 0x02277}, // GREATER-THAN OR LESS-THAN -+ {"GreaterSlantEqual", 0x02A7E}, // GREATER-THAN OR SLANTED EQUAL TO -+ {"GreaterTilde", 0x02273}, // GREATER-THAN OR EQUIVALENT TO -+ {"gscr", 0x0210A}, // SCRIPT SMALL G -+ {"Gscr", 0x1D4A2}, // MATHEMATICAL SCRIPT CAPITAL G -+ {"gsim", 0x02273}, // GREATER-THAN OR EQUIVALENT TO -+ {"gsime", 0x02A8E}, // GREATER-THAN ABOVE SIMILAR OR EQUAL -+ {"gsiml", 0x02A90}, // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN -+ {"gt", 0x0003E}, // GREATER-THAN SIGN -+ {"GT", 0x0003E}, // GREATER-THAN SIGN -+ {"Gt", 0x0226B}, // MUCH GREATER-THAN -+ {"gtcc", 0x02AA7}, // GREATER-THAN CLOSED BY CURVE -+ {"gtcir", 0x02A7A}, // GREATER-THAN WITH CIRCLE INSIDE -+ {"gtdot", 0x022D7}, // GREATER-THAN WITH DOT -+ {"gtlPar", 0x02995}, // DOUBLE LEFT ARC GREATER-THAN BRACKET -+ {"gtquest", 0x02A7C}, // GREATER-THAN WITH QUESTION MARK ABOVE -+ {"gtrapprox", 0x02A86}, // GREATER-THAN OR APPROXIMATE -+ {"gtrarr", 0x02978}, // GREATER-THAN ABOVE RIGHTWARDS ARROW -+ {"gtrdot", 0x022D7}, // GREATER-THAN WITH DOT -+ {"gtreqless", 0x022DB}, // GREATER-THAN EQUAL TO OR LESS-THAN -+ {"gtreqqless", 0x02A8C}, // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN -+ {"gtrless", 0x02277}, // GREATER-THAN OR LESS-THAN -+ {"gtrsim", 0x02273}, // GREATER-THAN OR EQUIVALENT TO -+// "gvertneqq", 0x02269;0x0FE00}, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke -+// "gvnE", 0x02269;0x0FE00}, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke -+ {NULL, 0} - }; - - static NameId namesH[]={ -- "Hacek", 0x002C7, // CARON -- "hairsp", 0x0200A, // HAIR SPACE -- "half", 0x000BD, // VULGAR FRACTION ONE HALF -- "hamilt", 0x0210B, // SCRIPT CAPITAL H -- "HARDcy", 0x0042A, // CYRILLIC CAPITAL LETTER HARD SIGN -- "hardcy", 0x0044A, // CYRILLIC SMALL LETTER HARD SIGN -- "harr", 0x02194, // LEFT RIGHT ARROW -- "hArr", 0x021D4, // LEFT RIGHT DOUBLE ARROW -- "harrcir", 0x02948, // LEFT RIGHT ARROW THROUGH SMALL CIRCLE -- "harrw", 0x021AD, // LEFT RIGHT WAVE ARROW -- "Hat", 0x0005E, // CIRCUMFLEX ACCENT -- "hbar", 0x0210F, // PLANCK CONSTANT OVER TWO PI -- "Hcirc", 0x00124, // LATIN CAPITAL LETTER H WITH CIRCUMFLEX -- "hcirc", 0x00125, // LATIN SMALL LETTER H WITH CIRCUMFLEX -- "hearts", 0x02665, // BLACK HEART SUIT -- "heartsuit", 0x02665, // BLACK HEART SUIT -- "hellip", 0x02026, // HORIZONTAL ELLIPSIS -- "hercon", 0x022B9, // HERMITIAN CONJUGATE MATRIX -- "Hfr", 0x0210C, // BLACK-LETTER CAPITAL H -- "hfr", 0x1D525, // MATHEMATICAL FRAKTUR SMALL H -- "HilbertSpace", 0x0210B, // SCRIPT CAPITAL H -- "hksearow", 0x02925, // SOUTH EAST ARROW WITH HOOK -- "hkswarow", 0x02926, // SOUTH WEST ARROW WITH HOOK -- "hoarr", 0x021FF, // LEFT RIGHT OPEN-HEADED ARROW -- "homtht", 0x0223B, // HOMOTHETIC -- "hookleftarrow", 0x021A9, // LEFTWARDS ARROW WITH HOOK -- "hookrightarrow", 0x021AA, // RIGHTWARDS ARROW WITH HOOK -- "Hopf", 0x0210D, // DOUBLE-STRUCK CAPITAL H -- "hopf", 0x1D559, // MATHEMATICAL DOUBLE-STRUCK SMALL H -- "horbar", 0x02015, // HORIZONTAL BAR -- "HorizontalLine", 0x02500, // BOX DRAWINGS LIGHT HORIZONTAL -- "Hscr", 0x0210B, // SCRIPT CAPITAL H -- "hscr", 0x1D4BD, // MATHEMATICAL SCRIPT SMALL H -- "hslash", 0x0210F, // PLANCK CONSTANT OVER TWO PI -- "Hstrok", 0x00126, // LATIN CAPITAL LETTER H WITH STROKE -- "hstrok", 0x00127, // LATIN SMALL LETTER H WITH STROKE -- "HumpDownHump", 0x0224E, // GEOMETRICALLY EQUIVALENT TO -- "HumpEqual", 0x0224F, // DIFFERENCE BETWEEN -- "hybull", 0x02043, // HYPHEN BULLET -- "hyphen", 0x02010, // HYPHEN -- NULL, 0 -+ {"Hacek", 0x002C7}, // CARON -+ {"hairsp", 0x0200A}, // HAIR SPACE -+ {"half", 0x000BD}, // VULGAR FRACTION ONE HALF -+ {"hamilt", 0x0210B}, // SCRIPT CAPITAL H -+ {"HARDcy", 0x0042A}, // CYRILLIC CAPITAL LETTER HARD SIGN -+ {"hardcy", 0x0044A}, // CYRILLIC SMALL LETTER HARD SIGN -+ {"harr", 0x02194}, // LEFT RIGHT ARROW -+ {"hArr", 0x021D4}, // LEFT RIGHT DOUBLE ARROW -+ {"harrcir", 0x02948}, // LEFT RIGHT ARROW THROUGH SMALL CIRCLE -+ {"harrw", 0x021AD}, // LEFT RIGHT WAVE ARROW -+ {"Hat", 0x0005E}, // CIRCUMFLEX ACCENT -+ {"hbar", 0x0210F}, // PLANCK CONSTANT OVER TWO PI -+ {"Hcirc", 0x00124}, // LATIN CAPITAL LETTER H WITH CIRCUMFLEX -+ {"hcirc", 0x00125}, // LATIN SMALL LETTER H WITH CIRCUMFLEX -+ {"hearts", 0x02665}, // BLACK HEART SUIT -+ {"heartsuit", 0x02665}, // BLACK HEART SUIT -+ {"hellip", 0x02026}, // HORIZONTAL ELLIPSIS -+ {"hercon", 0x022B9}, // HERMITIAN CONJUGATE MATRIX -+ {"Hfr", 0x0210C}, // BLACK-LETTER CAPITAL H -+ {"hfr", 0x1D525}, // MATHEMATICAL FRAKTUR SMALL H -+ {"HilbertSpace", 0x0210B}, // SCRIPT CAPITAL H -+ {"hksearow", 0x02925}, // SOUTH EAST ARROW WITH HOOK -+ {"hkswarow", 0x02926}, // SOUTH WEST ARROW WITH HOOK -+ {"hoarr", 0x021FF}, // LEFT RIGHT OPEN-HEADED ARROW -+ {"homtht", 0x0223B}, // HOMOTHETIC -+ {"hookleftarrow", 0x021A9}, // LEFTWARDS ARROW WITH HOOK -+ {"hookrightarrow", 0x021AA}, // RIGHTWARDS ARROW WITH HOOK -+ {"Hopf", 0x0210D}, // DOUBLE-STRUCK CAPITAL H -+ {"hopf", 0x1D559}, // MATHEMATICAL DOUBLE-STRUCK SMALL H -+ {"horbar", 0x02015}, // HORIZONTAL BAR -+ {"HorizontalLine", 0x02500}, // BOX DRAWINGS LIGHT HORIZONTAL -+ {"Hscr", 0x0210B}, // SCRIPT CAPITAL H -+ {"hscr", 0x1D4BD}, // MATHEMATICAL SCRIPT SMALL H -+ {"hslash", 0x0210F}, // PLANCK CONSTANT OVER TWO PI -+ {"Hstrok", 0x00126}, // LATIN CAPITAL LETTER H WITH STROKE -+ {"hstrok", 0x00127}, // LATIN SMALL LETTER H WITH STROKE -+ {"HumpDownHump", 0x0224E}, // GEOMETRICALLY EQUIVALENT TO -+ {"HumpEqual", 0x0224F}, // DIFFERENCE BETWEEN -+ {"hybull", 0x02043}, // HYPHEN BULLET -+ {"hyphen", 0x02010}, // HYPHEN -+ {NULL, 0} - }; - - static NameId namesI[]={ -- "Iacgr", 0x0038A, // GREEK CAPITAL LETTER IOTA WITH TONOS -- "iacgr", 0x003AF, // GREEK SMALL LETTER IOTA WITH TONOS -- "Iacute", 0x000CD, // LATIN CAPITAL LETTER I WITH ACUTE -- "iacute", 0x000ED, // LATIN SMALL LETTER I WITH ACUTE -- "ic", 0x02063, // INVISIBLE SEPARATOR -- "Icirc", 0x000CE, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX -- "icirc", 0x000EE, // LATIN SMALL LETTER I WITH CIRCUMFLEX -- "Icy", 0x00418, // CYRILLIC CAPITAL LETTER I -- "icy", 0x00438, // CYRILLIC SMALL LETTER I -- "idiagr", 0x00390, // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -- "Idigr", 0x003AA, // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -- "idigr", 0x003CA, // GREEK SMALL LETTER IOTA WITH DIALYTIKA -- "Idot", 0x00130, // LATIN CAPITAL LETTER I WITH DOT ABOVE -- "IEcy", 0x00415, // CYRILLIC CAPITAL LETTER IE -- "iecy", 0x00435, // CYRILLIC SMALL LETTER IE -- "iexcl", 0x000A1, // INVERTED EXCLAMATION MARK -- "iff", 0x021D4, // LEFT RIGHT DOUBLE ARROW -- "Ifr", 0x02111, // BLACK-LETTER CAPITAL I -- "ifr", 0x1D526, // MATHEMATICAL FRAKTUR SMALL I -- "Igr", 0x00399, // GREEK CAPITAL LETTER IOTA -- "igr", 0x003B9, // GREEK SMALL LETTER IOTA -- "Igrave", 0x000CC, // LATIN CAPITAL LETTER I WITH GRAVE -- "igrave", 0x000EC, // LATIN SMALL LETTER I WITH GRAVE -- "ii", 0x02148, // DOUBLE-STRUCK ITALIC SMALL I -- "iiiint", 0x02A0C, // QUADRUPLE INTEGRAL OPERATOR -- "iiint", 0x0222D, // TRIPLE INTEGRAL -- "iinfin", 0x029DC, // INCOMPLETE INFINITY -- "iiota", 0x02129, // TURNED GREEK SMALL LETTER IOTA -- "IJlig", 0x00132, // LATIN CAPITAL LIGATURE IJ -- "ijlig", 0x00133, // LATIN SMALL LIGATURE IJ -- "Im", 0x02111, // BLACK-LETTER CAPITAL I -- "Imacr", 0x0012A, // LATIN CAPITAL LETTER I WITH MACRON -- "imacr", 0x0012B, // LATIN SMALL LETTER I WITH MACRON -- "image", 0x02111, // BLACK-LETTER CAPITAL I -- "ImaginaryI", 0x02148, // DOUBLE-STRUCK ITALIC SMALL I -- "imagline", 0x02110, // SCRIPT CAPITAL I -- "imagpart", 0x02111, // BLACK-LETTER CAPITAL I -- "imath", 0x00131, // LATIN SMALL LETTER DOTLESS I -- "imof", 0x022B7, // IMAGE OF -- "imped", 0x001B5, // LATIN CAPITAL LETTER Z WITH STROKE -- "Implies", 0x021D2, // RIGHTWARDS DOUBLE ARROW -- "in", 0x02208, // ELEMENT OF -- "incare", 0x02105, // CARE OF -- "infin", 0x0221E, // INFINITY -- "infintie", 0x029DD, // TIE OVER INFINITY -- "inodot", 0x00131, // LATIN SMALL LETTER DOTLESS I -- "int", 0x0222B, // INTEGRAL -- "Int", 0x0222C, // DOUBLE INTEGRAL -- "intcal", 0x022BA, // INTERCALATE -- "integers", 0x02124, // DOUBLE-STRUCK CAPITAL Z -- "Integral", 0x0222B, // INTEGRAL -- "intercal", 0x022BA, // INTERCALATE -- "Intersection", 0x022C2, // N-ARY INTERSECTION -- "intlarhk", 0x02A17, // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK -- "intprod", 0x02A3C, // INTERIOR PRODUCT -- "InvisibleComma", 0x02063, // INVISIBLE SEPARATOR -- "InvisibleTimes", 0x02062, // INVISIBLE TIMES -- "IOcy", 0x00401, // CYRILLIC CAPITAL LETTER IO -- "iocy", 0x00451, // CYRILLIC SMALL LETTER IO -- "Iogon", 0x0012E, // LATIN CAPITAL LETTER I WITH OGONEK -- "iogon", 0x0012F, // LATIN SMALL LETTER I WITH OGONEK -- "Iopf", 0x1D540, // MATHEMATICAL DOUBLE-STRUCK CAPITAL I -- "iopf", 0x1D55A, // MATHEMATICAL DOUBLE-STRUCK SMALL I -- "Iota", 0x00399, // GREEK CAPITAL LETTER IOTA -- "iota", 0x003B9, // GREEK SMALL LETTER IOTA -- "iprod", 0x02A3C, // INTERIOR PRODUCT -- "iquest", 0x000BF, // INVERTED QUESTION MARK -- "Iscr", 0x02110, // SCRIPT CAPITAL I -- "iscr", 0x1D4BE, // MATHEMATICAL SCRIPT SMALL I -- "isin", 0x02208, // ELEMENT OF -- "isindot", 0x022F5, // ELEMENT OF WITH DOT ABOVE -- "isinE", 0x022F9, // ELEMENT OF WITH TWO HORIZONTAL STROKES -- "isins", 0x022F4, // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -- "isinsv", 0x022F3, // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -- "isinv", 0x02208, // ELEMENT OF -- "it", 0x02062, // INVISIBLE TIMES -- "Itilde", 0x00128, // LATIN CAPITAL LETTER I WITH TILDE -- "itilde", 0x00129, // LATIN SMALL LETTER I WITH TILDE -- "Iukcy", 0x00406, // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -- "iukcy", 0x00456, // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -- "Iuml", 0x000CF, // LATIN CAPITAL LETTER I WITH DIAERESIS -- "iuml", 0x000EF, // LATIN SMALL LETTER I WITH DIAERESIS -- NULL, 0 -+ {"Iacgr", 0x0038A}, // GREEK CAPITAL LETTER IOTA WITH TONOS -+ {"iacgr", 0x003AF}, // GREEK SMALL LETTER IOTA WITH TONOS -+ {"Iacute", 0x000CD}, // LATIN CAPITAL LETTER I WITH ACUTE -+ {"iacute", 0x000ED}, // LATIN SMALL LETTER I WITH ACUTE -+ {"ic", 0x02063}, // INVISIBLE SEPARATOR -+ {"Icirc", 0x000CE}, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX -+ {"icirc", 0x000EE}, // LATIN SMALL LETTER I WITH CIRCUMFLEX -+ {"Icy", 0x00418}, // CYRILLIC CAPITAL LETTER I -+ {"icy", 0x00438}, // CYRILLIC SMALL LETTER I -+ {"idiagr", 0x00390}, // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -+ {"Idigr", 0x003AA}, // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -+ {"idigr", 0x003CA}, // GREEK SMALL LETTER IOTA WITH DIALYTIKA -+ {"Idot", 0x00130}, // LATIN CAPITAL LETTER I WITH DOT ABOVE -+ {"IEcy", 0x00415}, // CYRILLIC CAPITAL LETTER IE -+ {"iecy", 0x00435}, // CYRILLIC SMALL LETTER IE -+ {"iexcl", 0x000A1}, // INVERTED EXCLAMATION MARK -+ {"iff", 0x021D4}, // LEFT RIGHT DOUBLE ARROW -+ {"Ifr", 0x02111}, // BLACK-LETTER CAPITAL I -+ {"ifr", 0x1D526}, // MATHEMATICAL FRAKTUR SMALL I -+ {"Igr", 0x00399}, // GREEK CAPITAL LETTER IOTA -+ {"igr", 0x003B9}, // GREEK SMALL LETTER IOTA -+ {"Igrave", 0x000CC}, // LATIN CAPITAL LETTER I WITH GRAVE -+ {"igrave", 0x000EC}, // LATIN SMALL LETTER I WITH GRAVE -+ {"ii", 0x02148}, // DOUBLE-STRUCK ITALIC SMALL I -+ {"iiiint", 0x02A0C}, // QUADRUPLE INTEGRAL OPERATOR -+ {"iiint", 0x0222D}, // TRIPLE INTEGRAL -+ {"iinfin", 0x029DC}, // INCOMPLETE INFINITY -+ {"iiota", 0x02129}, // TURNED GREEK SMALL LETTER IOTA -+ {"IJlig", 0x00132}, // LATIN CAPITAL LIGATURE IJ -+ {"ijlig", 0x00133}, // LATIN SMALL LIGATURE IJ -+ {"Im", 0x02111}, // BLACK-LETTER CAPITAL I -+ {"Imacr", 0x0012A}, // LATIN CAPITAL LETTER I WITH MACRON -+ {"imacr", 0x0012B}, // LATIN SMALL LETTER I WITH MACRON -+ {"image", 0x02111}, // BLACK-LETTER CAPITAL I -+ {"ImaginaryI", 0x02148}, // DOUBLE-STRUCK ITALIC SMALL I -+ {"imagline", 0x02110}, // SCRIPT CAPITAL I -+ {"imagpart", 0x02111}, // BLACK-LETTER CAPITAL I -+ {"imath", 0x00131}, // LATIN SMALL LETTER DOTLESS I -+ {"imof", 0x022B7}, // IMAGE OF -+ {"imped", 0x001B5}, // LATIN CAPITAL LETTER Z WITH STROKE -+ {"Implies", 0x021D2}, // RIGHTWARDS DOUBLE ARROW -+ {"in", 0x02208}, // ELEMENT OF -+ {"incare", 0x02105}, // CARE OF -+ {"infin", 0x0221E}, // INFINITY -+ {"infintie", 0x029DD}, // TIE OVER INFINITY -+ {"inodot", 0x00131}, // LATIN SMALL LETTER DOTLESS I -+ {"int", 0x0222B}, // INTEGRAL -+ {"Int", 0x0222C}, // DOUBLE INTEGRAL -+ {"intcal", 0x022BA}, // INTERCALATE -+ {"integers", 0x02124}, // DOUBLE-STRUCK CAPITAL Z -+ {"Integral", 0x0222B}, // INTEGRAL -+ {"intercal", 0x022BA}, // INTERCALATE -+ {"Intersection", 0x022C2}, // N-ARY INTERSECTION -+ {"intlarhk", 0x02A17}, // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK -+ {"intprod", 0x02A3C}, // INTERIOR PRODUCT -+ {"InvisibleComma", 0x02063}, // INVISIBLE SEPARATOR -+ {"InvisibleTimes", 0x02062}, // INVISIBLE TIMES -+ {"IOcy", 0x00401}, // CYRILLIC CAPITAL LETTER IO -+ {"iocy", 0x00451}, // CYRILLIC SMALL LETTER IO -+ {"Iogon", 0x0012E}, // LATIN CAPITAL LETTER I WITH OGONEK -+ {"iogon", 0x0012F}, // LATIN SMALL LETTER I WITH OGONEK -+ {"Iopf", 0x1D540}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL I -+ {"iopf", 0x1D55A}, // MATHEMATICAL DOUBLE-STRUCK SMALL I -+ {"Iota", 0x00399}, // GREEK CAPITAL LETTER IOTA -+ {"iota", 0x003B9}, // GREEK SMALL LETTER IOTA -+ {"iprod", 0x02A3C}, // INTERIOR PRODUCT -+ {"iquest", 0x000BF}, // INVERTED QUESTION MARK -+ {"Iscr", 0x02110}, // SCRIPT CAPITAL I -+ {"iscr", 0x1D4BE}, // MATHEMATICAL SCRIPT SMALL I -+ {"isin", 0x02208}, // ELEMENT OF -+ {"isindot", 0x022F5}, // ELEMENT OF WITH DOT ABOVE -+ {"isinE", 0x022F9}, // ELEMENT OF WITH TWO HORIZONTAL STROKES -+ {"isins", 0x022F4}, // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -+ {"isinsv", 0x022F3}, // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -+ {"isinv", 0x02208}, // ELEMENT OF -+ {"it", 0x02062}, // INVISIBLE TIMES -+ {"Itilde", 0x00128}, // LATIN CAPITAL LETTER I WITH TILDE -+ {"itilde", 0x00129}, // LATIN SMALL LETTER I WITH TILDE -+ {"Iukcy", 0x00406}, // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -+ {"iukcy", 0x00456}, // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -+ {"Iuml", 0x000CF}, // LATIN CAPITAL LETTER I WITH DIAERESIS -+ {"iuml", 0x000EF}, // LATIN SMALL LETTER I WITH DIAERESIS -+ {NULL, 0} - }; - - static NameId namesJ[]={ -- "Jcirc", 0x00134, // LATIN CAPITAL LETTER J WITH CIRCUMFLEX -- "jcirc", 0x00135, // LATIN SMALL LETTER J WITH CIRCUMFLEX -- "Jcy", 0x00419, // CYRILLIC CAPITAL LETTER SHORT I -- "jcy", 0x00439, // CYRILLIC SMALL LETTER SHORT I -- "Jfr", 0x1D50D, // MATHEMATICAL FRAKTUR CAPITAL J -- "jfr", 0x1D527, // MATHEMATICAL FRAKTUR SMALL J -- "jmath", 0x00237, // LATIN SMALL LETTER DOTLESS J -- "Jopf", 0x1D541, // MATHEMATICAL DOUBLE-STRUCK CAPITAL J -- "jopf", 0x1D55B, // MATHEMATICAL DOUBLE-STRUCK SMALL J -- "Jscr", 0x1D4A5, // MATHEMATICAL SCRIPT CAPITAL J -- "jscr", 0x1D4BF, // MATHEMATICAL SCRIPT SMALL J -- "Jsercy", 0x00408, // CYRILLIC CAPITAL LETTER JE -- "jsercy", 0x00458, // CYRILLIC SMALL LETTER JE -- "Jukcy", 0x00404, // CYRILLIC CAPITAL LETTER UKRAINIAN IE -- "jukcy", 0x00454, // CYRILLIC SMALL LETTER UKRAINIAN IE -- NULL, 0 -+ {"Jcirc", 0x00134}, // LATIN CAPITAL LETTER J WITH CIRCUMFLEX -+ {"jcirc", 0x00135}, // LATIN SMALL LETTER J WITH CIRCUMFLEX -+ {"Jcy", 0x00419}, // CYRILLIC CAPITAL LETTER SHORT I -+ {"jcy", 0x00439}, // CYRILLIC SMALL LETTER SHORT I -+ {"Jfr", 0x1D50D}, // MATHEMATICAL FRAKTUR CAPITAL J -+ {"jfr", 0x1D527}, // MATHEMATICAL FRAKTUR SMALL J -+ {"jmath", 0x00237}, // LATIN SMALL LETTER DOTLESS J -+ {"Jopf", 0x1D541}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL J -+ {"jopf", 0x1D55B}, // MATHEMATICAL DOUBLE-STRUCK SMALL J -+ {"Jscr", 0x1D4A5}, // MATHEMATICAL SCRIPT CAPITAL J -+ {"jscr", 0x1D4BF}, // MATHEMATICAL SCRIPT SMALL J -+ {"Jsercy", 0x00408}, // CYRILLIC CAPITAL LETTER JE -+ {"jsercy", 0x00458}, // CYRILLIC SMALL LETTER JE -+ {"Jukcy", 0x00404}, // CYRILLIC CAPITAL LETTER UKRAINIAN IE -+ {"jukcy", 0x00454}, // CYRILLIC SMALL LETTER UKRAINIAN IE -+ {NULL, 0} - }; - - static NameId namesK[]={ -- "Kappa", 0x0039A, // GREEK CAPITAL LETTER KAPPA -- "kappa", 0x003BA, // GREEK SMALL LETTER KAPPA -- "kappav", 0x003F0, // GREEK KAPPA SYMBOL -- "Kcedil", 0x00136, // LATIN CAPITAL LETTER K WITH CEDILLA -- "kcedil", 0x00137, // LATIN SMALL LETTER K WITH CEDILLA -- "Kcy", 0x0041A, // CYRILLIC CAPITAL LETTER KA -- "kcy", 0x0043A, // CYRILLIC SMALL LETTER KA -- "Kfr", 0x1D50E, // MATHEMATICAL FRAKTUR CAPITAL K -- "kfr", 0x1D528, // MATHEMATICAL FRAKTUR SMALL K -- "Kgr", 0x0039A, // GREEK CAPITAL LETTER KAPPA -- "kgr", 0x003BA, // GREEK SMALL LETTER KAPPA -- "kgreen", 0x00138, // LATIN SMALL LETTER KRA -- "KHcy", 0x00425, // CYRILLIC CAPITAL LETTER HA -- "khcy", 0x00445, // CYRILLIC SMALL LETTER HA -- "KHgr", 0x003A7, // GREEK CAPITAL LETTER CHI -- "khgr", 0x003C7, // GREEK SMALL LETTER CHI -- "KJcy", 0x0040C, // CYRILLIC CAPITAL LETTER KJE -- "kjcy", 0x0045C, // CYRILLIC SMALL LETTER KJE -- "Kopf", 0x1D542, // MATHEMATICAL DOUBLE-STRUCK CAPITAL K -- "kopf", 0x1D55C, // MATHEMATICAL DOUBLE-STRUCK SMALL K -- "Kscr", 0x1D4A6, // MATHEMATICAL SCRIPT CAPITAL K -- "kscr", 0x1D4C0, // MATHEMATICAL SCRIPT SMALL K -- NULL, 0 -+ {"Kappa", 0x0039A}, // GREEK CAPITAL LETTER KAPPA -+ {"kappa", 0x003BA}, // GREEK SMALL LETTER KAPPA -+ {"kappav", 0x003F0}, // GREEK KAPPA SYMBOL -+ {"Kcedil", 0x00136}, // LATIN CAPITAL LETTER K WITH CEDILLA -+ {"kcedil", 0x00137}, // LATIN SMALL LETTER K WITH CEDILLA -+ {"Kcy", 0x0041A}, // CYRILLIC CAPITAL LETTER KA -+ {"kcy", 0x0043A}, // CYRILLIC SMALL LETTER KA -+ {"Kfr", 0x1D50E}, // MATHEMATICAL FRAKTUR CAPITAL K -+ {"kfr", 0x1D528}, // MATHEMATICAL FRAKTUR SMALL K -+ {"Kgr", 0x0039A}, // GREEK CAPITAL LETTER KAPPA -+ {"kgr", 0x003BA}, // GREEK SMALL LETTER KAPPA -+ {"kgreen", 0x00138}, // LATIN SMALL LETTER KRA -+ {"KHcy", 0x00425}, // CYRILLIC CAPITAL LETTER HA -+ {"khcy", 0x00445}, // CYRILLIC SMALL LETTER HA -+ {"KHgr", 0x003A7}, // GREEK CAPITAL LETTER CHI -+ {"khgr", 0x003C7}, // GREEK SMALL LETTER CHI -+ {"KJcy", 0x0040C}, // CYRILLIC CAPITAL LETTER KJE -+ {"kjcy", 0x0045C}, // CYRILLIC SMALL LETTER KJE -+ {"Kopf", 0x1D542}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL K -+ {"kopf", 0x1D55C}, // MATHEMATICAL DOUBLE-STRUCK SMALL K -+ {"Kscr", 0x1D4A6}, // MATHEMATICAL SCRIPT CAPITAL K -+ {"kscr", 0x1D4C0}, // MATHEMATICAL SCRIPT SMALL K -+ {NULL, 0} - }; - - static NameId namesL[]={ -- "lAarr", 0x021DA, // LEFTWARDS TRIPLE ARROW -- "Lacute", 0x00139, // LATIN CAPITAL LETTER L WITH ACUTE -- "lacute", 0x0013A, // LATIN SMALL LETTER L WITH ACUTE -- "laemptyv", 0x029B4, // EMPTY SET WITH LEFT ARROW ABOVE -- "lagran", 0x02112, // SCRIPT CAPITAL L -- "Lambda", 0x0039B, // GREEK CAPITAL LETTER LAMDA -- "lambda", 0x003BB, // GREEK SMALL LETTER LAMDA -- "lang", 0x027E8, // MATHEMATICAL LEFT ANGLE BRACKET -- "Lang", 0x027EA, // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET -- "langd", 0x02991, // LEFT ANGLE BRACKET WITH DOT -- "langle", 0x027E8, // MATHEMATICAL LEFT ANGLE BRACKET -- "lap", 0x02A85, // LESS-THAN OR APPROXIMATE -- "Laplacetrf", 0x02112, // SCRIPT CAPITAL L -- "laquo", 0x000AB, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -- "larr", 0x02190, // LEFTWARDS ARROW -- "Larr", 0x0219E, // LEFTWARDS TWO HEADED ARROW -- "lArr", 0x021D0, // LEFTWARDS DOUBLE ARROW -- "larrb", 0x021E4, // LEFTWARDS ARROW TO BAR -- "larrbfs", 0x0291F, // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND -- "larrfs", 0x0291D, // LEFTWARDS ARROW TO BLACK DIAMOND -- "larrhk", 0x021A9, // LEFTWARDS ARROW WITH HOOK -- "larrlp", 0x021AB, // LEFTWARDS ARROW WITH LOOP -- "larrpl", 0x02939, // LEFT-SIDE ARC ANTICLOCKWISE ARROW -- "larrsim", 0x02973, // LEFTWARDS ARROW ABOVE TILDE OPERATOR -- "larrtl", 0x021A2, // LEFTWARDS ARROW WITH TAIL -- "lat", 0x02AAB, // LARGER THAN -- "latail", 0x02919, // LEFTWARDS ARROW-TAIL -- "lAtail", 0x0291B, // LEFTWARDS DOUBLE ARROW-TAIL -- "late", 0x02AAD, // LARGER THAN OR EQUAL TO --// "lates", 0x02AAD;0x0FE00, // LARGER THAN OR slanted EQUAL -- "lbarr", 0x0290C, // LEFTWARDS DOUBLE DASH ARROW -- "lBarr", 0x0290E, // LEFTWARDS TRIPLE DASH ARROW -- "lbbrk", 0x02772, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT -- "lbrace", 0x0007B, // LEFT CURLY BRACKET -- "lbrack", 0x0005B, // LEFT SQUARE BRACKET -- "lbrke", 0x0298B, // LEFT SQUARE BRACKET WITH UNDERBAR -- "lbrksld", 0x0298F, // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER -- "lbrkslu", 0x0298D, // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER -- "Lcaron", 0x0013D, // LATIN CAPITAL LETTER L WITH CARON -- "lcaron", 0x0013E, // LATIN SMALL LETTER L WITH CARON -- "Lcedil", 0x0013B, // LATIN CAPITAL LETTER L WITH CEDILLA -- "lcedil", 0x0013C, // LATIN SMALL LETTER L WITH CEDILLA -- "lceil", 0x02308, // LEFT CEILING -- "lcub", 0x0007B, // LEFT CURLY BRACKET -- "Lcy", 0x0041B, // CYRILLIC CAPITAL LETTER EL -- "lcy", 0x0043B, // CYRILLIC SMALL LETTER EL -- "ldca", 0x02936, // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS -- "ldquo", 0x0201C, // LEFT DOUBLE QUOTATION MARK -- "ldquor", 0x0201E, // DOUBLE LOW-9 QUOTATION MARK -- "ldrdhar", 0x02967, // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN -- "ldrushar", 0x0294B, // LEFT BARB DOWN RIGHT BARB UP HARPOON -- "ldsh", 0x021B2, // DOWNWARDS ARROW WITH TIP LEFTWARDS -- "le", 0x02264, // LESS-THAN OR EQUAL TO -- "lE", 0x02266, // LESS-THAN OVER EQUAL TO -- "LeftAngleBracket", 0x027E8, // MATHEMATICAL LEFT ANGLE BRACKET -- "leftarrow", 0x02190, // LEFTWARDS ARROW -- "LeftArrow", 0x02190, // LEFTWARDS ARROW -- "Leftarrow", 0x021D0, // LEFTWARDS DOUBLE ARROW -- "LeftArrowBar", 0x021E4, // LEFTWARDS ARROW TO BAR -- "LeftArrowRightArrow", 0x021C6, // LEFTWARDS ARROW OVER RIGHTWARDS ARROW -- "leftarrowtail", 0x021A2, // LEFTWARDS ARROW WITH TAIL -- "LeftCeiling", 0x02308, // LEFT CEILING -- "LeftDoubleBracket", 0x027E6, // MATHEMATICAL LEFT WHITE SQUARE BRACKET -- "LeftDownTeeVector", 0x02961, // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR -- "LeftDownVector", 0x021C3, // DOWNWARDS HARPOON WITH BARB LEFTWARDS -- "LeftDownVectorBar", 0x02959, // DOWNWARDS HARPOON WITH BARB LEFT TO BAR -- "LeftFloor", 0x0230A, // LEFT FLOOR -- "leftharpoondown", 0x021BD, // LEFTWARDS HARPOON WITH BARB DOWNWARDS -- "leftharpoonup", 0x021BC, // LEFTWARDS HARPOON WITH BARB UPWARDS -- "leftleftarrows", 0x021C7, // LEFTWARDS PAIRED ARROWS -- "leftrightarrow", 0x02194, // LEFT RIGHT ARROW -- "LeftRightArrow", 0x02194, // LEFT RIGHT ARROW -- "Leftrightarrow", 0x021D4, // LEFT RIGHT DOUBLE ARROW -- "leftrightarrows", 0x021C6, // LEFTWARDS ARROW OVER RIGHTWARDS ARROW -- "leftrightharpoons", 0x021CB, // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -- "leftrightsquigarrow", 0x021AD, // LEFT RIGHT WAVE ARROW -- "LeftRightVector", 0x0294E, // LEFT BARB UP RIGHT BARB UP HARPOON -- "LeftTee", 0x022A3, // LEFT TACK -- "LeftTeeArrow", 0x021A4, // LEFTWARDS ARROW FROM BAR -- "LeftTeeVector", 0x0295A, // LEFTWARDS HARPOON WITH BARB UP FROM BAR -- "leftthreetimes", 0x022CB, // LEFT SEMIDIRECT PRODUCT -- "LeftTriangle", 0x022B2, // NORMAL SUBGROUP OF -- "LeftTriangleBar", 0x029CF, // LEFT TRIANGLE BESIDE VERTICAL BAR -- "LeftTriangleEqual", 0x022B4, // NORMAL SUBGROUP OF OR EQUAL TO -- "LeftUpDownVector", 0x02951, // UP BARB LEFT DOWN BARB LEFT HARPOON -- "LeftUpTeeVector", 0x02960, // UPWARDS HARPOON WITH BARB LEFT FROM BAR -- "LeftUpVector", 0x021BF, // UPWARDS HARPOON WITH BARB LEFTWARDS -- "LeftUpVectorBar", 0x02958, // UPWARDS HARPOON WITH BARB LEFT TO BAR -- "LeftVector", 0x021BC, // LEFTWARDS HARPOON WITH BARB UPWARDS -- "LeftVectorBar", 0x02952, // LEFTWARDS HARPOON WITH BARB UP TO BAR -- "leg", 0x022DA, // LESS-THAN EQUAL TO OR GREATER-THAN -- "lEg", 0x02A8B, // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN -- "leq", 0x02264, // LESS-THAN OR EQUAL TO -- "leqq", 0x02266, // LESS-THAN OVER EQUAL TO -- "leqslant", 0x02A7D, // LESS-THAN OR SLANTED EQUAL TO -- "les", 0x02A7D, // LESS-THAN OR SLANTED EQUAL TO -- "lescc", 0x02AA8, // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL -- "lesdot", 0x02A7F, // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE -- "lesdoto", 0x02A81, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE -- "lesdotor", 0x02A83, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT --// "lesg", 0x022DA;0x0FE00, // LESS-THAN slanted EQUAL TO OR GREATER-THAN -- "lesges", 0x02A93, // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL -- "lessapprox", 0x02A85, // LESS-THAN OR APPROXIMATE -- "lessdot", 0x022D6, // LESS-THAN WITH DOT -- "lesseqgtr", 0x022DA, // LESS-THAN EQUAL TO OR GREATER-THAN -- "lesseqqgtr", 0x02A8B, // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN -- "LessEqualGreater", 0x022DA, // LESS-THAN EQUAL TO OR GREATER-THAN -- "LessFullEqual", 0x02266, // LESS-THAN OVER EQUAL TO -- "LessGreater", 0x02276, // LESS-THAN OR GREATER-THAN -- "lessgtr", 0x02276, // LESS-THAN OR GREATER-THAN -- "LessLess", 0x02AA1, // DOUBLE NESTED LESS-THAN -- "lesssim", 0x02272, // LESS-THAN OR EQUIVALENT TO -- "LessSlantEqual", 0x02A7D, // LESS-THAN OR SLANTED EQUAL TO -- "LessTilde", 0x02272, // LESS-THAN OR EQUIVALENT TO -- "lfisht", 0x0297C, // LEFT FISH TAIL -- "lfloor", 0x0230A, // LEFT FLOOR -- "Lfr", 0x1D50F, // MATHEMATICAL FRAKTUR CAPITAL L -- "lfr", 0x1D529, // MATHEMATICAL FRAKTUR SMALL L -- "lg", 0x02276, // LESS-THAN OR GREATER-THAN -- "lgE", 0x02A91, // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL -- "Lgr", 0x0039B, // GREEK CAPITAL LETTER LAMDA -- "lgr", 0x003BB, // GREEK SMALL LETTER LAMDA -- "lHar", 0x02962, // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN -- "lhard", 0x021BD, // LEFTWARDS HARPOON WITH BARB DOWNWARDS -- "lharu", 0x021BC, // LEFTWARDS HARPOON WITH BARB UPWARDS -- "lharul", 0x0296A, // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH -- "lhblk", 0x02584, // LOWER HALF BLOCK -- "LJcy", 0x00409, // CYRILLIC CAPITAL LETTER LJE -- "ljcy", 0x00459, // CYRILLIC SMALL LETTER LJE -- "ll", 0x0226A, // MUCH LESS-THAN -- "Ll", 0x022D8, // VERY MUCH LESS-THAN -- "llarr", 0x021C7, // LEFTWARDS PAIRED ARROWS -- "llcorner", 0x0231E, // BOTTOM LEFT CORNER -- "Lleftarrow", 0x021DA, // LEFTWARDS TRIPLE ARROW -- "llhard", 0x0296B, // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH -- "lltri", 0x025FA, // LOWER LEFT TRIANGLE -- "Lmidot", 0x0013F, // LATIN CAPITAL LETTER L WITH MIDDLE DOT -- "lmidot", 0x00140, // LATIN SMALL LETTER L WITH MIDDLE DOT -- "lmoust", 0x023B0, // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION -- "lmoustache", 0x023B0, // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION -- "lnap", 0x02A89, // LESS-THAN AND NOT APPROXIMATE -- "lnapprox", 0x02A89, // LESS-THAN AND NOT APPROXIMATE -- "lnE", 0x02268, // LESS-THAN BUT NOT EQUAL TO -- "lne", 0x02A87, // LESS-THAN AND SINGLE-LINE NOT EQUAL TO -- "lneq", 0x02A87, // LESS-THAN AND SINGLE-LINE NOT EQUAL TO -- "lneqq", 0x02268, // LESS-THAN BUT NOT EQUAL TO -- "lnsim", 0x022E6, // LESS-THAN BUT NOT EQUIVALENT TO -- "loang", 0x027EC, // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET -- "loarr", 0x021FD, // LEFTWARDS OPEN-HEADED ARROW -- "lobrk", 0x027E6, // MATHEMATICAL LEFT WHITE SQUARE BRACKET -- "longleftarrow", 0x027F5, // LONG LEFTWARDS ARROW -- "LongLeftArrow", 0x027F5, // LONG LEFTWARDS ARROW -- "Longleftarrow", 0x027F8, // LONG LEFTWARDS DOUBLE ARROW -- "longleftrightarrow", 0x027F7, // LONG LEFT RIGHT ARROW -- "LongLeftRightArrow", 0x027F7, // LONG LEFT RIGHT ARROW -- "Longleftrightarrow", 0x027FA, // LONG LEFT RIGHT DOUBLE ARROW -- "longmapsto", 0x027FC, // LONG RIGHTWARDS ARROW FROM BAR -- "longrightarrow", 0x027F6, // LONG RIGHTWARDS ARROW -- "LongRightArrow", 0x027F6, // LONG RIGHTWARDS ARROW -- "Longrightarrow", 0x027F9, // LONG RIGHTWARDS DOUBLE ARROW -- "looparrowleft", 0x021AB, // LEFTWARDS ARROW WITH LOOP -- "looparrowright", 0x021AC, // RIGHTWARDS ARROW WITH LOOP -- "lopar", 0x02985, // LEFT WHITE PARENTHESIS -- "Lopf", 0x1D543, // MATHEMATICAL DOUBLE-STRUCK CAPITAL L -- "lopf", 0x1D55D, // MATHEMATICAL DOUBLE-STRUCK SMALL L -- "loplus", 0x02A2D, // PLUS SIGN IN LEFT HALF CIRCLE -- "lotimes", 0x02A34, // MULTIPLICATION SIGN IN LEFT HALF CIRCLE -- "lowast", 0x02217, // ASTERISK OPERATOR -- "lowbar", 0x0005F, // LOW LINE -- "LowerLeftArrow", 0x02199, // SOUTH WEST ARROW -- "LowerRightArrow", 0x02198, // SOUTH EAST ARROW -- "loz", 0x025CA, // LOZENGE -- "lozenge", 0x025CA, // LOZENGE -- "lozf", 0x029EB, // BLACK LOZENGE -- "lpar", 0x00028, // LEFT PARENTHESIS -- "lparlt", 0x02993, // LEFT ARC LESS-THAN BRACKET -- "lrarr", 0x021C6, // LEFTWARDS ARROW OVER RIGHTWARDS ARROW -- "lrcorner", 0x0231F, // BOTTOM RIGHT CORNER -- "lrhar", 0x021CB, // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -- "lrhard", 0x0296D, // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH -- "lrm", 0x0200E, // LEFT-TO-RIGHT MARK -- "lrtri", 0x022BF, // RIGHT TRIANGLE -- "lsaquo", 0x02039, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK -- "Lscr", 0x02112, // SCRIPT CAPITAL L -- "lscr", 0x1D4C1, // MATHEMATICAL SCRIPT SMALL L -- "lsh", 0x021B0, // UPWARDS ARROW WITH TIP LEFTWARDS -- "Lsh", 0x021B0, // UPWARDS ARROW WITH TIP LEFTWARDS -- "lsim", 0x02272, // LESS-THAN OR EQUIVALENT TO -- "lsime", 0x02A8D, // LESS-THAN ABOVE SIMILAR OR EQUAL -- "lsimg", 0x02A8F, // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN -- "lsqb", 0x0005B, // LEFT SQUARE BRACKET -- "lsquo", 0x02018, // LEFT SINGLE QUOTATION MARK -- "lsquor", 0x0201A, // SINGLE LOW-9 QUOTATION MARK -- "Lstrok", 0x00141, // LATIN CAPITAL LETTER L WITH STROKE -- "lstrok", 0x00142, // LATIN SMALL LETTER L WITH STROKE -- "lt", 0x0003C, // LESS-THAN SIGN -- "LT", 0x0003C, // LESS-THAN SIGN -- "Lt", 0x0226A, // MUCH LESS-THAN -- "ltcc", 0x02AA6, // LESS-THAN CLOSED BY CURVE -- "ltcir", 0x02A79, // LESS-THAN WITH CIRCLE INSIDE -- "ltdot", 0x022D6, // LESS-THAN WITH DOT -- "lthree", 0x022CB, // LEFT SEMIDIRECT PRODUCT -- "ltimes", 0x022C9, // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT -- "ltlarr", 0x02976, // LESS-THAN ABOVE LEFTWARDS ARROW -- "ltquest", 0x02A7B, // LESS-THAN WITH QUESTION MARK ABOVE -- "ltri", 0x025C3, // WHITE LEFT-POINTING SMALL TRIANGLE -- "ltrie", 0x022B4, // NORMAL SUBGROUP OF OR EQUAL TO -- "ltrif", 0x025C2, // BLACK LEFT-POINTING SMALL TRIANGLE -- "ltrPar", 0x02996, // DOUBLE RIGHT ARC LESS-THAN BRACKET -- "lurdshar", 0x0294A, // LEFT BARB UP RIGHT BARB DOWN HARPOON -- "luruhar", 0x02966, // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP --// "lvertneqq", 0x02268;0x0FE00, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke --// "lvnE", 0x02268;0x0FE00, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke -- NULL, 0 -+ {"lAarr", 0x021DA}, // LEFTWARDS TRIPLE ARROW -+ {"Lacute", 0x00139}, // LATIN CAPITAL LETTER L WITH ACUTE -+ {"lacute", 0x0013A}, // LATIN SMALL LETTER L WITH ACUTE -+ {"laemptyv", 0x029B4}, // EMPTY SET WITH LEFT ARROW ABOVE -+ {"lagran", 0x02112}, // SCRIPT CAPITAL L -+ {"Lambda", 0x0039B}, // GREEK CAPITAL LETTER LAMDA -+ {"lambda", 0x003BB}, // GREEK SMALL LETTER LAMDA -+ {"lang", 0x027E8}, // MATHEMATICAL LEFT ANGLE BRACKET -+ {"Lang", 0x027EA}, // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET -+ {"langd", 0x02991}, // LEFT ANGLE BRACKET WITH DOT -+ {"langle", 0x027E8}, // MATHEMATICAL LEFT ANGLE BRACKET -+ {"lap", 0x02A85}, // LESS-THAN OR APPROXIMATE -+ {"Laplacetrf", 0x02112}, // SCRIPT CAPITAL L -+ {"laquo", 0x000AB}, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -+ {"larr", 0x02190}, // LEFTWARDS ARROW -+ {"Larr", 0x0219E}, // LEFTWARDS TWO HEADED ARROW -+ {"lArr", 0x021D0}, // LEFTWARDS DOUBLE ARROW -+ {"larrb", 0x021E4}, // LEFTWARDS ARROW TO BAR -+ {"larrbfs", 0x0291F}, // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND -+ {"larrfs", 0x0291D}, // LEFTWARDS ARROW TO BLACK DIAMOND -+ {"larrhk", 0x021A9}, // LEFTWARDS ARROW WITH HOOK -+ {"larrlp", 0x021AB}, // LEFTWARDS ARROW WITH LOOP -+ {"larrpl", 0x02939}, // LEFT-SIDE ARC ANTICLOCKWISE ARROW -+ {"larrsim", 0x02973}, // LEFTWARDS ARROW ABOVE TILDE OPERATOR -+ {"larrtl", 0x021A2}, // LEFTWARDS ARROW WITH TAIL -+ {"lat", 0x02AAB}, // LARGER THAN -+ {"latail", 0x02919}, // LEFTWARDS ARROW-TAIL -+ {"lAtail", 0x0291B}, // LEFTWARDS DOUBLE ARROW-TAIL -+ {"late", 0x02AAD}, // LARGER THAN OR EQUAL TO -+// "lates", 0x02AAD;0x0FE00}, // LARGER THAN OR slanted EQUAL -+ {"lbarr", 0x0290C}, // LEFTWARDS DOUBLE DASH ARROW -+ {"lBarr", 0x0290E}, // LEFTWARDS TRIPLE DASH ARROW -+ {"lbbrk", 0x02772}, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT -+ {"lbrace", 0x0007B}, // LEFT CURLY BRACKET -+ {"lbrack", 0x0005B}, // LEFT SQUARE BRACKET -+ {"lbrke", 0x0298B}, // LEFT SQUARE BRACKET WITH UNDERBAR -+ {"lbrksld", 0x0298F}, // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER -+ {"lbrkslu", 0x0298D}, // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER -+ {"Lcaron", 0x0013D}, // LATIN CAPITAL LETTER L WITH CARON -+ {"lcaron", 0x0013E}, // LATIN SMALL LETTER L WITH CARON -+ {"Lcedil", 0x0013B}, // LATIN CAPITAL LETTER L WITH CEDILLA -+ {"lcedil", 0x0013C}, // LATIN SMALL LETTER L WITH CEDILLA -+ {"lceil", 0x02308}, // LEFT CEILING -+ {"lcub", 0x0007B}, // LEFT CURLY BRACKET -+ {"Lcy", 0x0041B}, // CYRILLIC CAPITAL LETTER EL -+ {"lcy", 0x0043B}, // CYRILLIC SMALL LETTER EL -+ {"ldca", 0x02936}, // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS -+ {"ldquo", 0x0201C}, // LEFT DOUBLE QUOTATION MARK -+ {"ldquor", 0x0201E}, // DOUBLE LOW-9 QUOTATION MARK -+ {"ldrdhar", 0x02967}, // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN -+ {"ldrushar", 0x0294B}, // LEFT BARB DOWN RIGHT BARB UP HARPOON -+ {"ldsh", 0x021B2}, // DOWNWARDS ARROW WITH TIP LEFTWARDS -+ {"le", 0x02264}, // LESS-THAN OR EQUAL TO -+ {"lE", 0x02266}, // LESS-THAN OVER EQUAL TO -+ {"LeftAngleBracket", 0x027E8}, // MATHEMATICAL LEFT ANGLE BRACKET -+ {"leftarrow", 0x02190}, // LEFTWARDS ARROW -+ {"LeftArrow", 0x02190}, // LEFTWARDS ARROW -+ {"Leftarrow", 0x021D0}, // LEFTWARDS DOUBLE ARROW -+ {"LeftArrowBar", 0x021E4}, // LEFTWARDS ARROW TO BAR -+ {"LeftArrowRightArrow", 0x021C6}, // LEFTWARDS ARROW OVER RIGHTWARDS ARROW -+ {"leftarrowtail", 0x021A2}, // LEFTWARDS ARROW WITH TAIL -+ {"LeftCeiling", 0x02308}, // LEFT CEILING -+ {"LeftDoubleBracket", 0x027E6}, // MATHEMATICAL LEFT WHITE SQUARE BRACKET -+ {"LeftDownTeeVector", 0x02961}, // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR -+ {"LeftDownVector", 0x021C3}, // DOWNWARDS HARPOON WITH BARB LEFTWARDS -+ {"LeftDownVectorBar", 0x02959}, // DOWNWARDS HARPOON WITH BARB LEFT TO BAR -+ {"LeftFloor", 0x0230A}, // LEFT FLOOR -+ {"leftharpoondown", 0x021BD}, // LEFTWARDS HARPOON WITH BARB DOWNWARDS -+ {"leftharpoonup", 0x021BC}, // LEFTWARDS HARPOON WITH BARB UPWARDS -+ {"leftleftarrows", 0x021C7}, // LEFTWARDS PAIRED ARROWS -+ {"leftrightarrow", 0x02194}, // LEFT RIGHT ARROW -+ {"LeftRightArrow", 0x02194}, // LEFT RIGHT ARROW -+ {"Leftrightarrow", 0x021D4}, // LEFT RIGHT DOUBLE ARROW -+ {"leftrightarrows", 0x021C6}, // LEFTWARDS ARROW OVER RIGHTWARDS ARROW -+ {"leftrightharpoons", 0x021CB}, // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -+ {"leftrightsquigarrow", 0x021AD}, // LEFT RIGHT WAVE ARROW -+ {"LeftRightVector", 0x0294E}, // LEFT BARB UP RIGHT BARB UP HARPOON -+ {"LeftTee", 0x022A3}, // LEFT TACK -+ {"LeftTeeArrow", 0x021A4}, // LEFTWARDS ARROW FROM BAR -+ {"LeftTeeVector", 0x0295A}, // LEFTWARDS HARPOON WITH BARB UP FROM BAR -+ {"leftthreetimes", 0x022CB}, // LEFT SEMIDIRECT PRODUCT -+ {"LeftTriangle", 0x022B2}, // NORMAL SUBGROUP OF -+ {"LeftTriangleBar", 0x029CF}, // LEFT TRIANGLE BESIDE VERTICAL BAR -+ {"LeftTriangleEqual", 0x022B4}, // NORMAL SUBGROUP OF OR EQUAL TO -+ {"LeftUpDownVector", 0x02951}, // UP BARB LEFT DOWN BARB LEFT HARPOON -+ {"LeftUpTeeVector", 0x02960}, // UPWARDS HARPOON WITH BARB LEFT FROM BAR -+ {"LeftUpVector", 0x021BF}, // UPWARDS HARPOON WITH BARB LEFTWARDS -+ {"LeftUpVectorBar", 0x02958}, // UPWARDS HARPOON WITH BARB LEFT TO BAR -+ {"LeftVector", 0x021BC}, // LEFTWARDS HARPOON WITH BARB UPWARDS -+ {"LeftVectorBar", 0x02952}, // LEFTWARDS HARPOON WITH BARB UP TO BAR -+ {"leg", 0x022DA}, // LESS-THAN EQUAL TO OR GREATER-THAN -+ {"lEg", 0x02A8B}, // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN -+ {"leq", 0x02264}, // LESS-THAN OR EQUAL TO -+ {"leqq", 0x02266}, // LESS-THAN OVER EQUAL TO -+ {"leqslant", 0x02A7D}, // LESS-THAN OR SLANTED EQUAL TO -+ {"les", 0x02A7D}, // LESS-THAN OR SLANTED EQUAL TO -+ {"lescc", 0x02AA8}, // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL -+ {"lesdot", 0x02A7F}, // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE -+ {"lesdoto", 0x02A81}, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE -+ {"lesdotor", 0x02A83}, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT -+// "lesg", 0x022DA;0x0FE00}, // LESS-THAN slanted EQUAL TO OR GREATER-THAN -+ {"lesges", 0x02A93}, // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL -+ {"lessapprox", 0x02A85}, // LESS-THAN OR APPROXIMATE -+ {"lessdot", 0x022D6}, // LESS-THAN WITH DOT -+ {"lesseqgtr", 0x022DA}, // LESS-THAN EQUAL TO OR GREATER-THAN -+ {"lesseqqgtr", 0x02A8B}, // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN -+ {"LessEqualGreater", 0x022DA}, // LESS-THAN EQUAL TO OR GREATER-THAN -+ {"LessFullEqual", 0x02266}, // LESS-THAN OVER EQUAL TO -+ {"LessGreater", 0x02276}, // LESS-THAN OR GREATER-THAN -+ {"lessgtr", 0x02276}, // LESS-THAN OR GREATER-THAN -+ {"LessLess", 0x02AA1}, // DOUBLE NESTED LESS-THAN -+ {"lesssim", 0x02272}, // LESS-THAN OR EQUIVALENT TO -+ {"LessSlantEqual", 0x02A7D}, // LESS-THAN OR SLANTED EQUAL TO -+ {"LessTilde", 0x02272}, // LESS-THAN OR EQUIVALENT TO -+ {"lfisht", 0x0297C}, // LEFT FISH TAIL -+ {"lfloor", 0x0230A}, // LEFT FLOOR -+ {"Lfr", 0x1D50F}, // MATHEMATICAL FRAKTUR CAPITAL L -+ {"lfr", 0x1D529}, // MATHEMATICAL FRAKTUR SMALL L -+ {"lg", 0x02276}, // LESS-THAN OR GREATER-THAN -+ {"lgE", 0x02A91}, // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL -+ {"Lgr", 0x0039B}, // GREEK CAPITAL LETTER LAMDA -+ {"lgr", 0x003BB}, // GREEK SMALL LETTER LAMDA -+ {"lHar", 0x02962}, // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN -+ {"lhard", 0x021BD}, // LEFTWARDS HARPOON WITH BARB DOWNWARDS -+ {"lharu", 0x021BC}, // LEFTWARDS HARPOON WITH BARB UPWARDS -+ {"lharul", 0x0296A}, // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH -+ {"lhblk", 0x02584}, // LOWER HALF BLOCK -+ {"LJcy", 0x00409}, // CYRILLIC CAPITAL LETTER LJE -+ {"ljcy", 0x00459}, // CYRILLIC SMALL LETTER LJE -+ {"ll", 0x0226A}, // MUCH LESS-THAN -+ {"Ll", 0x022D8}, // VERY MUCH LESS-THAN -+ {"llarr", 0x021C7}, // LEFTWARDS PAIRED ARROWS -+ {"llcorner", 0x0231E}, // BOTTOM LEFT CORNER -+ {"Lleftarrow", 0x021DA}, // LEFTWARDS TRIPLE ARROW -+ {"llhard", 0x0296B}, // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH -+ {"lltri", 0x025FA}, // LOWER LEFT TRIANGLE -+ {"Lmidot", 0x0013F}, // LATIN CAPITAL LETTER L WITH MIDDLE DOT -+ {"lmidot", 0x00140}, // LATIN SMALL LETTER L WITH MIDDLE DOT -+ {"lmoust", 0x023B0}, // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION -+ {"lmoustache", 0x023B0}, // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION -+ {"lnap", 0x02A89}, // LESS-THAN AND NOT APPROXIMATE -+ {"lnapprox", 0x02A89}, // LESS-THAN AND NOT APPROXIMATE -+ {"lnE", 0x02268}, // LESS-THAN BUT NOT EQUAL TO -+ {"lne", 0x02A87}, // LESS-THAN AND SINGLE-LINE NOT EQUAL TO -+ {"lneq", 0x02A87}, // LESS-THAN AND SINGLE-LINE NOT EQUAL TO -+ {"lneqq", 0x02268}, // LESS-THAN BUT NOT EQUAL TO -+ {"lnsim", 0x022E6}, // LESS-THAN BUT NOT EQUIVALENT TO -+ {"loang", 0x027EC}, // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET -+ {"loarr", 0x021FD}, // LEFTWARDS OPEN-HEADED ARROW -+ {"lobrk", 0x027E6}, // MATHEMATICAL LEFT WHITE SQUARE BRACKET -+ {"longleftarrow", 0x027F5}, // LONG LEFTWARDS ARROW -+ {"LongLeftArrow", 0x027F5}, // LONG LEFTWARDS ARROW -+ {"Longleftarrow", 0x027F8}, // LONG LEFTWARDS DOUBLE ARROW -+ {"longleftrightarrow", 0x027F7}, // LONG LEFT RIGHT ARROW -+ {"LongLeftRightArrow", 0x027F7}, // LONG LEFT RIGHT ARROW -+ {"Longleftrightarrow", 0x027FA}, // LONG LEFT RIGHT DOUBLE ARROW -+ {"longmapsto", 0x027FC}, // LONG RIGHTWARDS ARROW FROM BAR -+ {"longrightarrow", 0x027F6}, // LONG RIGHTWARDS ARROW -+ {"LongRightArrow", 0x027F6}, // LONG RIGHTWARDS ARROW -+ {"Longrightarrow", 0x027F9}, // LONG RIGHTWARDS DOUBLE ARROW -+ {"looparrowleft", 0x021AB}, // LEFTWARDS ARROW WITH LOOP -+ {"looparrowright", 0x021AC}, // RIGHTWARDS ARROW WITH LOOP -+ {"lopar", 0x02985}, // LEFT WHITE PARENTHESIS -+ {"Lopf", 0x1D543}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL L -+ {"lopf", 0x1D55D}, // MATHEMATICAL DOUBLE-STRUCK SMALL L -+ {"loplus", 0x02A2D}, // PLUS SIGN IN LEFT HALF CIRCLE -+ {"lotimes", 0x02A34}, // MULTIPLICATION SIGN IN LEFT HALF CIRCLE -+ {"lowast", 0x02217}, // ASTERISK OPERATOR -+ {"lowbar", 0x0005F}, // LOW LINE -+ {"LowerLeftArrow", 0x02199}, // SOUTH WEST ARROW -+ {"LowerRightArrow", 0x02198}, // SOUTH EAST ARROW -+ {"loz", 0x025CA}, // LOZENGE -+ {"lozenge", 0x025CA}, // LOZENGE -+ {"lozf", 0x029EB}, // BLACK LOZENGE -+ {"lpar", 0x00028}, // LEFT PARENTHESIS -+ {"lparlt", 0x02993}, // LEFT ARC LESS-THAN BRACKET -+ {"lrarr", 0x021C6}, // LEFTWARDS ARROW OVER RIGHTWARDS ARROW -+ {"lrcorner", 0x0231F}, // BOTTOM RIGHT CORNER -+ {"lrhar", 0x021CB}, // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -+ {"lrhard", 0x0296D}, // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH -+ {"lrm", 0x0200E}, // LEFT-TO-RIGHT MARK -+ {"lrtri", 0x022BF}, // RIGHT TRIANGLE -+ {"lsaquo", 0x02039}, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK -+ {"Lscr", 0x02112}, // SCRIPT CAPITAL L -+ {"lscr", 0x1D4C1}, // MATHEMATICAL SCRIPT SMALL L -+ {"lsh", 0x021B0}, // UPWARDS ARROW WITH TIP LEFTWARDS -+ {"Lsh", 0x021B0}, // UPWARDS ARROW WITH TIP LEFTWARDS -+ {"lsim", 0x02272}, // LESS-THAN OR EQUIVALENT TO -+ {"lsime", 0x02A8D}, // LESS-THAN ABOVE SIMILAR OR EQUAL -+ {"lsimg", 0x02A8F}, // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN -+ {"lsqb", 0x0005B}, // LEFT SQUARE BRACKET -+ {"lsquo", 0x02018}, // LEFT SINGLE QUOTATION MARK -+ {"lsquor", 0x0201A}, // SINGLE LOW-9 QUOTATION MARK -+ {"Lstrok", 0x00141}, // LATIN CAPITAL LETTER L WITH STROKE -+ {"lstrok", 0x00142}, // LATIN SMALL LETTER L WITH STROKE -+ {"lt", 0x0003C}, // LESS-THAN SIGN -+ {"LT", 0x0003C}, // LESS-THAN SIGN -+ {"Lt", 0x0226A}, // MUCH LESS-THAN -+ {"ltcc", 0x02AA6}, // LESS-THAN CLOSED BY CURVE -+ {"ltcir", 0x02A79}, // LESS-THAN WITH CIRCLE INSIDE -+ {"ltdot", 0x022D6}, // LESS-THAN WITH DOT -+ {"lthree", 0x022CB}, // LEFT SEMIDIRECT PRODUCT -+ {"ltimes", 0x022C9}, // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT -+ {"ltlarr", 0x02976}, // LESS-THAN ABOVE LEFTWARDS ARROW -+ {"ltquest", 0x02A7B}, // LESS-THAN WITH QUESTION MARK ABOVE -+ {"ltri", 0x025C3}, // WHITE LEFT-POINTING SMALL TRIANGLE -+ {"ltrie", 0x022B4}, // NORMAL SUBGROUP OF OR EQUAL TO -+ {"ltrif", 0x025C2}, // BLACK LEFT-POINTING SMALL TRIANGLE -+ {"ltrPar", 0x02996}, // DOUBLE RIGHT ARC LESS-THAN BRACKET -+ {"lurdshar", 0x0294A}, // LEFT BARB UP RIGHT BARB DOWN HARPOON -+ {"luruhar", 0x02966}, // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP -+// "lvertneqq", 0x02268;0x0FE00}, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke -+// "lvnE", 0x02268;0x0FE00}, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke -+ {NULL, 0} - }; - - static NameId namesM[]={ -- "macr", 0x000AF, // MACRON -- "male", 0x02642, // MALE SIGN -- "malt", 0x02720, // MALTESE CROSS -- "maltese", 0x02720, // MALTESE CROSS -- "map", 0x021A6, // RIGHTWARDS ARROW FROM BAR -- "Map", 0x02905, // RIGHTWARDS TWO-HEADED ARROW FROM BAR -- "mapsto", 0x021A6, // RIGHTWARDS ARROW FROM BAR -- "mapstodown", 0x021A7, // DOWNWARDS ARROW FROM BAR -- "mapstoleft", 0x021A4, // LEFTWARDS ARROW FROM BAR -- "mapstoup", 0x021A5, // UPWARDS ARROW FROM BAR -- "marker", 0x025AE, // BLACK VERTICAL RECTANGLE -- "mcomma", 0x02A29, // MINUS SIGN WITH COMMA ABOVE -- "Mcy", 0x0041C, // CYRILLIC CAPITAL LETTER EM -- "mcy", 0x0043C, // CYRILLIC SMALL LETTER EM -- "mdash", 0x02014, // EM DASH -- "mDDot", 0x0223A, // GEOMETRIC PROPORTION -- "measuredangle", 0x02221, // MEASURED ANGLE -- "MediumSpace", 0x0205F, // MEDIUM MATHEMATICAL SPACE -- "Mellintrf", 0x02133, // SCRIPT CAPITAL M -- "Mfr", 0x1D510, // MATHEMATICAL FRAKTUR CAPITAL M -- "mfr", 0x1D52A, // MATHEMATICAL FRAKTUR SMALL M -- "Mgr", 0x0039C, // GREEK CAPITAL LETTER MU -- "mgr", 0x003BC, // GREEK SMALL LETTER MU -- "mho", 0x02127, // INVERTED OHM SIGN -- "micro", 0x000B5, // MICRO SIGN -- "mid", 0x02223, // DIVIDES -- "midast", 0x0002A, // ASTERISK -- "midcir", 0x02AF0, // VERTICAL LINE WITH CIRCLE BELOW -- "middot", 0x000B7, // MIDDLE DOT -- "minus", 0x02212, // MINUS SIGN -- "minusb", 0x0229F, // SQUARED MINUS -- "minusd", 0x02238, // DOT MINUS -- "minusdu", 0x02A2A, // MINUS SIGN WITH DOT BELOW -- "MinusPlus", 0x02213, // MINUS-OR-PLUS SIGN -- "mlcp", 0x02ADB, // TRANSVERSAL INTERSECTION -- "mldr", 0x02026, // HORIZONTAL ELLIPSIS -- "mnplus", 0x02213, // MINUS-OR-PLUS SIGN -- "models", 0x022A7, // MODELS -- "Mopf", 0x1D544, // MATHEMATICAL DOUBLE-STRUCK CAPITAL M -- "mopf", 0x1D55E, // MATHEMATICAL DOUBLE-STRUCK SMALL M -- "mp", 0x02213, // MINUS-OR-PLUS SIGN -- "Mscr", 0x02133, // SCRIPT CAPITAL M -- "mscr", 0x1D4C2, // MATHEMATICAL SCRIPT SMALL M -- "mstpos", 0x0223E, // INVERTED LAZY S -- "Mu", 0x0039C, // GREEK CAPITAL LETTER MU -- "mu", 0x003BC, // GREEK SMALL LETTER MU -- "multimap", 0x022B8, // MULTIMAP -- "mumap", 0x022B8, // MULTIMAP -- NULL, 0 -+ {"macr", 0x000AF}, // MACRON -+ {"male", 0x02642}, // MALE SIGN -+ {"malt", 0x02720}, // MALTESE CROSS -+ {"maltese", 0x02720}, // MALTESE CROSS -+ {"map", 0x021A6}, // RIGHTWARDS ARROW FROM BAR -+ {"Map", 0x02905}, // RIGHTWARDS TWO-HEADED ARROW FROM BAR -+ {"mapsto", 0x021A6}, // RIGHTWARDS ARROW FROM BAR -+ {"mapstodown", 0x021A7}, // DOWNWARDS ARROW FROM BAR -+ {"mapstoleft", 0x021A4}, // LEFTWARDS ARROW FROM BAR -+ {"mapstoup", 0x021A5}, // UPWARDS ARROW FROM BAR -+ {"marker", 0x025AE}, // BLACK VERTICAL RECTANGLE -+ {"mcomma", 0x02A29}, // MINUS SIGN WITH COMMA ABOVE -+ {"Mcy", 0x0041C}, // CYRILLIC CAPITAL LETTER EM -+ {"mcy", 0x0043C}, // CYRILLIC SMALL LETTER EM -+ {"mdash", 0x02014}, // EM DASH -+ {"mDDot", 0x0223A}, // GEOMETRIC PROPORTION -+ {"measuredangle", 0x02221}, // MEASURED ANGLE -+ {"MediumSpace", 0x0205F}, // MEDIUM MATHEMATICAL SPACE -+ {"Mellintrf", 0x02133}, // SCRIPT CAPITAL M -+ {"Mfr", 0x1D510}, // MATHEMATICAL FRAKTUR CAPITAL M -+ {"mfr", 0x1D52A}, // MATHEMATICAL FRAKTUR SMALL M -+ {"Mgr", 0x0039C}, // GREEK CAPITAL LETTER MU -+ {"mgr", 0x003BC}, // GREEK SMALL LETTER MU -+ {"mho", 0x02127}, // INVERTED OHM SIGN -+ {"micro", 0x000B5}, // MICRO SIGN -+ {"mid", 0x02223}, // DIVIDES -+ {"midast", 0x0002A}, // ASTERISK -+ {"midcir", 0x02AF0}, // VERTICAL LINE WITH CIRCLE BELOW -+ {"middot", 0x000B7}, // MIDDLE DOT -+ {"minus", 0x02212}, // MINUS SIGN -+ {"minusb", 0x0229F}, // SQUARED MINUS -+ {"minusd", 0x02238}, // DOT MINUS -+ {"minusdu", 0x02A2A}, // MINUS SIGN WITH DOT BELOW -+ {"MinusPlus", 0x02213}, // MINUS-OR-PLUS SIGN -+ {"mlcp", 0x02ADB}, // TRANSVERSAL INTERSECTION -+ {"mldr", 0x02026}, // HORIZONTAL ELLIPSIS -+ {"mnplus", 0x02213}, // MINUS-OR-PLUS SIGN -+ {"models", 0x022A7}, // MODELS -+ {"Mopf", 0x1D544}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL M -+ {"mopf", 0x1D55E}, // MATHEMATICAL DOUBLE-STRUCK SMALL M -+ {"mp", 0x02213}, // MINUS-OR-PLUS SIGN -+ {"Mscr", 0x02133}, // SCRIPT CAPITAL M -+ {"mscr", 0x1D4C2}, // MATHEMATICAL SCRIPT SMALL M -+ {"mstpos", 0x0223E}, // INVERTED LAZY S -+ {"Mu", 0x0039C}, // GREEK CAPITAL LETTER MU -+ {"mu", 0x003BC}, // GREEK SMALL LETTER MU -+ {"multimap", 0x022B8}, // MULTIMAP -+ {"mumap", 0x022B8}, // MULTIMAP -+ {NULL, 0} - }; - - static NameId namesN[]={ -- "nabla", 0x02207, // NABLA -- "Nacute", 0x00143, // LATIN CAPITAL LETTER N WITH ACUTE -- "nacute", 0x00144, // LATIN SMALL LETTER N WITH ACUTE --// "nang", 0x02220;0x020D2, // ANGLE with vertical line -- "nap", 0x02249, // NOT ALMOST EQUAL TO --// "napE", 0x02A70;0x00338, // APPROXIMATELY EQUAL OR EQUAL TO with slash --// "napid", 0x0224B;0x00338, // TRIPLE TILDE with slash -- "napos", 0x00149, // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -- "napprox", 0x02249, // NOT ALMOST EQUAL TO -- "natur", 0x0266E, // MUSIC NATURAL SIGN -- "natural", 0x0266E, // MUSIC NATURAL SIGN -- "naturals", 0x02115, // DOUBLE-STRUCK CAPITAL N -- "nbsp", 0x000A0, // NO-BREAK SPACE --// "nbump", 0x0224E;0x00338, // GEOMETRICALLY EQUIVALENT TO with slash --// "nbumpe", 0x0224F;0x00338, // DIFFERENCE BETWEEN with slash -- "ncap", 0x02A43, // INTERSECTION WITH OVERBAR -- "Ncaron", 0x00147, // LATIN CAPITAL LETTER N WITH CARON -- "ncaron", 0x00148, // LATIN SMALL LETTER N WITH CARON -- "Ncedil", 0x00145, // LATIN CAPITAL LETTER N WITH CEDILLA -- "ncedil", 0x00146, // LATIN SMALL LETTER N WITH CEDILLA -- "ncong", 0x02247, // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO --// "ncongdot", 0x02A6D;0x00338, // CONGRUENT WITH DOT ABOVE with slash -- "ncup", 0x02A42, // UNION WITH OVERBAR -- "Ncy", 0x0041D, // CYRILLIC CAPITAL LETTER EN -- "ncy", 0x0043D, // CYRILLIC SMALL LETTER EN -- "ndash", 0x02013, // EN DASH -- "ne", 0x02260, // NOT EQUAL TO -- "nearhk", 0x02924, // NORTH EAST ARROW WITH HOOK -- "nearr", 0x02197, // NORTH EAST ARROW -- "neArr", 0x021D7, // NORTH EAST DOUBLE ARROW -- "nearrow", 0x02197, // NORTH EAST ARROW --// "nedot", 0x02250;0x00338, // APPROACHES THE LIMIT with slash -- "NegativeMediumSpace", 0x0200B, // ZERO WIDTH SPACE -- "NegativeThickSpace", 0x0200B, // ZERO WIDTH SPACE -- "NegativeThinSpace", 0x0200B, // ZERO WIDTH SPACE -- "NegativeVeryThinSpace", 0x0200B, // ZERO WIDTH SPACE -- "nequiv", 0x02262, // NOT IDENTICAL TO -- "nesear", 0x02928, // NORTH EAST ARROW AND SOUTH EAST ARROW --// "nesim", 0x02242;0x00338, // MINUS TILDE with slash -- "NestedGreaterGreater", 0x0226B, // MUCH GREATER-THAN -- "NestedLessLess", 0x0226A, // MUCH LESS-THAN -- "NewLine", 0x0000A, // LINE FEED (LF) -- "nexist", 0x02204, // THERE DOES NOT EXIST -- "nexists", 0x02204, // THERE DOES NOT EXIST -- "Nfr", 0x1D511, // MATHEMATICAL FRAKTUR CAPITAL N -- "nfr", 0x1D52B, // MATHEMATICAL FRAKTUR SMALL N --// "ngE", 0x02267;0x00338, // GREATER-THAN OVER EQUAL TO with slash -- "nge", 0x02271, // NEITHER GREATER-THAN NOR EQUAL TO -- "ngeq", 0x02271, // NEITHER GREATER-THAN NOR EQUAL TO --// "ngeqq", 0x02267;0x00338, // GREATER-THAN OVER EQUAL TO with slash --// "ngeqslant", 0x02A7E;0x00338, // GREATER-THAN OR SLANTED EQUAL TO with slash --// "nges", 0x02A7E;0x00338, // GREATER-THAN OR SLANTED EQUAL TO with slash --// "nGg", 0x022D9;0x00338, // VERY MUCH GREATER-THAN with slash -- "Ngr", 0x0039D, // GREEK CAPITAL LETTER NU -- "ngr", 0x003BD, // GREEK SMALL LETTER NU -- "ngsim", 0x02275, // NEITHER GREATER-THAN NOR EQUIVALENT TO --// "nGt", 0x0226B;0x020D2, // MUCH GREATER THAN with vertical line -- "ngt", 0x0226F, // NOT GREATER-THAN -- "ngtr", 0x0226F, // NOT GREATER-THAN --// "nGtv", 0x0226B;0x00338, // MUCH GREATER THAN with slash -- "nharr", 0x021AE, // LEFT RIGHT ARROW WITH STROKE -- "nhArr", 0x021CE, // LEFT RIGHT DOUBLE ARROW WITH STROKE -- "nhpar", 0x02AF2, // PARALLEL WITH HORIZONTAL STROKE -- "ni", 0x0220B, // CONTAINS AS MEMBER -- "nis", 0x022FC, // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -- "nisd", 0x022FA, // CONTAINS WITH LONG HORIZONTAL STROKE -- "niv", 0x0220B, // CONTAINS AS MEMBER -- "NJcy", 0x0040A, // CYRILLIC CAPITAL LETTER NJE -- "njcy", 0x0045A, // CYRILLIC SMALL LETTER NJE -- "nlarr", 0x0219A, // LEFTWARDS ARROW WITH STROKE -- "nlArr", 0x021CD, // LEFTWARDS DOUBLE ARROW WITH STROKE -- "nldr", 0x02025, // TWO DOT LEADER --// "nlE", 0x02266;0x00338, // LESS-THAN OVER EQUAL TO with slash -- "nle", 0x02270, // NEITHER LESS-THAN NOR EQUAL TO -- "nleftarrow", 0x0219A, // LEFTWARDS ARROW WITH STROKE -- "nLeftarrow", 0x021CD, // LEFTWARDS DOUBLE ARROW WITH STROKE -- "nleftrightarrow", 0x021AE, // LEFT RIGHT ARROW WITH STROKE -- "nLeftrightarrow", 0x021CE, // LEFT RIGHT DOUBLE ARROW WITH STROKE -- "nleq", 0x02270, // NEITHER LESS-THAN NOR EQUAL TO --// "nleqq", 0x02266;0x00338, // LESS-THAN OVER EQUAL TO with slash --// "nleqslant", 0x02A7D;0x00338, // LESS-THAN OR SLANTED EQUAL TO with slash --// "nles", 0x02A7D;0x00338, // LESS-THAN OR SLANTED EQUAL TO with slash -- "nless", 0x0226E, // NOT LESS-THAN --// "nLl", 0x022D8;0x00338, // VERY MUCH LESS-THAN with slash -- "nlsim", 0x02274, // NEITHER LESS-THAN NOR EQUIVALENT TO --// "nLt", 0x0226A;0x020D2, // MUCH LESS THAN with vertical line -- "nlt", 0x0226E, // NOT LESS-THAN -- "nltri", 0x022EA, // NOT NORMAL SUBGROUP OF -- "nltrie", 0x022EC, // NOT NORMAL SUBGROUP OF OR EQUAL TO --// "nLtv", 0x0226A;0x00338, // MUCH LESS THAN with slash -- "nmid", 0x02224, // DOES NOT DIVIDE -- "NoBreak", 0x02060, // WORD JOINER -- "NonBreakingSpace", 0x000A0, // NO-BREAK SPACE -- "Nopf", 0x02115, // DOUBLE-STRUCK CAPITAL N -- "nopf", 0x1D55F, // MATHEMATICAL DOUBLE-STRUCK SMALL N -- "not", 0x000AC, // NOT SIGN -- "Not", 0x02AEC, // DOUBLE STROKE NOT SIGN -- "NotCongruent", 0x02262, // NOT IDENTICAL TO -- "NotCupCap", 0x0226D, // NOT EQUIVALENT TO -- "NotDoubleVerticalBar", 0x02226, // NOT PARALLEL TO -- "NotElement", 0x02209, // NOT AN ELEMENT OF -- "NotEqual", 0x02260, // NOT EQUAL TO --// "NotEqualTilde", 0x02242;0x00338, // MINUS TILDE with slash -- "NotExists", 0x02204, // THERE DOES NOT EXIST -- "NotGreater", 0x0226F, // NOT GREATER-THAN -- "NotGreaterEqual", 0x02271, // NEITHER GREATER-THAN NOR EQUAL TO --// "NotGreaterFullEqual", 0x02267;0x00338, // GREATER-THAN OVER EQUAL TO with slash --// "NotGreaterGreater", 0x0226B;0x00338, // MUCH GREATER THAN with slash -- "NotGreaterLess", 0x02279, // NEITHER GREATER-THAN NOR LESS-THAN --// "NotGreaterSlantEqual", 0x02A7E;0x00338, // GREATER-THAN OR SLANTED EQUAL TO with slash -- "NotGreaterTilde", 0x02275, // NEITHER GREATER-THAN NOR EQUIVALENT TO --// "NotHumpDownHump", 0x0224E;0x00338, // GEOMETRICALLY EQUIVALENT TO with slash --// "NotHumpEqual", 0x0224F;0x00338, // DIFFERENCE BETWEEN with slash -- "notin", 0x02209, // NOT AN ELEMENT OF --// "notindot", 0x022F5;0x00338, // ELEMENT OF WITH DOT ABOVE with slash --// "notinE", 0x022F9;0x00338, // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash -- "notinva", 0x02209, // NOT AN ELEMENT OF -- "notinvb", 0x022F7, // SMALL ELEMENT OF WITH OVERBAR -- "notinvc", 0x022F6, // ELEMENT OF WITH OVERBAR -- "NotLeftTriangle", 0x022EA, // NOT NORMAL SUBGROUP OF --// "NotLeftTriangleBar", 0x029CF;0x00338, // LEFT TRIANGLE BESIDE VERTICAL BAR with slash -- "NotLeftTriangleEqual", 0x022EC, // NOT NORMAL SUBGROUP OF OR EQUAL TO -- "NotLess", 0x0226E, // NOT LESS-THAN -- "NotLessEqual", 0x02270, // NEITHER LESS-THAN NOR EQUAL TO -- "NotLessGreater", 0x02278, // NEITHER LESS-THAN NOR GREATER-THAN --// "NotLessLess", 0x0226A;0x00338, // MUCH LESS THAN with slash --// "NotLessSlantEqual", 0x02A7D;0x00338, // LESS-THAN OR SLANTED EQUAL TO with slash -- "NotLessTilde", 0x02274, // NEITHER LESS-THAN NOR EQUIVALENT TO --// "NotNestedGreaterGreater", 0x02AA2;0x00338, // DOUBLE NESTED GREATER-THAN with slash --// "NotNestedLessLess", 0x02AA1;0x00338, // DOUBLE NESTED LESS-THAN with slash -- "notni", 0x0220C, // DOES NOT CONTAIN AS MEMBER -- "notniva", 0x0220C, // DOES NOT CONTAIN AS MEMBER -- "notnivb", 0x022FE, // SMALL CONTAINS WITH OVERBAR -- "notnivc", 0x022FD, // CONTAINS WITH OVERBAR -- "NotPrecedes", 0x02280, // DOES NOT PRECEDE --// "NotPrecedesEqual", 0x02AAF;0x00338, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash -- "NotPrecedesSlantEqual", 0x022E0, // DOES NOT PRECEDE OR EQUAL -- "NotReverseElement", 0x0220C, // DOES NOT CONTAIN AS MEMBER -- "NotRightTriangle", 0x022EB, // DOES NOT CONTAIN AS NORMAL SUBGROUP --// "NotRightTriangleBar", 0x029D0;0x00338, // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash -- "NotRightTriangleEqual", 0x022ED, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL --// "NotSquareSubset", 0x0228F;0x00338, // SQUARE IMAGE OF with slash -- "NotSquareSubsetEqual", 0x022E2, // NOT SQUARE IMAGE OF OR EQUAL TO --// "NotSquareSuperset", 0x02290;0x00338, // SQUARE ORIGINAL OF with slash -- "NotSquareSupersetEqual", 0x022E3, // NOT SQUARE ORIGINAL OF OR EQUAL TO --// "NotSubset", 0x02282;0x020D2, // SUBSET OF with vertical line -- "NotSubsetEqual", 0x02288, // NEITHER A SUBSET OF NOR EQUAL TO -- "NotSucceeds", 0x02281, // DOES NOT SUCCEED --// "NotSucceedsEqual", 0x02AB0;0x00338, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash -- "NotSucceedsSlantEqual", 0x022E1, // DOES NOT SUCCEED OR EQUAL --// "NotSucceedsTilde", 0x0227F;0x00338, // SUCCEEDS OR EQUIVALENT TO with slash --// "NotSuperset", 0x02283;0x020D2, // SUPERSET OF with vertical line -- "NotSupersetEqual", 0x02289, // NEITHER A SUPERSET OF NOR EQUAL TO -- "NotTilde", 0x02241, // NOT TILDE -- "NotTildeEqual", 0x02244, // NOT ASYMPTOTICALLY EQUAL TO -- "NotTildeFullEqual", 0x02247, // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO -- "NotTildeTilde", 0x02249, // NOT ALMOST EQUAL TO -- "NotVerticalBar", 0x02224, // DOES NOT DIVIDE -- "npar", 0x02226, // NOT PARALLEL TO -- "nparallel", 0x02226, // NOT PARALLEL TO --// "nparsl", 0x02AFD;0x020E5, // DOUBLE SOLIDUS OPERATOR with reverse slash --// "npart", 0x02202;0x00338, // PARTIAL DIFFERENTIAL with slash -- "npolint", 0x02A14, // LINE INTEGRATION NOT INCLUDING THE POLE -- "npr", 0x02280, // DOES NOT PRECEDE -- "nprcue", 0x022E0, // DOES NOT PRECEDE OR EQUAL --// "npre", 0x02AAF;0x00338, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash -- "nprec", 0x02280, // DOES NOT PRECEDE --// "npreceq", 0x02AAF;0x00338, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash -- "nrarr", 0x0219B, // RIGHTWARDS ARROW WITH STROKE -- "nrArr", 0x021CF, // RIGHTWARDS DOUBLE ARROW WITH STROKE --// "nrarrc", 0x02933;0x00338, // WAVE ARROW POINTING DIRECTLY RIGHT with slash --// "nrarrw", 0x0219D;0x00338, // RIGHTWARDS WAVE ARROW with slash -- "nrightarrow", 0x0219B, // RIGHTWARDS ARROW WITH STROKE -- "nRightarrow", 0x021CF, // RIGHTWARDS DOUBLE ARROW WITH STROKE -- "nrtri", 0x022EB, // DOES NOT CONTAIN AS NORMAL SUBGROUP -- "nrtrie", 0x022ED, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -- "nsc", 0x02281, // DOES NOT SUCCEED -- "nsccue", 0x022E1, // DOES NOT SUCCEED OR EQUAL --// "nsce", 0x02AB0;0x00338, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash -- "Nscr", 0x1D4A9, // MATHEMATICAL SCRIPT CAPITAL N -- "nscr", 0x1D4C3, // MATHEMATICAL SCRIPT SMALL N -- "nshortmid", 0x02224, // DOES NOT DIVIDE -- "nshortparallel", 0x02226, // NOT PARALLEL TO -- "nsim", 0x02241, // NOT TILDE -- "nsime", 0x02244, // NOT ASYMPTOTICALLY EQUAL TO -- "nsimeq", 0x02244, // NOT ASYMPTOTICALLY EQUAL TO -- "nsmid", 0x02224, // DOES NOT DIVIDE -- "nspar", 0x02226, // NOT PARALLEL TO -- "nsqsube", 0x022E2, // NOT SQUARE IMAGE OF OR EQUAL TO -- "nsqsupe", 0x022E3, // NOT SQUARE ORIGINAL OF OR EQUAL TO -- "nsub", 0x02284, // NOT A SUBSET OF -- "nsube", 0x02288, // NEITHER A SUBSET OF NOR EQUAL TO --// "nsubE", 0x02AC5;0x00338, // SUBSET OF ABOVE EQUALS SIGN with slash --// "nsubset", 0x02282;0x020D2, // SUBSET OF with vertical line -- "nsubseteq", 0x02288, // NEITHER A SUBSET OF NOR EQUAL TO --// "nsubseteqq", 0x02AC5;0x00338, // SUBSET OF ABOVE EQUALS SIGN with slash -- "nsucc", 0x02281, // DOES NOT SUCCEED --// "nsucceq", 0x02AB0;0x00338, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash -- "nsup", 0x02285, // NOT A SUPERSET OF -- "nsupe", 0x02289, // NEITHER A SUPERSET OF NOR EQUAL TO --// "nsupE", 0x02AC6;0x00338, // SUPERSET OF ABOVE EQUALS SIGN with slash --// "nsupset", 0x02283;0x020D2, // SUPERSET OF with vertical line -- "nsupseteq", 0x02289, // NEITHER A SUPERSET OF NOR EQUAL TO --// "nsupseteqq", 0x02AC6;0x00338, // SUPERSET OF ABOVE EQUALS SIGN with slash -- "ntgl", 0x02279, // NEITHER GREATER-THAN NOR LESS-THAN -- "Ntilde", 0x000D1, // LATIN CAPITAL LETTER N WITH TILDE -- "ntilde", 0x000F1, // LATIN SMALL LETTER N WITH TILDE -- "ntlg", 0x02278, // NEITHER LESS-THAN NOR GREATER-THAN -- "ntriangleleft", 0x022EA, // NOT NORMAL SUBGROUP OF -- "ntrianglelefteq", 0x022EC, // NOT NORMAL SUBGROUP OF OR EQUAL TO -- "ntriangleright", 0x022EB, // DOES NOT CONTAIN AS NORMAL SUBGROUP -- "ntrianglerighteq", 0x022ED, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -- "Nu", 0x0039D, // GREEK CAPITAL LETTER NU -- "nu", 0x003BD, // GREEK SMALL LETTER NU -- "num", 0x00023, // NUMBER SIGN -- "numero", 0x02116, // NUMERO SIGN -- "numsp", 0x02007, // FIGURE SPACE --// "nvap", 0x0224D;0x020D2, // EQUIVALENT TO with vertical line -- "nvdash", 0x022AC, // DOES NOT PROVE -- "nvDash", 0x022AD, // NOT TRUE -- "nVdash", 0x022AE, // DOES NOT FORCE -- "nVDash", 0x022AF, // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE --// "nvge", 0x02265;0x020D2, // GREATER-THAN OR EQUAL TO with vertical line --// "nvgt", 0x0003E;0x020D2, // GREATER-THAN SIGN with vertical line -- "nvHarr", 0x02904, // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE -- "nvinfin", 0x029DE, // INFINITY NEGATED WITH VERTICAL BAR -- "nvlArr", 0x02902, // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE --// "nvle", 0x02264;0x020D2, // LESS-THAN OR EQUAL TO with vertical line --// "nvlt", 0x0003C;0x020D2, // LESS-THAN SIGN with vertical line --// "nvltrie", 0x022B4;0x020D2, // NORMAL SUBGROUP OF OR EQUAL TO with vertical line -- "nvrArr", 0x02903, // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE --// "nvrtrie", 0x022B5;0x020D2, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line --// "nvsim", 0x0223C;0x020D2, // TILDE OPERATOR with vertical line -- "nwarhk", 0x02923, // NORTH WEST ARROW WITH HOOK -- "nwarr", 0x02196, // NORTH WEST ARROW -- "nwArr", 0x021D6, // NORTH WEST DOUBLE ARROW -- "nwarrow", 0x02196, // NORTH WEST ARROW -- "nwnear", 0x02927, // NORTH WEST ARROW AND NORTH EAST ARROW -- NULL, 0 -+ {"nabla", 0x02207}, // NABLA -+ {"Nacute", 0x00143}, // LATIN CAPITAL LETTER N WITH ACUTE -+ {"nacute", 0x00144}, // LATIN SMALL LETTER N WITH ACUTE -+// "nang", 0x02220;0x020D2}, // ANGLE with vertical line -+ {"nap", 0x02249}, // NOT ALMOST EQUAL TO -+// "napE", 0x02A70;0x00338}, // APPROXIMATELY EQUAL OR EQUAL TO with slash -+// "napid", 0x0224B;0x00338}, // TRIPLE TILDE with slash -+ {"napos", 0x00149}, // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -+ {"napprox", 0x02249}, // NOT ALMOST EQUAL TO -+ {"natur", 0x0266E}, // MUSIC NATURAL SIGN -+ {"natural", 0x0266E}, // MUSIC NATURAL SIGN -+ {"naturals", 0x02115}, // DOUBLE-STRUCK CAPITAL N -+ {"nbsp", 0x000A0}, // NO-BREAK SPACE -+// "nbump", 0x0224E;0x00338}, // GEOMETRICALLY EQUIVALENT TO with slash -+// "nbumpe", 0x0224F;0x00338}, // DIFFERENCE BETWEEN with slash -+ {"ncap", 0x02A43}, // INTERSECTION WITH OVERBAR -+ {"Ncaron", 0x00147}, // LATIN CAPITAL LETTER N WITH CARON -+ {"ncaron", 0x00148}, // LATIN SMALL LETTER N WITH CARON -+ {"Ncedil", 0x00145}, // LATIN CAPITAL LETTER N WITH CEDILLA -+ {"ncedil", 0x00146}, // LATIN SMALL LETTER N WITH CEDILLA -+ {"ncong", 0x02247}, // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO -+// "ncongdot", 0x02A6D;0x00338}, // CONGRUENT WITH DOT ABOVE with slash -+ {"ncup", 0x02A42}, // UNION WITH OVERBAR -+ {"Ncy", 0x0041D}, // CYRILLIC CAPITAL LETTER EN -+ {"ncy", 0x0043D}, // CYRILLIC SMALL LETTER EN -+ {"ndash", 0x02013}, // EN DASH -+ {"ne", 0x02260}, // NOT EQUAL TO -+ {"nearhk", 0x02924}, // NORTH EAST ARROW WITH HOOK -+ {"nearr", 0x02197}, // NORTH EAST ARROW -+ {"neArr", 0x021D7}, // NORTH EAST DOUBLE ARROW -+ {"nearrow", 0x02197}, // NORTH EAST ARROW -+// "nedot", 0x02250;0x00338}, // APPROACHES THE LIMIT with slash -+ {"NegativeMediumSpace", 0x0200B}, // ZERO WIDTH SPACE -+ {"NegativeThickSpace", 0x0200B}, // ZERO WIDTH SPACE -+ {"NegativeThinSpace", 0x0200B}, // ZERO WIDTH SPACE -+ {"NegativeVeryThinSpace", 0x0200B}, // ZERO WIDTH SPACE -+ {"nequiv", 0x02262}, // NOT IDENTICAL TO -+ {"nesear", 0x02928}, // NORTH EAST ARROW AND SOUTH EAST ARROW -+// "nesim", 0x02242;0x00338}, // MINUS TILDE with slash -+ {"NestedGreaterGreater", 0x0226B}, // MUCH GREATER-THAN -+ {"NestedLessLess", 0x0226A}, // MUCH LESS-THAN -+ {"NewLine", 0x0000A}, // LINE FEED (LF) -+ {"nexist", 0x02204}, // THERE DOES NOT EXIST -+ {"nexists", 0x02204}, // THERE DOES NOT EXIST -+ {"Nfr", 0x1D511}, // MATHEMATICAL FRAKTUR CAPITAL N -+ {"nfr", 0x1D52B}, // MATHEMATICAL FRAKTUR SMALL N -+// "ngE", 0x02267;0x00338}, // GREATER-THAN OVER EQUAL TO with slash -+ {"nge", 0x02271}, // NEITHER GREATER-THAN NOR EQUAL TO -+ {"ngeq", 0x02271}, // NEITHER GREATER-THAN NOR EQUAL TO -+// "ngeqq", 0x02267;0x00338}, // GREATER-THAN OVER EQUAL TO with slash -+// "ngeqslant", 0x02A7E;0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash -+// "nges", 0x02A7E;0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash -+// "nGg", 0x022D9;0x00338}, // VERY MUCH GREATER-THAN with slash -+ {"Ngr", 0x0039D}, // GREEK CAPITAL LETTER NU -+ {"ngr", 0x003BD}, // GREEK SMALL LETTER NU -+ {"ngsim", 0x02275}, // NEITHER GREATER-THAN NOR EQUIVALENT TO -+// "nGt", 0x0226B;0x020D2}, // MUCH GREATER THAN with vertical line -+ {"ngt", 0x0226F}, // NOT GREATER-THAN -+ {"ngtr", 0x0226F}, // NOT GREATER-THAN -+// "nGtv", 0x0226B;0x00338}, // MUCH GREATER THAN with slash -+ {"nharr", 0x021AE}, // LEFT RIGHT ARROW WITH STROKE -+ {"nhArr", 0x021CE}, // LEFT RIGHT DOUBLE ARROW WITH STROKE -+ {"nhpar", 0x02AF2}, // PARALLEL WITH HORIZONTAL STROKE -+ {"ni", 0x0220B}, // CONTAINS AS MEMBER -+ {"nis", 0x022FC}, // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -+ {"nisd", 0x022FA}, // CONTAINS WITH LONG HORIZONTAL STROKE -+ {"niv", 0x0220B}, // CONTAINS AS MEMBER -+ {"NJcy", 0x0040A}, // CYRILLIC CAPITAL LETTER NJE -+ {"njcy", 0x0045A}, // CYRILLIC SMALL LETTER NJE -+ {"nlarr", 0x0219A}, // LEFTWARDS ARROW WITH STROKE -+ {"nlArr", 0x021CD}, // LEFTWARDS DOUBLE ARROW WITH STROKE -+ {"nldr", 0x02025}, // TWO DOT LEADER -+// "nlE", 0x02266;0x00338}, // LESS-THAN OVER EQUAL TO with slash -+ {"nle", 0x02270}, // NEITHER LESS-THAN NOR EQUAL TO -+ {"nleftarrow", 0x0219A}, // LEFTWARDS ARROW WITH STROKE -+ {"nLeftarrow", 0x021CD}, // LEFTWARDS DOUBLE ARROW WITH STROKE -+ {"nleftrightarrow", 0x021AE}, // LEFT RIGHT ARROW WITH STROKE -+ {"nLeftrightarrow", 0x021CE}, // LEFT RIGHT DOUBLE ARROW WITH STROKE -+ {"nleq", 0x02270}, // NEITHER LESS-THAN NOR EQUAL TO -+// "nleqq", 0x02266;0x00338}, // LESS-THAN OVER EQUAL TO with slash -+// "nleqslant", 0x02A7D;0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash -+// "nles", 0x02A7D;0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash -+ {"nless", 0x0226E}, // NOT LESS-THAN -+// "nLl", 0x022D8;0x00338}, // VERY MUCH LESS-THAN with slash -+ {"nlsim", 0x02274}, // NEITHER LESS-THAN NOR EQUIVALENT TO -+// "nLt", 0x0226A;0x020D2}, // MUCH LESS THAN with vertical line -+ {"nlt", 0x0226E}, // NOT LESS-THAN -+ {"nltri", 0x022EA}, // NOT NORMAL SUBGROUP OF -+ {"nltrie", 0x022EC}, // NOT NORMAL SUBGROUP OF OR EQUAL TO -+// "nLtv", 0x0226A;0x00338}, // MUCH LESS THAN with slash -+ {"nmid", 0x02224}, // DOES NOT DIVIDE -+ {"NoBreak", 0x02060}, // WORD JOINER -+ {"NonBreakingSpace", 0x000A0}, // NO-BREAK SPACE -+ {"Nopf", 0x02115}, // DOUBLE-STRUCK CAPITAL N -+ {"nopf", 0x1D55F}, // MATHEMATICAL DOUBLE-STRUCK SMALL N -+ {"not", 0x000AC}, // NOT SIGN -+ {"Not", 0x02AEC}, // DOUBLE STROKE NOT SIGN -+ {"NotCongruent", 0x02262}, // NOT IDENTICAL TO -+ {"NotCupCap", 0x0226D}, // NOT EQUIVALENT TO -+ {"NotDoubleVerticalBar", 0x02226}, // NOT PARALLEL TO -+ {"NotElement", 0x02209}, // NOT AN ELEMENT OF -+ {"NotEqual", 0x02260}, // NOT EQUAL TO -+// "NotEqualTilde", 0x02242;0x00338}, // MINUS TILDE with slash -+ {"NotExists", 0x02204}, // THERE DOES NOT EXIST -+ {"NotGreater", 0x0226F}, // NOT GREATER-THAN -+ {"NotGreaterEqual", 0x02271}, // NEITHER GREATER-THAN NOR EQUAL TO -+// "NotGreaterFullEqual", 0x02267;0x00338}, // GREATER-THAN OVER EQUAL TO with slash -+// "NotGreaterGreater", 0x0226B;0x00338}, // MUCH GREATER THAN with slash -+ {"NotGreaterLess", 0x02279}, // NEITHER GREATER-THAN NOR LESS-THAN -+// "NotGreaterSlantEqual", 0x02A7E;0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash -+ {"NotGreaterTilde", 0x02275}, // NEITHER GREATER-THAN NOR EQUIVALENT TO -+// "NotHumpDownHump", 0x0224E;0x00338}, // GEOMETRICALLY EQUIVALENT TO with slash -+// "NotHumpEqual", 0x0224F;0x00338}, // DIFFERENCE BETWEEN with slash -+ {"notin", 0x02209}, // NOT AN ELEMENT OF -+// "notindot", 0x022F5;0x00338}, // ELEMENT OF WITH DOT ABOVE with slash -+// "notinE", 0x022F9;0x00338}, // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash -+ {"notinva", 0x02209}, // NOT AN ELEMENT OF -+ {"notinvb", 0x022F7}, // SMALL ELEMENT OF WITH OVERBAR -+ {"notinvc", 0x022F6}, // ELEMENT OF WITH OVERBAR -+ {"NotLeftTriangle", 0x022EA}, // NOT NORMAL SUBGROUP OF -+// "NotLeftTriangleBar", 0x029CF;0x00338}, // LEFT TRIANGLE BESIDE VERTICAL BAR with slash -+ {"NotLeftTriangleEqual", 0x022EC}, // NOT NORMAL SUBGROUP OF OR EQUAL TO -+ {"NotLess", 0x0226E}, // NOT LESS-THAN -+ {"NotLessEqual", 0x02270}, // NEITHER LESS-THAN NOR EQUAL TO -+ {"NotLessGreater", 0x02278}, // NEITHER LESS-THAN NOR GREATER-THAN -+// "NotLessLess", 0x0226A;0x00338}, // MUCH LESS THAN with slash -+// "NotLessSlantEqual", 0x02A7D;0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash -+ {"NotLessTilde", 0x02274}, // NEITHER LESS-THAN NOR EQUIVALENT TO -+// "NotNestedGreaterGreater", 0x02AA2;0x00338}, // DOUBLE NESTED GREATER-THAN with slash -+// "NotNestedLessLess", 0x02AA1;0x00338}, // DOUBLE NESTED LESS-THAN with slash -+ {"notni", 0x0220C}, // DOES NOT CONTAIN AS MEMBER -+ {"notniva", 0x0220C}, // DOES NOT CONTAIN AS MEMBER -+ {"notnivb", 0x022FE}, // SMALL CONTAINS WITH OVERBAR -+ {"notnivc", 0x022FD}, // CONTAINS WITH OVERBAR -+ {"NotPrecedes", 0x02280}, // DOES NOT PRECEDE -+// "NotPrecedesEqual", 0x02AAF;0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash -+ {"NotPrecedesSlantEqual", 0x022E0}, // DOES NOT PRECEDE OR EQUAL -+ {"NotReverseElement", 0x0220C}, // DOES NOT CONTAIN AS MEMBER -+ {"NotRightTriangle", 0x022EB}, // DOES NOT CONTAIN AS NORMAL SUBGROUP -+// "NotRightTriangleBar", 0x029D0;0x00338}, // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash -+ {"NotRightTriangleEqual", 0x022ED}, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -+// "NotSquareSubset", 0x0228F;0x00338}, // SQUARE IMAGE OF with slash -+ {"NotSquareSubsetEqual", 0x022E2}, // NOT SQUARE IMAGE OF OR EQUAL TO -+// "NotSquareSuperset", 0x02290;0x00338}, // SQUARE ORIGINAL OF with slash -+ {"NotSquareSupersetEqual", 0x022E3}, // NOT SQUARE ORIGINAL OF OR EQUAL TO -+// "NotSubset", 0x02282;0x020D2}, // SUBSET OF with vertical line -+ {"NotSubsetEqual", 0x02288}, // NEITHER A SUBSET OF NOR EQUAL TO -+ {"NotSucceeds", 0x02281}, // DOES NOT SUCCEED -+// "NotSucceedsEqual", 0x02AB0;0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash -+ {"NotSucceedsSlantEqual", 0x022E1}, // DOES NOT SUCCEED OR EQUAL -+// "NotSucceedsTilde", 0x0227F;0x00338}, // SUCCEEDS OR EQUIVALENT TO with slash -+// "NotSuperset", 0x02283;0x020D2}, // SUPERSET OF with vertical line -+ {"NotSupersetEqual", 0x02289}, // NEITHER A SUPERSET OF NOR EQUAL TO -+ {"NotTilde", 0x02241}, // NOT TILDE -+ {"NotTildeEqual", 0x02244}, // NOT ASYMPTOTICALLY EQUAL TO -+ {"NotTildeFullEqual", 0x02247}, // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO -+ {"NotTildeTilde", 0x02249}, // NOT ALMOST EQUAL TO -+ {"NotVerticalBar", 0x02224}, // DOES NOT DIVIDE -+ {"npar", 0x02226}, // NOT PARALLEL TO -+ {"nparallel", 0x02226}, // NOT PARALLEL TO -+// "nparsl", 0x02AFD;0x020E5}, // DOUBLE SOLIDUS OPERATOR with reverse slash -+// "npart", 0x02202;0x00338}, // PARTIAL DIFFERENTIAL with slash -+ {"npolint", 0x02A14}, // LINE INTEGRATION NOT INCLUDING THE POLE -+ {"npr", 0x02280}, // DOES NOT PRECEDE -+ {"nprcue", 0x022E0}, // DOES NOT PRECEDE OR EQUAL -+// "npre", 0x02AAF;0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash -+ {"nprec", 0x02280}, // DOES NOT PRECEDE -+// "npreceq", 0x02AAF;0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash -+ {"nrarr", 0x0219B}, // RIGHTWARDS ARROW WITH STROKE -+ {"nrArr", 0x021CF}, // RIGHTWARDS DOUBLE ARROW WITH STROKE -+// "nrarrc", 0x02933;0x00338}, // WAVE ARROW POINTING DIRECTLY RIGHT with slash -+// "nrarrw", 0x0219D;0x00338}, // RIGHTWARDS WAVE ARROW with slash -+ {"nrightarrow", 0x0219B}, // RIGHTWARDS ARROW WITH STROKE -+ {"nRightarrow", 0x021CF}, // RIGHTWARDS DOUBLE ARROW WITH STROKE -+ {"nrtri", 0x022EB}, // DOES NOT CONTAIN AS NORMAL SUBGROUP -+ {"nrtrie", 0x022ED}, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -+ {"nsc", 0x02281}, // DOES NOT SUCCEED -+ {"nsccue", 0x022E1}, // DOES NOT SUCCEED OR EQUAL -+// "nsce", 0x02AB0;0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash -+ {"Nscr", 0x1D4A9}, // MATHEMATICAL SCRIPT CAPITAL N -+ {"nscr", 0x1D4C3}, // MATHEMATICAL SCRIPT SMALL N -+ {"nshortmid", 0x02224}, // DOES NOT DIVIDE -+ {"nshortparallel", 0x02226}, // NOT PARALLEL TO -+ {"nsim", 0x02241}, // NOT TILDE -+ {"nsime", 0x02244}, // NOT ASYMPTOTICALLY EQUAL TO -+ {"nsimeq", 0x02244}, // NOT ASYMPTOTICALLY EQUAL TO -+ {"nsmid", 0x02224}, // DOES NOT DIVIDE -+ {"nspar", 0x02226}, // NOT PARALLEL TO -+ {"nsqsube", 0x022E2}, // NOT SQUARE IMAGE OF OR EQUAL TO -+ {"nsqsupe", 0x022E3}, // NOT SQUARE ORIGINAL OF OR EQUAL TO -+ {"nsub", 0x02284}, // NOT A SUBSET OF -+ {"nsube", 0x02288}, // NEITHER A SUBSET OF NOR EQUAL TO -+// "nsubE", 0x02AC5;0x00338}, // SUBSET OF ABOVE EQUALS SIGN with slash -+// "nsubset", 0x02282;0x020D2}, // SUBSET OF with vertical line -+ {"nsubseteq", 0x02288}, // NEITHER A SUBSET OF NOR EQUAL TO -+// "nsubseteqq", 0x02AC5;0x00338}, // SUBSET OF ABOVE EQUALS SIGN with slash -+ {"nsucc", 0x02281}, // DOES NOT SUCCEED -+// "nsucceq", 0x02AB0;0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash -+ {"nsup", 0x02285}, // NOT A SUPERSET OF -+ {"nsupe", 0x02289}, // NEITHER A SUPERSET OF NOR EQUAL TO -+// "nsupE", 0x02AC6;0x00338}, // SUPERSET OF ABOVE EQUALS SIGN with slash -+// "nsupset", 0x02283;0x020D2}, // SUPERSET OF with vertical line -+ {"nsupseteq", 0x02289}, // NEITHER A SUPERSET OF NOR EQUAL TO -+// "nsupseteqq", 0x02AC6;0x00338}, // SUPERSET OF ABOVE EQUALS SIGN with slash -+ {"ntgl", 0x02279}, // NEITHER GREATER-THAN NOR LESS-THAN -+ {"Ntilde", 0x000D1}, // LATIN CAPITAL LETTER N WITH TILDE -+ {"ntilde", 0x000F1}, // LATIN SMALL LETTER N WITH TILDE -+ {"ntlg", 0x02278}, // NEITHER LESS-THAN NOR GREATER-THAN -+ {"ntriangleleft", 0x022EA}, // NOT NORMAL SUBGROUP OF -+ {"ntrianglelefteq", 0x022EC}, // NOT NORMAL SUBGROUP OF OR EQUAL TO -+ {"ntriangleright", 0x022EB}, // DOES NOT CONTAIN AS NORMAL SUBGROUP -+ {"ntrianglerighteq", 0x022ED}, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -+ {"Nu", 0x0039D}, // GREEK CAPITAL LETTER NU -+ {"nu", 0x003BD}, // GREEK SMALL LETTER NU -+ {"num", 0x00023}, // NUMBER SIGN -+ {"numero", 0x02116}, // NUMERO SIGN -+ {"numsp", 0x02007}, // FIGURE SPACE -+// "nvap", 0x0224D;0x020D2}, // EQUIVALENT TO with vertical line -+ {"nvdash", 0x022AC}, // DOES NOT PROVE -+ {"nvDash", 0x022AD}, // NOT TRUE -+ {"nVdash", 0x022AE}, // DOES NOT FORCE -+ {"nVDash", 0x022AF}, // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE -+// "nvge", 0x02265;0x020D2}, // GREATER-THAN OR EQUAL TO with vertical line -+// "nvgt", 0x0003E;0x020D2}, // GREATER-THAN SIGN with vertical line -+ {"nvHarr", 0x02904}, // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE -+ {"nvinfin", 0x029DE}, // INFINITY NEGATED WITH VERTICAL BAR -+ {"nvlArr", 0x02902}, // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE -+// "nvle", 0x02264;0x020D2}, // LESS-THAN OR EQUAL TO with vertical line -+// "nvlt", 0x0003C;0x020D2}, // LESS-THAN SIGN with vertical line -+// "nvltrie", 0x022B4;0x020D2}, // NORMAL SUBGROUP OF OR EQUAL TO with vertical line -+ {"nvrArr", 0x02903}, // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE -+// "nvrtrie", 0x022B5;0x020D2}, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line -+// "nvsim", 0x0223C;0x020D2}, // TILDE OPERATOR with vertical line -+ {"nwarhk", 0x02923}, // NORTH WEST ARROW WITH HOOK -+ {"nwarr", 0x02196}, // NORTH WEST ARROW -+ {"nwArr", 0x021D6}, // NORTH WEST DOUBLE ARROW -+ {"nwarrow", 0x02196}, // NORTH WEST ARROW -+ {"nwnear", 0x02927}, // NORTH WEST ARROW AND NORTH EAST ARROW -+ {NULL, 0} - }; - - static NameId namesO[]={ -- "Oacgr", 0x0038C, // GREEK CAPITAL LETTER OMICRON WITH TONOS -- "oacgr", 0x003CC, // GREEK SMALL LETTER OMICRON WITH TONOS -- "Oacute", 0x000D3, // LATIN CAPITAL LETTER O WITH ACUTE -- "oacute", 0x000F3, // LATIN SMALL LETTER O WITH ACUTE -- "oast", 0x0229B, // CIRCLED ASTERISK OPERATOR -- "ocir", 0x0229A, // CIRCLED RING OPERATOR -- "Ocirc", 0x000D4, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX -- "ocirc", 0x000F4, // LATIN SMALL LETTER O WITH CIRCUMFLEX -- "Ocy", 0x0041E, // CYRILLIC CAPITAL LETTER O -- "ocy", 0x0043E, // CYRILLIC SMALL LETTER O -- "odash", 0x0229D, // CIRCLED DASH -- "Odblac", 0x00150, // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -- "odblac", 0x00151, // LATIN SMALL LETTER O WITH DOUBLE ACUTE -- "odiv", 0x02A38, // CIRCLED DIVISION SIGN -- "odot", 0x02299, // CIRCLED DOT OPERATOR -- "odsold", 0x029BC, // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN -- "OElig", 0x00152, // LATIN CAPITAL LIGATURE OE -- "oelig", 0x00153, // LATIN SMALL LIGATURE OE -- "ofcir", 0x029BF, // CIRCLED BULLET -- "Ofr", 0x1D512, // MATHEMATICAL FRAKTUR CAPITAL O -- "ofr", 0x1D52C, // MATHEMATICAL FRAKTUR SMALL O -- "ogon", 0x002DB, // OGONEK -- "Ogr", 0x0039F, // GREEK CAPITAL LETTER OMICRON -- "ogr", 0x003BF, // GREEK SMALL LETTER OMICRON -- "Ograve", 0x000D2, // LATIN CAPITAL LETTER O WITH GRAVE -- "ograve", 0x000F2, // LATIN SMALL LETTER O WITH GRAVE -- "ogt", 0x029C1, // CIRCLED GREATER-THAN -- "OHacgr", 0x0038F, // GREEK CAPITAL LETTER OMEGA WITH TONOS -- "ohacgr", 0x003CE, // GREEK SMALL LETTER OMEGA WITH TONOS -- "ohbar", 0x029B5, // CIRCLE WITH HORIZONTAL BAR -- "OHgr", 0x003A9, // GREEK CAPITAL LETTER OMEGA -- "ohgr", 0x003C9, // GREEK SMALL LETTER OMEGA -- "ohm", 0x003A9, // GREEK CAPITAL LETTER OMEGA -- "oint", 0x0222E, // CONTOUR INTEGRAL -- "olarr", 0x021BA, // ANTICLOCKWISE OPEN CIRCLE ARROW -- "olcir", 0x029BE, // CIRCLED WHITE BULLET -- "olcross", 0x029BB, // CIRCLE WITH SUPERIMPOSED X -- "oline", 0x0203E, // OVERLINE -- "olt", 0x029C0, // CIRCLED LESS-THAN -- "Omacr", 0x0014C, // LATIN CAPITAL LETTER O WITH MACRON -- "omacr", 0x0014D, // LATIN SMALL LETTER O WITH MACRON -- "Omega", 0x003A9, // GREEK CAPITAL LETTER OMEGA -- "omega", 0x003C9, // GREEK SMALL LETTER OMEGA -- "Omicron", 0x0039F, // GREEK CAPITAL LETTER OMICRON -- "omicron", 0x003BF, // GREEK SMALL LETTER OMICRON -- "omid", 0x029B6, // CIRCLED VERTICAL BAR -- "ominus", 0x02296, // CIRCLED MINUS -- "Oopf", 0x1D546, // MATHEMATICAL DOUBLE-STRUCK CAPITAL O -- "oopf", 0x1D560, // MATHEMATICAL DOUBLE-STRUCK SMALL O -- "opar", 0x029B7, // CIRCLED PARALLEL -- "OpenCurlyDoubleQuote", 0x0201C, // LEFT DOUBLE QUOTATION MARK -- "OpenCurlyQuote", 0x02018, // LEFT SINGLE QUOTATION MARK -- "operp", 0x029B9, // CIRCLED PERPENDICULAR -- "oplus", 0x02295, // CIRCLED PLUS -- "or", 0x02228, // LOGICAL OR -- "Or", 0x02A54, // DOUBLE LOGICAL OR -- "orarr", 0x021BB, // CLOCKWISE OPEN CIRCLE ARROW -- "ord", 0x02A5D, // LOGICAL OR WITH HORIZONTAL DASH -- "order", 0x02134, // SCRIPT SMALL O -- "orderof", 0x02134, // SCRIPT SMALL O -- "ordf", 0x000AA, // FEMININE ORDINAL INDICATOR -- "ordm", 0x000BA, // MASCULINE ORDINAL INDICATOR -- "origof", 0x022B6, // ORIGINAL OF -- "oror", 0x02A56, // TWO INTERSECTING LOGICAL OR -- "orslope", 0x02A57, // SLOPING LARGE OR -- "orv", 0x02A5B, // LOGICAL OR WITH MIDDLE STEM -- "oS", 0x024C8, // CIRCLED LATIN CAPITAL LETTER S -- "oscr", 0x02134, // SCRIPT SMALL O -- "Oscr", 0x1D4AA, // MATHEMATICAL SCRIPT CAPITAL O -- "Oslash", 0x000D8, // LATIN CAPITAL LETTER O WITH STROKE -- "oslash", 0x000F8, // LATIN SMALL LETTER O WITH STROKE -- "osol", 0x02298, // CIRCLED DIVISION SLASH -- "Otilde", 0x000D5, // LATIN CAPITAL LETTER O WITH TILDE -- "otilde", 0x000F5, // LATIN SMALL LETTER O WITH TILDE -- "otimes", 0x02297, // CIRCLED TIMES -- "Otimes", 0x02A37, // MULTIPLICATION SIGN IN DOUBLE CIRCLE -- "otimesas", 0x02A36, // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT -- "Ouml", 0x000D6, // LATIN CAPITAL LETTER O WITH DIAERESIS -- "ouml", 0x000F6, // LATIN SMALL LETTER O WITH DIAERESIS -- "ovbar", 0x0233D, // APL FUNCTIONAL SYMBOL CIRCLE STILE -- "OverBar", 0x0203E, // OVERLINE -- "OverBrace", 0x023DE, // TOP CURLY BRACKET -- "OverBracket", 0x023B4, // TOP SQUARE BRACKET -- "OverParenthesis", 0x023DC, // TOP PARENTHESIS -- NULL, 0 -+ {"Oacgr", 0x0038C}, // GREEK CAPITAL LETTER OMICRON WITH TONOS -+ {"oacgr", 0x003CC}, // GREEK SMALL LETTER OMICRON WITH TONOS -+ {"Oacute", 0x000D3}, // LATIN CAPITAL LETTER O WITH ACUTE -+ {"oacute", 0x000F3}, // LATIN SMALL LETTER O WITH ACUTE -+ {"oast", 0x0229B}, // CIRCLED ASTERISK OPERATOR -+ {"ocir", 0x0229A}, // CIRCLED RING OPERATOR -+ {"Ocirc", 0x000D4}, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX -+ {"ocirc", 0x000F4}, // LATIN SMALL LETTER O WITH CIRCUMFLEX -+ {"Ocy", 0x0041E}, // CYRILLIC CAPITAL LETTER O -+ {"ocy", 0x0043E}, // CYRILLIC SMALL LETTER O -+ {"odash", 0x0229D}, // CIRCLED DASH -+ {"Odblac", 0x00150}, // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -+ {"odblac", 0x00151}, // LATIN SMALL LETTER O WITH DOUBLE ACUTE -+ {"odiv", 0x02A38}, // CIRCLED DIVISION SIGN -+ {"odot", 0x02299}, // CIRCLED DOT OPERATOR -+ {"odsold", 0x029BC}, // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN -+ {"OElig", 0x00152}, // LATIN CAPITAL LIGATURE OE -+ {"oelig", 0x00153}, // LATIN SMALL LIGATURE OE -+ {"ofcir", 0x029BF}, // CIRCLED BULLET -+ {"Ofr", 0x1D512}, // MATHEMATICAL FRAKTUR CAPITAL O -+ {"ofr", 0x1D52C}, // MATHEMATICAL FRAKTUR SMALL O -+ {"ogon", 0x002DB}, // OGONEK -+ {"Ogr", 0x0039F}, // GREEK CAPITAL LETTER OMICRON -+ {"ogr", 0x003BF}, // GREEK SMALL LETTER OMICRON -+ {"Ograve", 0x000D2}, // LATIN CAPITAL LETTER O WITH GRAVE -+ {"ograve", 0x000F2}, // LATIN SMALL LETTER O WITH GRAVE -+ {"ogt", 0x029C1}, // CIRCLED GREATER-THAN -+ {"OHacgr", 0x0038F}, // GREEK CAPITAL LETTER OMEGA WITH TONOS -+ {"ohacgr", 0x003CE}, // GREEK SMALL LETTER OMEGA WITH TONOS -+ {"ohbar", 0x029B5}, // CIRCLE WITH HORIZONTAL BAR -+ {"OHgr", 0x003A9}, // GREEK CAPITAL LETTER OMEGA -+ {"ohgr", 0x003C9}, // GREEK SMALL LETTER OMEGA -+ {"ohm", 0x003A9}, // GREEK CAPITAL LETTER OMEGA -+ {"oint", 0x0222E}, // CONTOUR INTEGRAL -+ {"olarr", 0x021BA}, // ANTICLOCKWISE OPEN CIRCLE ARROW -+ {"olcir", 0x029BE}, // CIRCLED WHITE BULLET -+ {"olcross", 0x029BB}, // CIRCLE WITH SUPERIMPOSED X -+ {"oline", 0x0203E}, // OVERLINE -+ {"olt", 0x029C0}, // CIRCLED LESS-THAN -+ {"Omacr", 0x0014C}, // LATIN CAPITAL LETTER O WITH MACRON -+ {"omacr", 0x0014D}, // LATIN SMALL LETTER O WITH MACRON -+ {"Omega", 0x003A9}, // GREEK CAPITAL LETTER OMEGA -+ {"omega", 0x003C9}, // GREEK SMALL LETTER OMEGA -+ {"Omicron", 0x0039F}, // GREEK CAPITAL LETTER OMICRON -+ {"omicron", 0x003BF}, // GREEK SMALL LETTER OMICRON -+ {"omid", 0x029B6}, // CIRCLED VERTICAL BAR -+ {"ominus", 0x02296}, // CIRCLED MINUS -+ {"Oopf", 0x1D546}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL O -+ {"oopf", 0x1D560}, // MATHEMATICAL DOUBLE-STRUCK SMALL O -+ {"opar", 0x029B7}, // CIRCLED PARALLEL -+ {"OpenCurlyDoubleQuote", 0x0201C}, // LEFT DOUBLE QUOTATION MARK -+ {"OpenCurlyQuote", 0x02018}, // LEFT SINGLE QUOTATION MARK -+ {"operp", 0x029B9}, // CIRCLED PERPENDICULAR -+ {"oplus", 0x02295}, // CIRCLED PLUS -+ {"or", 0x02228}, // LOGICAL OR -+ {"Or", 0x02A54}, // DOUBLE LOGICAL OR -+ {"orarr", 0x021BB}, // CLOCKWISE OPEN CIRCLE ARROW -+ {"ord", 0x02A5D}, // LOGICAL OR WITH HORIZONTAL DASH -+ {"order", 0x02134}, // SCRIPT SMALL O -+ {"orderof", 0x02134}, // SCRIPT SMALL O -+ {"ordf", 0x000AA}, // FEMININE ORDINAL INDICATOR -+ {"ordm", 0x000BA}, // MASCULINE ORDINAL INDICATOR -+ {"origof", 0x022B6}, // ORIGINAL OF -+ {"oror", 0x02A56}, // TWO INTERSECTING LOGICAL OR -+ {"orslope", 0x02A57}, // SLOPING LARGE OR -+ {"orv", 0x02A5B}, // LOGICAL OR WITH MIDDLE STEM -+ {"oS", 0x024C8}, // CIRCLED LATIN CAPITAL LETTER S -+ {"oscr", 0x02134}, // SCRIPT SMALL O -+ {"Oscr", 0x1D4AA}, // MATHEMATICAL SCRIPT CAPITAL O -+ {"Oslash", 0x000D8}, // LATIN CAPITAL LETTER O WITH STROKE -+ {"oslash", 0x000F8}, // LATIN SMALL LETTER O WITH STROKE -+ {"osol", 0x02298}, // CIRCLED DIVISION SLASH -+ {"Otilde", 0x000D5}, // LATIN CAPITAL LETTER O WITH TILDE -+ {"otilde", 0x000F5}, // LATIN SMALL LETTER O WITH TILDE -+ {"otimes", 0x02297}, // CIRCLED TIMES -+ {"Otimes", 0x02A37}, // MULTIPLICATION SIGN IN DOUBLE CIRCLE -+ {"otimesas", 0x02A36}, // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT -+ {"Ouml", 0x000D6}, // LATIN CAPITAL LETTER O WITH DIAERESIS -+ {"ouml", 0x000F6}, // LATIN SMALL LETTER O WITH DIAERESIS -+ {"ovbar", 0x0233D}, // APL FUNCTIONAL SYMBOL CIRCLE STILE -+ {"OverBar", 0x0203E}, // OVERLINE -+ {"OverBrace", 0x023DE}, // TOP CURLY BRACKET -+ {"OverBracket", 0x023B4}, // TOP SQUARE BRACKET -+ {"OverParenthesis", 0x023DC}, // TOP PARENTHESIS -+ {NULL, 0} - }; - - static NameId namesP[]={ -- "par", 0x02225, // PARALLEL TO -- "para", 0x000B6, // PILCROW SIGN -- "parallel", 0x02225, // PARALLEL TO -- "parsim", 0x02AF3, // PARALLEL WITH TILDE OPERATOR -- "parsl", 0x02AFD, // DOUBLE SOLIDUS OPERATOR -- "part", 0x02202, // PARTIAL DIFFERENTIAL -- "PartialD", 0x02202, // PARTIAL DIFFERENTIAL -- "Pcy", 0x0041F, // CYRILLIC CAPITAL LETTER PE -- "pcy", 0x0043F, // CYRILLIC SMALL LETTER PE -- "percnt", 0x00025, // PERCENT SIGN -- "period", 0x0002E, // FULL STOP -- "permil", 0x02030, // PER MILLE SIGN -- "perp", 0x022A5, // UP TACK -- "pertenk", 0x02031, // PER TEN THOUSAND SIGN -- "Pfr", 0x1D513, // MATHEMATICAL FRAKTUR CAPITAL P -- "pfr", 0x1D52D, // MATHEMATICAL FRAKTUR SMALL P -- "Pgr", 0x003A0, // GREEK CAPITAL LETTER PI -- "pgr", 0x003C0, // GREEK SMALL LETTER PI -- "PHgr", 0x003A6, // GREEK CAPITAL LETTER PHI -- "phgr", 0x003C6, // GREEK SMALL LETTER PHI -- "Phi", 0x003A6, // GREEK CAPITAL LETTER PHI -- "phi", 0x003C6, // GREEK SMALL LETTER PHI -- "phiv", 0x003D5, // GREEK PHI SYMBOL -- "phmmat", 0x02133, // SCRIPT CAPITAL M -- "phone", 0x0260E, // BLACK TELEPHONE -- "Pi", 0x003A0, // GREEK CAPITAL LETTER PI -- "pi", 0x003C0, // GREEK SMALL LETTER PI -- "pitchfork", 0x022D4, // PITCHFORK -- "piv", 0x003D6, // GREEK PI SYMBOL -- "planck", 0x0210F, // PLANCK CONSTANT OVER TWO PI -- "planckh", 0x0210E, // PLANCK CONSTANT -- "plankv", 0x0210F, // PLANCK CONSTANT OVER TWO PI -- "plus", 0x0002B, // PLUS SIGN -- "plusacir", 0x02A23, // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE -- "plusb", 0x0229E, // SQUARED PLUS -- "pluscir", 0x02A22, // PLUS SIGN WITH SMALL CIRCLE ABOVE -- "plusdo", 0x02214, // DOT PLUS -- "plusdu", 0x02A25, // PLUS SIGN WITH DOT BELOW -- "pluse", 0x02A72, // PLUS SIGN ABOVE EQUALS SIGN -- "PlusMinus", 0x000B1, // PLUS-MINUS SIGN -- "plusmn", 0x000B1, // PLUS-MINUS SIGN -- "plussim", 0x02A26, // PLUS SIGN WITH TILDE BELOW -- "plustwo", 0x02A27, // PLUS SIGN WITH SUBSCRIPT TWO -- "pm", 0x000B1, // PLUS-MINUS SIGN -- "Poincareplane", 0x0210C, // BLACK-LETTER CAPITAL H -- "pointint", 0x02A15, // INTEGRAL AROUND A POINT OPERATOR -- "Popf", 0x02119, // DOUBLE-STRUCK CAPITAL P -- "popf", 0x1D561, // MATHEMATICAL DOUBLE-STRUCK SMALL P -- "pound", 0x000A3, // POUND SIGN -- "pr", 0x0227A, // PRECEDES -- "Pr", 0x02ABB, // DOUBLE PRECEDES -- "prap", 0x02AB7, // PRECEDES ABOVE ALMOST EQUAL TO -- "prcue", 0x0227C, // PRECEDES OR EQUAL TO -- "pre", 0x02AAF, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -- "prE", 0x02AB3, // PRECEDES ABOVE EQUALS SIGN -- "prec", 0x0227A, // PRECEDES -- "precapprox", 0x02AB7, // PRECEDES ABOVE ALMOST EQUAL TO -- "preccurlyeq", 0x0227C, // PRECEDES OR EQUAL TO -- "Precedes", 0x0227A, // PRECEDES -- "PrecedesEqual", 0x02AAF, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -- "PrecedesSlantEqual", 0x0227C, // PRECEDES OR EQUAL TO -- "PrecedesTilde", 0x0227E, // PRECEDES OR EQUIVALENT TO -- "preceq", 0x02AAF, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -- "precnapprox", 0x02AB9, // PRECEDES ABOVE NOT ALMOST EQUAL TO -- "precneqq", 0x02AB5, // PRECEDES ABOVE NOT EQUAL TO -- "precnsim", 0x022E8, // PRECEDES BUT NOT EQUIVALENT TO -- "precsim", 0x0227E, // PRECEDES OR EQUIVALENT TO -- "prime", 0x02032, // PRIME -- "Prime", 0x02033, // DOUBLE PRIME -- "primes", 0x02119, // DOUBLE-STRUCK CAPITAL P -- "prnap", 0x02AB9, // PRECEDES ABOVE NOT ALMOST EQUAL TO -- "prnE", 0x02AB5, // PRECEDES ABOVE NOT EQUAL TO -- "prnsim", 0x022E8, // PRECEDES BUT NOT EQUIVALENT TO -- "prod", 0x0220F, // N-ARY PRODUCT -- "Product", 0x0220F, // N-ARY PRODUCT -- "profalar", 0x0232E, // ALL AROUND-PROFILE -- "profline", 0x02312, // ARC -- "profsurf", 0x02313, // SEGMENT -- "prop", 0x0221D, // PROPORTIONAL TO -- "Proportion", 0x02237, // PROPORTION -- "Proportional", 0x0221D, // PROPORTIONAL TO -- "propto", 0x0221D, // PROPORTIONAL TO -- "prsim", 0x0227E, // PRECEDES OR EQUIVALENT TO -- "prurel", 0x022B0, // PRECEDES UNDER RELATION -- "Pscr", 0x1D4AB, // MATHEMATICAL SCRIPT CAPITAL P -- "pscr", 0x1D4C5, // MATHEMATICAL SCRIPT SMALL P -- "PSgr", 0x003A8, // GREEK CAPITAL LETTER PSI -- "psgr", 0x003C8, // GREEK SMALL LETTER PSI -- "Psi", 0x003A8, // GREEK CAPITAL LETTER PSI -- "psi", 0x003C8, // GREEK SMALL LETTER PSI -- "puncsp", 0x02008, // PUNCTUATION SPACE -- NULL, 0 -+ {"par", 0x02225}, // PARALLEL TO -+ {"para", 0x000B6}, // PILCROW SIGN -+ {"parallel", 0x02225}, // PARALLEL TO -+ {"parsim", 0x02AF3}, // PARALLEL WITH TILDE OPERATOR -+ {"parsl", 0x02AFD}, // DOUBLE SOLIDUS OPERATOR -+ {"part", 0x02202}, // PARTIAL DIFFERENTIAL -+ {"PartialD", 0x02202}, // PARTIAL DIFFERENTIAL -+ {"Pcy", 0x0041F}, // CYRILLIC CAPITAL LETTER PE -+ {"pcy", 0x0043F}, // CYRILLIC SMALL LETTER PE -+ {"percnt", 0x00025}, // PERCENT SIGN -+ {"period", 0x0002E}, // FULL STOP -+ {"permil", 0x02030}, // PER MILLE SIGN -+ {"perp", 0x022A5}, // UP TACK -+ {"pertenk", 0x02031}, // PER TEN THOUSAND SIGN -+ {"Pfr", 0x1D513}, // MATHEMATICAL FRAKTUR CAPITAL P -+ {"pfr", 0x1D52D}, // MATHEMATICAL FRAKTUR SMALL P -+ {"Pgr", 0x003A0}, // GREEK CAPITAL LETTER PI -+ {"pgr", 0x003C0}, // GREEK SMALL LETTER PI -+ {"PHgr", 0x003A6}, // GREEK CAPITAL LETTER PHI -+ {"phgr", 0x003C6}, // GREEK SMALL LETTER PHI -+ {"Phi", 0x003A6}, // GREEK CAPITAL LETTER PHI -+ {"phi", 0x003C6}, // GREEK SMALL LETTER PHI -+ {"phiv", 0x003D5}, // GREEK PHI SYMBOL -+ {"phmmat", 0x02133}, // SCRIPT CAPITAL M -+ {"phone", 0x0260E}, // BLACK TELEPHONE -+ {"Pi", 0x003A0}, // GREEK CAPITAL LETTER PI -+ {"pi", 0x003C0}, // GREEK SMALL LETTER PI -+ {"pitchfork", 0x022D4}, // PITCHFORK -+ {"piv", 0x003D6}, // GREEK PI SYMBOL -+ {"planck", 0x0210F}, // PLANCK CONSTANT OVER TWO PI -+ {"planckh", 0x0210E}, // PLANCK CONSTANT -+ {"plankv", 0x0210F}, // PLANCK CONSTANT OVER TWO PI -+ {"plus", 0x0002B}, // PLUS SIGN -+ {"plusacir", 0x02A23}, // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE -+ {"plusb", 0x0229E}, // SQUARED PLUS -+ {"pluscir", 0x02A22}, // PLUS SIGN WITH SMALL CIRCLE ABOVE -+ {"plusdo", 0x02214}, // DOT PLUS -+ {"plusdu", 0x02A25}, // PLUS SIGN WITH DOT BELOW -+ {"pluse", 0x02A72}, // PLUS SIGN ABOVE EQUALS SIGN -+ {"PlusMinus", 0x000B1}, // PLUS-MINUS SIGN -+ {"plusmn", 0x000B1}, // PLUS-MINUS SIGN -+ {"plussim", 0x02A26}, // PLUS SIGN WITH TILDE BELOW -+ {"plustwo", 0x02A27}, // PLUS SIGN WITH SUBSCRIPT TWO -+ {"pm", 0x000B1}, // PLUS-MINUS SIGN -+ {"Poincareplane", 0x0210C}, // BLACK-LETTER CAPITAL H -+ {"pointint", 0x02A15}, // INTEGRAL AROUND A POINT OPERATOR -+ {"Popf", 0x02119}, // DOUBLE-STRUCK CAPITAL P -+ {"popf", 0x1D561}, // MATHEMATICAL DOUBLE-STRUCK SMALL P -+ {"pound", 0x000A3}, // POUND SIGN -+ {"pr", 0x0227A}, // PRECEDES -+ {"Pr", 0x02ABB}, // DOUBLE PRECEDES -+ {"prap", 0x02AB7}, // PRECEDES ABOVE ALMOST EQUAL TO -+ {"prcue", 0x0227C}, // PRECEDES OR EQUAL TO -+ {"pre", 0x02AAF}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -+ {"prE", 0x02AB3}, // PRECEDES ABOVE EQUALS SIGN -+ {"prec", 0x0227A}, // PRECEDES -+ {"precapprox", 0x02AB7}, // PRECEDES ABOVE ALMOST EQUAL TO -+ {"preccurlyeq", 0x0227C}, // PRECEDES OR EQUAL TO -+ {"Precedes", 0x0227A}, // PRECEDES -+ {"PrecedesEqual", 0x02AAF}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -+ {"PrecedesSlantEqual", 0x0227C}, // PRECEDES OR EQUAL TO -+ {"PrecedesTilde", 0x0227E}, // PRECEDES OR EQUIVALENT TO -+ {"preceq", 0x02AAF}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -+ {"precnapprox", 0x02AB9}, // PRECEDES ABOVE NOT ALMOST EQUAL TO -+ {"precneqq", 0x02AB5}, // PRECEDES ABOVE NOT EQUAL TO -+ {"precnsim", 0x022E8}, // PRECEDES BUT NOT EQUIVALENT TO -+ {"precsim", 0x0227E}, // PRECEDES OR EQUIVALENT TO -+ {"prime", 0x02032}, // PRIME -+ {"Prime", 0x02033}, // DOUBLE PRIME -+ {"primes", 0x02119}, // DOUBLE-STRUCK CAPITAL P -+ {"prnap", 0x02AB9}, // PRECEDES ABOVE NOT ALMOST EQUAL TO -+ {"prnE", 0x02AB5}, // PRECEDES ABOVE NOT EQUAL TO -+ {"prnsim", 0x022E8}, // PRECEDES BUT NOT EQUIVALENT TO -+ {"prod", 0x0220F}, // N-ARY PRODUCT -+ {"Product", 0x0220F}, // N-ARY PRODUCT -+ {"profalar", 0x0232E}, // ALL AROUND-PROFILE -+ {"profline", 0x02312}, // ARC -+ {"profsurf", 0x02313}, // SEGMENT -+ {"prop", 0x0221D}, // PROPORTIONAL TO -+ {"Proportion", 0x02237}, // PROPORTION -+ {"Proportional", 0x0221D}, // PROPORTIONAL TO -+ {"propto", 0x0221D}, // PROPORTIONAL TO -+ {"prsim", 0x0227E}, // PRECEDES OR EQUIVALENT TO -+ {"prurel", 0x022B0}, // PRECEDES UNDER RELATION -+ {"Pscr", 0x1D4AB}, // MATHEMATICAL SCRIPT CAPITAL P -+ {"pscr", 0x1D4C5}, // MATHEMATICAL SCRIPT SMALL P -+ {"PSgr", 0x003A8}, // GREEK CAPITAL LETTER PSI -+ {"psgr", 0x003C8}, // GREEK SMALL LETTER PSI -+ {"Psi", 0x003A8}, // GREEK CAPITAL LETTER PSI -+ {"psi", 0x003C8}, // GREEK SMALL LETTER PSI -+ {"puncsp", 0x02008}, // PUNCTUATION SPACE -+ {NULL, 0} - }; - - static NameId namesQ[]={ -- "Qfr", 0x1D514, // MATHEMATICAL FRAKTUR CAPITAL Q -- "qfr", 0x1D52E, // MATHEMATICAL FRAKTUR SMALL Q -- "qint", 0x02A0C, // QUADRUPLE INTEGRAL OPERATOR -- "Qopf", 0x0211A, // DOUBLE-STRUCK CAPITAL Q -- "qopf", 0x1D562, // MATHEMATICAL DOUBLE-STRUCK SMALL Q -- "qprime", 0x02057, // QUADRUPLE PRIME -- "Qscr", 0x1D4AC, // MATHEMATICAL SCRIPT CAPITAL Q -- "qscr", 0x1D4C6, // MATHEMATICAL SCRIPT SMALL Q -- "quaternions", 0x0210D, // DOUBLE-STRUCK CAPITAL H -- "quatint", 0x02A16, // QUATERNION INTEGRAL OPERATOR -- "quest", 0x0003F, // QUESTION MARK -- "questeq", 0x0225F, // QUESTIONED EQUAL TO -- "quot", 0x00022, // QUOTATION MARK -- "QUOT", 0x00022, // QUOTATION MARK -- NULL, 0 -+ {"Qfr", 0x1D514}, // MATHEMATICAL FRAKTUR CAPITAL Q -+ {"qfr", 0x1D52E}, // MATHEMATICAL FRAKTUR SMALL Q -+ {"qint", 0x02A0C}, // QUADRUPLE INTEGRAL OPERATOR -+ {"Qopf", 0x0211A}, // DOUBLE-STRUCK CAPITAL Q -+ {"qopf", 0x1D562}, // MATHEMATICAL DOUBLE-STRUCK SMALL Q -+ {"qprime", 0x02057}, // QUADRUPLE PRIME -+ {"Qscr", 0x1D4AC}, // MATHEMATICAL SCRIPT CAPITAL Q -+ {"qscr", 0x1D4C6}, // MATHEMATICAL SCRIPT SMALL Q -+ {"quaternions", 0x0210D}, // DOUBLE-STRUCK CAPITAL H -+ {"quatint", 0x02A16}, // QUATERNION INTEGRAL OPERATOR -+ {"quest", 0x0003F}, // QUESTION MARK -+ {"questeq", 0x0225F}, // QUESTIONED EQUAL TO -+ {"quot", 0x00022}, // QUOTATION MARK -+ {"QUOT", 0x00022}, // QUOTATION MARK -+ {NULL, 0} - }; - - static NameId namesR[]={ -- "rAarr", 0x021DB, // RIGHTWARDS TRIPLE ARROW --// "race", 0x0223D;0x00331, // REVERSED TILDE with underline -- "Racute", 0x00154, // LATIN CAPITAL LETTER R WITH ACUTE -- "racute", 0x00155, // LATIN SMALL LETTER R WITH ACUTE -- "radic", 0x0221A, // SQUARE ROOT -- "raemptyv", 0x029B3, // EMPTY SET WITH RIGHT ARROW ABOVE -- "rang", 0x027E9, // MATHEMATICAL RIGHT ANGLE BRACKET -- "Rang", 0x027EB, // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET -- "rangd", 0x02992, // RIGHT ANGLE BRACKET WITH DOT -- "range", 0x029A5, // REVERSED ANGLE WITH UNDERBAR -- "rangle", 0x027E9, // MATHEMATICAL RIGHT ANGLE BRACKET -- "raquo", 0x000BB, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -- "rarr", 0x02192, // RIGHTWARDS ARROW -- "Rarr", 0x021A0, // RIGHTWARDS TWO HEADED ARROW -- "rArr", 0x021D2, // RIGHTWARDS DOUBLE ARROW -- "rarrap", 0x02975, // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO -- "rarrb", 0x021E5, // RIGHTWARDS ARROW TO BAR -- "rarrbfs", 0x02920, // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND -- "rarrc", 0x02933, // WAVE ARROW POINTING DIRECTLY RIGHT -- "rarrfs", 0x0291E, // RIGHTWARDS ARROW TO BLACK DIAMOND -- "rarrhk", 0x021AA, // RIGHTWARDS ARROW WITH HOOK -- "rarrlp", 0x021AC, // RIGHTWARDS ARROW WITH LOOP -- "rarrpl", 0x02945, // RIGHTWARDS ARROW WITH PLUS BELOW -- "rarrsim", 0x02974, // RIGHTWARDS ARROW ABOVE TILDE OPERATOR -- "rarrtl", 0x021A3, // RIGHTWARDS ARROW WITH TAIL -- "Rarrtl", 0x02916, // RIGHTWARDS TWO-HEADED ARROW WITH TAIL -- "rarrw", 0x0219D, // RIGHTWARDS WAVE ARROW -- "ratail", 0x0291A, // RIGHTWARDS ARROW-TAIL -- "rAtail", 0x0291C, // RIGHTWARDS DOUBLE ARROW-TAIL -- "ratio", 0x02236, // RATIO -- "rationals", 0x0211A, // DOUBLE-STRUCK CAPITAL Q -- "rbarr", 0x0290D, // RIGHTWARDS DOUBLE DASH ARROW -- "rBarr", 0x0290F, // RIGHTWARDS TRIPLE DASH ARROW -- "RBarr", 0x02910, // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW -- "rbbrk", 0x02773, // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT -- "rbrace", 0x0007D, // RIGHT CURLY BRACKET -- "rbrack", 0x0005D, // RIGHT SQUARE BRACKET -- "rbrke", 0x0298C, // RIGHT SQUARE BRACKET WITH UNDERBAR -- "rbrksld", 0x0298E, // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER -- "rbrkslu", 0x02990, // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER -- "Rcaron", 0x00158, // LATIN CAPITAL LETTER R WITH CARON -- "rcaron", 0x00159, // LATIN SMALL LETTER R WITH CARON -- "Rcedil", 0x00156, // LATIN CAPITAL LETTER R WITH CEDILLA -- "rcedil", 0x00157, // LATIN SMALL LETTER R WITH CEDILLA -- "rceil", 0x02309, // RIGHT CEILING -- "rcub", 0x0007D, // RIGHT CURLY BRACKET -- "Rcy", 0x00420, // CYRILLIC CAPITAL LETTER ER -- "rcy", 0x00440, // CYRILLIC SMALL LETTER ER -- "rdca", 0x02937, // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS -- "rdldhar", 0x02969, // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN -- "rdquo", 0x0201D, // RIGHT DOUBLE QUOTATION MARK -- "rdquor", 0x0201D, // RIGHT DOUBLE QUOTATION MARK -- "rdsh", 0x021B3, // DOWNWARDS ARROW WITH TIP RIGHTWARDS -- "Re", 0x0211C, // BLACK-LETTER CAPITAL R -- "real", 0x0211C, // BLACK-LETTER CAPITAL R -- "realine", 0x0211B, // SCRIPT CAPITAL R -- "realpart", 0x0211C, // BLACK-LETTER CAPITAL R -- "reals", 0x0211D, // DOUBLE-STRUCK CAPITAL R -- "rect", 0x025AD, // WHITE RECTANGLE -- "reg", 0x000AE, // REGISTERED SIGN -- "REG", 0x000AE, // REGISTERED SIGN -- "ReverseElement", 0x0220B, // CONTAINS AS MEMBER -- "ReverseEquilibrium", 0x021CB, // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -- "ReverseUpEquilibrium", 0x0296F, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -- "rfisht", 0x0297D, // RIGHT FISH TAIL -- "rfloor", 0x0230B, // RIGHT FLOOR -- "Rfr", 0x0211C, // BLACK-LETTER CAPITAL R -- "rfr", 0x1D52F, // MATHEMATICAL FRAKTUR SMALL R -- "Rgr", 0x003A1, // GREEK CAPITAL LETTER RHO -- "rgr", 0x003C1, // GREEK SMALL LETTER RHO -- "rHar", 0x02964, // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN -- "rhard", 0x021C1, // RIGHTWARDS HARPOON WITH BARB DOWNWARDS -- "rharu", 0x021C0, // RIGHTWARDS HARPOON WITH BARB UPWARDS -- "rharul", 0x0296C, // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH -- "Rho", 0x003A1, // GREEK CAPITAL LETTER RHO -- "rho", 0x003C1, // GREEK SMALL LETTER RHO -- "rhov", 0x003F1, // GREEK RHO SYMBOL -- "RightAngleBracket", 0x027E9, // MATHEMATICAL RIGHT ANGLE BRACKET -- "rightarrow", 0x02192, // RIGHTWARDS ARROW -- "RightArrow", 0x02192, // RIGHTWARDS ARROW -- "Rightarrow", 0x021D2, // RIGHTWARDS DOUBLE ARROW -- "RightArrowBar", 0x021E5, // RIGHTWARDS ARROW TO BAR -- "RightArrowLeftArrow", 0x021C4, // RIGHTWARDS ARROW OVER LEFTWARDS ARROW -- "rightarrowtail", 0x021A3, // RIGHTWARDS ARROW WITH TAIL -- "RightCeiling", 0x02309, // RIGHT CEILING -- "RightDoubleBracket", 0x027E7, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET -- "RightDownTeeVector", 0x0295D, // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR -- "RightDownVector", 0x021C2, // DOWNWARDS HARPOON WITH BARB RIGHTWARDS -- "RightDownVectorBar", 0x02955, // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR -- "RightFloor", 0x0230B, // RIGHT FLOOR -- "rightharpoondown", 0x021C1, // RIGHTWARDS HARPOON WITH BARB DOWNWARDS -- "rightharpoonup", 0x021C0, // RIGHTWARDS HARPOON WITH BARB UPWARDS -- "rightleftarrows", 0x021C4, // RIGHTWARDS ARROW OVER LEFTWARDS ARROW -- "rightleftharpoons", 0x021CC, // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -- "rightrightarrows", 0x021C9, // RIGHTWARDS PAIRED ARROWS -- "rightsquigarrow", 0x0219D, // RIGHTWARDS WAVE ARROW -- "RightTee", 0x022A2, // RIGHT TACK -- "RightTeeArrow", 0x021A6, // RIGHTWARDS ARROW FROM BAR -- "RightTeeVector", 0x0295B, // RIGHTWARDS HARPOON WITH BARB UP FROM BAR -- "rightthreetimes", 0x022CC, // RIGHT SEMIDIRECT PRODUCT -- "RightTriangle", 0x022B3, // CONTAINS AS NORMAL SUBGROUP -- "RightTriangleBar", 0x029D0, // VERTICAL BAR BESIDE RIGHT TRIANGLE -- "RightTriangleEqual", 0x022B5, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -- "RightUpDownVector", 0x0294F, // UP BARB RIGHT DOWN BARB RIGHT HARPOON -- "RightUpTeeVector", 0x0295C, // UPWARDS HARPOON WITH BARB RIGHT FROM BAR -- "RightUpVector", 0x021BE, // UPWARDS HARPOON WITH BARB RIGHTWARDS -- "RightUpVectorBar", 0x02954, // UPWARDS HARPOON WITH BARB RIGHT TO BAR -- "RightVector", 0x021C0, // RIGHTWARDS HARPOON WITH BARB UPWARDS -- "RightVectorBar", 0x02953, // RIGHTWARDS HARPOON WITH BARB UP TO BAR -- "ring", 0x002DA, // RING ABOVE -- "risingdotseq", 0x02253, // IMAGE OF OR APPROXIMATELY EQUAL TO -- "rlarr", 0x021C4, // RIGHTWARDS ARROW OVER LEFTWARDS ARROW -- "rlhar", 0x021CC, // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -- "rlm", 0x0200F, // RIGHT-TO-LEFT MARK -- "rmoust", 0x023B1, // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION -- "rmoustache", 0x023B1, // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION -- "rnmid", 0x02AEE, // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH -- "roang", 0x027ED, // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET -- "roarr", 0x021FE, // RIGHTWARDS OPEN-HEADED ARROW -- "robrk", 0x027E7, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET -- "ropar", 0x02986, // RIGHT WHITE PARENTHESIS -- "Ropf", 0x0211D, // DOUBLE-STRUCK CAPITAL R -- "ropf", 0x1D563, // MATHEMATICAL DOUBLE-STRUCK SMALL R -- "roplus", 0x02A2E, // PLUS SIGN IN RIGHT HALF CIRCLE -- "rotimes", 0x02A35, // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE -- "RoundImplies", 0x02970, // RIGHT DOUBLE ARROW WITH ROUNDED HEAD -- "rpar", 0x00029, // RIGHT PARENTHESIS -- "rpargt", 0x02994, // RIGHT ARC GREATER-THAN BRACKET -- "rppolint", 0x02A12, // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE -- "rrarr", 0x021C9, // RIGHTWARDS PAIRED ARROWS -- "Rrightarrow", 0x021DB, // RIGHTWARDS TRIPLE ARROW -- "rsaquo", 0x0203A, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK -- "Rscr", 0x0211B, // SCRIPT CAPITAL R -- "rscr", 0x1D4C7, // MATHEMATICAL SCRIPT SMALL R -- "rsh", 0x021B1, // UPWARDS ARROW WITH TIP RIGHTWARDS -- "Rsh", 0x021B1, // UPWARDS ARROW WITH TIP RIGHTWARDS -- "rsqb", 0x0005D, // RIGHT SQUARE BRACKET -- "rsquo", 0x02019, // RIGHT SINGLE QUOTATION MARK -- "rsquor", 0x02019, // RIGHT SINGLE QUOTATION MARK -- "rthree", 0x022CC, // RIGHT SEMIDIRECT PRODUCT -- "rtimes", 0x022CA, // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT -- "rtri", 0x025B9, // WHITE RIGHT-POINTING SMALL TRIANGLE -- "rtrie", 0x022B5, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -- "rtrif", 0x025B8, // BLACK RIGHT-POINTING SMALL TRIANGLE -- "rtriltri", 0x029CE, // RIGHT TRIANGLE ABOVE LEFT TRIANGLE -- "RuleDelayed", 0x029F4, // RULE-DELAYED -- "ruluhar", 0x02968, // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP -- "rx", 0x0211E, // PRESCRIPTION TAKE -- NULL, 0 -+ {"rAarr", 0x021DB}, // RIGHTWARDS TRIPLE ARROW -+// "race", 0x0223D;0x00331}, // REVERSED TILDE with underline -+ {"Racute", 0x00154}, // LATIN CAPITAL LETTER R WITH ACUTE -+ {"racute", 0x00155}, // LATIN SMALL LETTER R WITH ACUTE -+ {"radic", 0x0221A}, // SQUARE ROOT -+ {"raemptyv", 0x029B3}, // EMPTY SET WITH RIGHT ARROW ABOVE -+ {"rang", 0x027E9}, // MATHEMATICAL RIGHT ANGLE BRACKET -+ {"Rang", 0x027EB}, // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET -+ {"rangd", 0x02992}, // RIGHT ANGLE BRACKET WITH DOT -+ {"range", 0x029A5}, // REVERSED ANGLE WITH UNDERBAR -+ {"rangle", 0x027E9}, // MATHEMATICAL RIGHT ANGLE BRACKET -+ {"raquo", 0x000BB}, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -+ {"rarr", 0x02192}, // RIGHTWARDS ARROW -+ {"Rarr", 0x021A0}, // RIGHTWARDS TWO HEADED ARROW -+ {"rArr", 0x021D2}, // RIGHTWARDS DOUBLE ARROW -+ {"rarrap", 0x02975}, // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO -+ {"rarrb", 0x021E5}, // RIGHTWARDS ARROW TO BAR -+ {"rarrbfs", 0x02920}, // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND -+ {"rarrc", 0x02933}, // WAVE ARROW POINTING DIRECTLY RIGHT -+ {"rarrfs", 0x0291E}, // RIGHTWARDS ARROW TO BLACK DIAMOND -+ {"rarrhk", 0x021AA}, // RIGHTWARDS ARROW WITH HOOK -+ {"rarrlp", 0x021AC}, // RIGHTWARDS ARROW WITH LOOP -+ {"rarrpl", 0x02945}, // RIGHTWARDS ARROW WITH PLUS BELOW -+ {"rarrsim", 0x02974}, // RIGHTWARDS ARROW ABOVE TILDE OPERATOR -+ {"rarrtl", 0x021A3}, // RIGHTWARDS ARROW WITH TAIL -+ {"Rarrtl", 0x02916}, // RIGHTWARDS TWO-HEADED ARROW WITH TAIL -+ {"rarrw", 0x0219D}, // RIGHTWARDS WAVE ARROW -+ {"ratail", 0x0291A}, // RIGHTWARDS ARROW-TAIL -+ {"rAtail", 0x0291C}, // RIGHTWARDS DOUBLE ARROW-TAIL -+ {"ratio", 0x02236}, // RATIO -+ {"rationals", 0x0211A}, // DOUBLE-STRUCK CAPITAL Q -+ {"rbarr", 0x0290D}, // RIGHTWARDS DOUBLE DASH ARROW -+ {"rBarr", 0x0290F}, // RIGHTWARDS TRIPLE DASH ARROW -+ {"RBarr", 0x02910}, // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW -+ {"rbbrk", 0x02773}, // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT -+ {"rbrace", 0x0007D}, // RIGHT CURLY BRACKET -+ {"rbrack", 0x0005D}, // RIGHT SQUARE BRACKET -+ {"rbrke", 0x0298C}, // RIGHT SQUARE BRACKET WITH UNDERBAR -+ {"rbrksld", 0x0298E}, // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER -+ {"rbrkslu", 0x02990}, // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER -+ {"Rcaron", 0x00158}, // LATIN CAPITAL LETTER R WITH CARON -+ {"rcaron", 0x00159}, // LATIN SMALL LETTER R WITH CARON -+ {"Rcedil", 0x00156}, // LATIN CAPITAL LETTER R WITH CEDILLA -+ {"rcedil", 0x00157}, // LATIN SMALL LETTER R WITH CEDILLA -+ {"rceil", 0x02309}, // RIGHT CEILING -+ {"rcub", 0x0007D}, // RIGHT CURLY BRACKET -+ {"Rcy", 0x00420}, // CYRILLIC CAPITAL LETTER ER -+ {"rcy", 0x00440}, // CYRILLIC SMALL LETTER ER -+ {"rdca", 0x02937}, // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS -+ {"rdldhar", 0x02969}, // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN -+ {"rdquo", 0x0201D}, // RIGHT DOUBLE QUOTATION MARK -+ {"rdquor", 0x0201D}, // RIGHT DOUBLE QUOTATION MARK -+ {"rdsh", 0x021B3}, // DOWNWARDS ARROW WITH TIP RIGHTWARDS -+ {"Re", 0x0211C}, // BLACK-LETTER CAPITAL R -+ {"real", 0x0211C}, // BLACK-LETTER CAPITAL R -+ {"realine", 0x0211B}, // SCRIPT CAPITAL R -+ {"realpart", 0x0211C}, // BLACK-LETTER CAPITAL R -+ {"reals", 0x0211D}, // DOUBLE-STRUCK CAPITAL R -+ {"rect", 0x025AD}, // WHITE RECTANGLE -+ {"reg", 0x000AE}, // REGISTERED SIGN -+ {"REG", 0x000AE}, // REGISTERED SIGN -+ {"ReverseElement", 0x0220B}, // CONTAINS AS MEMBER -+ {"ReverseEquilibrium", 0x021CB}, // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -+ {"ReverseUpEquilibrium", 0x0296F}, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -+ {"rfisht", 0x0297D}, // RIGHT FISH TAIL -+ {"rfloor", 0x0230B}, // RIGHT FLOOR -+ {"Rfr", 0x0211C}, // BLACK-LETTER CAPITAL R -+ {"rfr", 0x1D52F}, // MATHEMATICAL FRAKTUR SMALL R -+ {"Rgr", 0x003A1}, // GREEK CAPITAL LETTER RHO -+ {"rgr", 0x003C1}, // GREEK SMALL LETTER RHO -+ {"rHar", 0x02964}, // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN -+ {"rhard", 0x021C1}, // RIGHTWARDS HARPOON WITH BARB DOWNWARDS -+ {"rharu", 0x021C0}, // RIGHTWARDS HARPOON WITH BARB UPWARDS -+ {"rharul", 0x0296C}, // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH -+ {"Rho", 0x003A1}, // GREEK CAPITAL LETTER RHO -+ {"rho", 0x003C1}, // GREEK SMALL LETTER RHO -+ {"rhov", 0x003F1}, // GREEK RHO SYMBOL -+ {"RightAngleBracket", 0x027E9}, // MATHEMATICAL RIGHT ANGLE BRACKET -+ {"rightarrow", 0x02192}, // RIGHTWARDS ARROW -+ {"RightArrow", 0x02192}, // RIGHTWARDS ARROW -+ {"Rightarrow", 0x021D2}, // RIGHTWARDS DOUBLE ARROW -+ {"RightArrowBar", 0x021E5}, // RIGHTWARDS ARROW TO BAR -+ {"RightArrowLeftArrow", 0x021C4}, // RIGHTWARDS ARROW OVER LEFTWARDS ARROW -+ {"rightarrowtail", 0x021A3}, // RIGHTWARDS ARROW WITH TAIL -+ {"RightCeiling", 0x02309}, // RIGHT CEILING -+ {"RightDoubleBracket", 0x027E7}, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET -+ {"RightDownTeeVector", 0x0295D}, // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR -+ {"RightDownVector", 0x021C2}, // DOWNWARDS HARPOON WITH BARB RIGHTWARDS -+ {"RightDownVectorBar", 0x02955}, // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR -+ {"RightFloor", 0x0230B}, // RIGHT FLOOR -+ {"rightharpoondown", 0x021C1}, // RIGHTWARDS HARPOON WITH BARB DOWNWARDS -+ {"rightharpoonup", 0x021C0}, // RIGHTWARDS HARPOON WITH BARB UPWARDS -+ {"rightleftarrows", 0x021C4}, // RIGHTWARDS ARROW OVER LEFTWARDS ARROW -+ {"rightleftharpoons", 0x021CC}, // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -+ {"rightrightarrows", 0x021C9}, // RIGHTWARDS PAIRED ARROWS -+ {"rightsquigarrow", 0x0219D}, // RIGHTWARDS WAVE ARROW -+ {"RightTee", 0x022A2}, // RIGHT TACK -+ {"RightTeeArrow", 0x021A6}, // RIGHTWARDS ARROW FROM BAR -+ {"RightTeeVector", 0x0295B}, // RIGHTWARDS HARPOON WITH BARB UP FROM BAR -+ {"rightthreetimes", 0x022CC}, // RIGHT SEMIDIRECT PRODUCT -+ {"RightTriangle", 0x022B3}, // CONTAINS AS NORMAL SUBGROUP -+ {"RightTriangleBar", 0x029D0}, // VERTICAL BAR BESIDE RIGHT TRIANGLE -+ {"RightTriangleEqual", 0x022B5}, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -+ {"RightUpDownVector", 0x0294F}, // UP BARB RIGHT DOWN BARB RIGHT HARPOON -+ {"RightUpTeeVector", 0x0295C}, // UPWARDS HARPOON WITH BARB RIGHT FROM BAR -+ {"RightUpVector", 0x021BE}, // UPWARDS HARPOON WITH BARB RIGHTWARDS -+ {"RightUpVectorBar", 0x02954}, // UPWARDS HARPOON WITH BARB RIGHT TO BAR -+ {"RightVector", 0x021C0}, // RIGHTWARDS HARPOON WITH BARB UPWARDS -+ {"RightVectorBar", 0x02953}, // RIGHTWARDS HARPOON WITH BARB UP TO BAR -+ {"ring", 0x002DA}, // RING ABOVE -+ {"risingdotseq", 0x02253}, // IMAGE OF OR APPROXIMATELY EQUAL TO -+ {"rlarr", 0x021C4}, // RIGHTWARDS ARROW OVER LEFTWARDS ARROW -+ {"rlhar", 0x021CC}, // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -+ {"rlm", 0x0200F}, // RIGHT-TO-LEFT MARK -+ {"rmoust", 0x023B1}, // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION -+ {"rmoustache", 0x023B1}, // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION -+ {"rnmid", 0x02AEE}, // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH -+ {"roang", 0x027ED}, // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET -+ {"roarr", 0x021FE}, // RIGHTWARDS OPEN-HEADED ARROW -+ {"robrk", 0x027E7}, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET -+ {"ropar", 0x02986}, // RIGHT WHITE PARENTHESIS -+ {"Ropf", 0x0211D}, // DOUBLE-STRUCK CAPITAL R -+ {"ropf", 0x1D563}, // MATHEMATICAL DOUBLE-STRUCK SMALL R -+ {"roplus", 0x02A2E}, // PLUS SIGN IN RIGHT HALF CIRCLE -+ {"rotimes", 0x02A35}, // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE -+ {"RoundImplies", 0x02970}, // RIGHT DOUBLE ARROW WITH ROUNDED HEAD -+ {"rpar", 0x00029}, // RIGHT PARENTHESIS -+ {"rpargt", 0x02994}, // RIGHT ARC GREATER-THAN BRACKET -+ {"rppolint", 0x02A12}, // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE -+ {"rrarr", 0x021C9}, // RIGHTWARDS PAIRED ARROWS -+ {"Rrightarrow", 0x021DB}, // RIGHTWARDS TRIPLE ARROW -+ {"rsaquo", 0x0203A}, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK -+ {"Rscr", 0x0211B}, // SCRIPT CAPITAL R -+ {"rscr", 0x1D4C7}, // MATHEMATICAL SCRIPT SMALL R -+ {"rsh", 0x021B1}, // UPWARDS ARROW WITH TIP RIGHTWARDS -+ {"Rsh", 0x021B1}, // UPWARDS ARROW WITH TIP RIGHTWARDS -+ {"rsqb", 0x0005D}, // RIGHT SQUARE BRACKET -+ {"rsquo", 0x02019}, // RIGHT SINGLE QUOTATION MARK -+ {"rsquor", 0x02019}, // RIGHT SINGLE QUOTATION MARK -+ {"rthree", 0x022CC}, // RIGHT SEMIDIRECT PRODUCT -+ {"rtimes", 0x022CA}, // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT -+ {"rtri", 0x025B9}, // WHITE RIGHT-POINTING SMALL TRIANGLE -+ {"rtrie", 0x022B5}, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -+ {"rtrif", 0x025B8}, // BLACK RIGHT-POINTING SMALL TRIANGLE -+ {"rtriltri", 0x029CE}, // RIGHT TRIANGLE ABOVE LEFT TRIANGLE -+ {"RuleDelayed", 0x029F4}, // RULE-DELAYED -+ {"ruluhar", 0x02968}, // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP -+ {"rx", 0x0211E}, // PRESCRIPTION TAKE -+ {NULL, 0} - }; - - static NameId namesS[]={ -- "Sacute", 0x0015A, // LATIN CAPITAL LETTER S WITH ACUTE -- "sacute", 0x0015B, // LATIN SMALL LETTER S WITH ACUTE -- "sbquo", 0x0201A, // SINGLE LOW-9 QUOTATION MARK -- "sc", 0x0227B, // SUCCEEDS -- "Sc", 0x02ABC, // DOUBLE SUCCEEDS -- "scap", 0x02AB8, // SUCCEEDS ABOVE ALMOST EQUAL TO -- "Scaron", 0x00160, // LATIN CAPITAL LETTER S WITH CARON -- "scaron", 0x00161, // LATIN SMALL LETTER S WITH CARON -- "sccue", 0x0227D, // SUCCEEDS OR EQUAL TO -- "sce", 0x02AB0, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -- "scE", 0x02AB4, // SUCCEEDS ABOVE EQUALS SIGN -- "Scedil", 0x0015E, // LATIN CAPITAL LETTER S WITH CEDILLA -- "scedil", 0x0015F, // LATIN SMALL LETTER S WITH CEDILLA -- "Scirc", 0x0015C, // LATIN CAPITAL LETTER S WITH CIRCUMFLEX -- "scirc", 0x0015D, // LATIN SMALL LETTER S WITH CIRCUMFLEX -- "scnap", 0x02ABA, // SUCCEEDS ABOVE NOT ALMOST EQUAL TO -- "scnE", 0x02AB6, // SUCCEEDS ABOVE NOT EQUAL TO -- "scnsim", 0x022E9, // SUCCEEDS BUT NOT EQUIVALENT TO -- "scpolint", 0x02A13, // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE -- "scsim", 0x0227F, // SUCCEEDS OR EQUIVALENT TO -- "Scy", 0x00421, // CYRILLIC CAPITAL LETTER ES -- "scy", 0x00441, // CYRILLIC SMALL LETTER ES -- "sdot", 0x022C5, // DOT OPERATOR -- "sdotb", 0x022A1, // SQUARED DOT OPERATOR -- "sdote", 0x02A66, // EQUALS SIGN WITH DOT BELOW -- "searhk", 0x02925, // SOUTH EAST ARROW WITH HOOK -- "searr", 0x02198, // SOUTH EAST ARROW -- "seArr", 0x021D8, // SOUTH EAST DOUBLE ARROW -- "searrow", 0x02198, // SOUTH EAST ARROW -- "sect", 0x000A7, // SECTION SIGN -- "semi", 0x0003B, // SEMICOLON -- "seswar", 0x02929, // SOUTH EAST ARROW AND SOUTH WEST ARROW -- "setminus", 0x02216, // SET MINUS -- "setmn", 0x02216, // SET MINUS -- "sext", 0x02736, // SIX POINTED BLACK STAR -- "sfgr", 0x003C2, // GREEK SMALL LETTER FINAL SIGMA -- "Sfr", 0x1D516, // MATHEMATICAL FRAKTUR CAPITAL S -- "sfr", 0x1D530, // MATHEMATICAL FRAKTUR SMALL S -- "sfrown", 0x02322, // FROWN -- "Sgr", 0x003A3, // GREEK CAPITAL LETTER SIGMA -- "sgr", 0x003C3, // GREEK SMALL LETTER SIGMA -- "sharp", 0x0266F, // MUSIC SHARP SIGN -- "SHCHcy", 0x00429, // CYRILLIC CAPITAL LETTER SHCHA -- "shchcy", 0x00449, // CYRILLIC SMALL LETTER SHCHA -- "SHcy", 0x00428, // CYRILLIC CAPITAL LETTER SHA -- "shcy", 0x00448, // CYRILLIC SMALL LETTER SHA -- "ShortDownArrow", 0x02193, // DOWNWARDS ARROW -- "ShortLeftArrow", 0x02190, // LEFTWARDS ARROW -- "shortmid", 0x02223, // DIVIDES -- "shortparallel", 0x02225, // PARALLEL TO -- "ShortRightArrow", 0x02192, // RIGHTWARDS ARROW -- "ShortUpArrow", 0x02191, // UPWARDS ARROW -- "shy", 0x000AD, // SOFT HYPHEN -- "Sigma", 0x003A3, // GREEK CAPITAL LETTER SIGMA -- "sigma", 0x003C3, // GREEK SMALL LETTER SIGMA -- "sigmaf", 0x003C2, // GREEK SMALL LETTER FINAL SIGMA -- "sigmav", 0x003C2, // GREEK SMALL LETTER FINAL SIGMA -- "sim", 0x0223C, // TILDE OPERATOR -- "simdot", 0x02A6A, // TILDE OPERATOR WITH DOT ABOVE -- "sime", 0x02243, // ASYMPTOTICALLY EQUAL TO -- "simeq", 0x02243, // ASYMPTOTICALLY EQUAL TO -- "simg", 0x02A9E, // SIMILAR OR GREATER-THAN -- "simgE", 0x02AA0, // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN -- "siml", 0x02A9D, // SIMILAR OR LESS-THAN -- "simlE", 0x02A9F, // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN -- "simne", 0x02246, // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO -- "simplus", 0x02A24, // PLUS SIGN WITH TILDE ABOVE -- "simrarr", 0x02972, // TILDE OPERATOR ABOVE RIGHTWARDS ARROW -- "slarr", 0x02190, // LEFTWARDS ARROW -- "SmallCircle", 0x02218, // RING OPERATOR -- "smallsetminus", 0x02216, // SET MINUS -- "smashp", 0x02A33, // SMASH PRODUCT -- "smeparsl", 0x029E4, // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE -- "smid", 0x02223, // DIVIDES -- "smile", 0x02323, // SMILE -- "smt", 0x02AAA, // SMALLER THAN -- "smte", 0x02AAC, // SMALLER THAN OR EQUAL TO --// "smtes", 0x02AAC;0x0FE00, // SMALLER THAN OR slanted EQUAL -- "SOFTcy", 0x0042C, // CYRILLIC CAPITAL LETTER SOFT SIGN -- "softcy", 0x0044C, // CYRILLIC SMALL LETTER SOFT SIGN -- "sol", 0x0002F, // SOLIDUS -- "solb", 0x029C4, // SQUARED RISING DIAGONAL SLASH -- "solbar", 0x0233F, // APL FUNCTIONAL SYMBOL SLASH BAR -- "Sopf", 0x1D54A, // MATHEMATICAL DOUBLE-STRUCK CAPITAL S -- "sopf", 0x1D564, // MATHEMATICAL DOUBLE-STRUCK SMALL S -- "spades", 0x02660, // BLACK SPADE SUIT -- "spadesuit", 0x02660, // BLACK SPADE SUIT -- "spar", 0x02225, // PARALLEL TO -- "sqcap", 0x02293, // SQUARE CAP --// "sqcaps", 0x02293;0x0FE00, // SQUARE CAP with serifs -- "sqcup", 0x02294, // SQUARE CUP --// "sqcups", 0x02294;0x0FE00, // SQUARE CUP with serifs -- "Sqrt", 0x0221A, // SQUARE ROOT -- "sqsub", 0x0228F, // SQUARE IMAGE OF -- "sqsube", 0x02291, // SQUARE IMAGE OF OR EQUAL TO -- "sqsubset", 0x0228F, // SQUARE IMAGE OF -- "sqsubseteq", 0x02291, // SQUARE IMAGE OF OR EQUAL TO -- "sqsup", 0x02290, // SQUARE ORIGINAL OF -- "sqsupe", 0x02292, // SQUARE ORIGINAL OF OR EQUAL TO -- "sqsupset", 0x02290, // SQUARE ORIGINAL OF -- "sqsupseteq", 0x02292, // SQUARE ORIGINAL OF OR EQUAL TO -- "squ", 0x025A1, // WHITE SQUARE -- "square", 0x025A1, // WHITE SQUARE -- "Square", 0x025A1, // WHITE SQUARE -- "SquareIntersection", 0x02293, // SQUARE CAP -- "SquareSubset", 0x0228F, // SQUARE IMAGE OF -- "SquareSubsetEqual", 0x02291, // SQUARE IMAGE OF OR EQUAL TO -- "SquareSuperset", 0x02290, // SQUARE ORIGINAL OF -- "SquareSupersetEqual", 0x02292, // SQUARE ORIGINAL OF OR EQUAL TO -- "SquareUnion", 0x02294, // SQUARE CUP -- "squarf", 0x025AA, // BLACK SMALL SQUARE -- "squf", 0x025AA, // BLACK SMALL SQUARE -- "srarr", 0x02192, // RIGHTWARDS ARROW -- "Sscr", 0x1D4AE, // MATHEMATICAL SCRIPT CAPITAL S -- "sscr", 0x1D4C8, // MATHEMATICAL SCRIPT SMALL S -- "ssetmn", 0x02216, // SET MINUS -- "ssmile", 0x02323, // SMILE -- "sstarf", 0x022C6, // STAR OPERATOR -- "Star", 0x022C6, // STAR OPERATOR -- "star", 0x02606, // WHITE STAR -- "starf", 0x02605, // BLACK STAR -- "straightepsilon", 0x003F5, // GREEK LUNATE EPSILON SYMBOL -- "straightphi", 0x003D5, // GREEK PHI SYMBOL -- "strns", 0x000AF, // MACRON -- "sub", 0x02282, // SUBSET OF -- "Sub", 0x022D0, // DOUBLE SUBSET -- "subdot", 0x02ABD, // SUBSET WITH DOT -- "sube", 0x02286, // SUBSET OF OR EQUAL TO -- "subE", 0x02AC5, // SUBSET OF ABOVE EQUALS SIGN -- "subedot", 0x02AC3, // SUBSET OF OR EQUAL TO WITH DOT ABOVE -- "submult", 0x02AC1, // SUBSET WITH MULTIPLICATION SIGN BELOW -- "subne", 0x0228A, // SUBSET OF WITH NOT EQUAL TO -- "subnE", 0x02ACB, // SUBSET OF ABOVE NOT EQUAL TO -- "subplus", 0x02ABF, // SUBSET WITH PLUS SIGN BELOW -- "subrarr", 0x02979, // SUBSET ABOVE RIGHTWARDS ARROW -- "subset", 0x02282, // SUBSET OF -- "Subset", 0x022D0, // DOUBLE SUBSET -- "subseteq", 0x02286, // SUBSET OF OR EQUAL TO -- "subseteqq", 0x02AC5, // SUBSET OF ABOVE EQUALS SIGN -- "SubsetEqual", 0x02286, // SUBSET OF OR EQUAL TO -- "subsetneq", 0x0228A, // SUBSET OF WITH NOT EQUAL TO -- "subsetneqq", 0x02ACB, // SUBSET OF ABOVE NOT EQUAL TO -- "subsim", 0x02AC7, // SUBSET OF ABOVE TILDE OPERATOR -- "subsub", 0x02AD5, // SUBSET ABOVE SUBSET -- "subsup", 0x02AD3, // SUBSET ABOVE SUPERSET -- "succ", 0x0227B, // SUCCEEDS -- "succapprox", 0x02AB8, // SUCCEEDS ABOVE ALMOST EQUAL TO -- "succcurlyeq", 0x0227D, // SUCCEEDS OR EQUAL TO -- "Succeeds", 0x0227B, // SUCCEEDS -- "SucceedsEqual", 0x02AB0, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -- "SucceedsSlantEqual", 0x0227D, // SUCCEEDS OR EQUAL TO -- "SucceedsTilde", 0x0227F, // SUCCEEDS OR EQUIVALENT TO -- "succeq", 0x02AB0, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -- "succnapprox", 0x02ABA, // SUCCEEDS ABOVE NOT ALMOST EQUAL TO -- "succneqq", 0x02AB6, // SUCCEEDS ABOVE NOT EQUAL TO -- "succnsim", 0x022E9, // SUCCEEDS BUT NOT EQUIVALENT TO -- "succsim", 0x0227F, // SUCCEEDS OR EQUIVALENT TO -- "SuchThat", 0x0220B, // CONTAINS AS MEMBER -- "sum", 0x02211, // N-ARY SUMMATION -- "Sum", 0x02211, // N-ARY SUMMATION -- "sung", 0x0266A, // EIGHTH NOTE -- "sup", 0x02283, // SUPERSET OF -- "Sup", 0x022D1, // DOUBLE SUPERSET -- "sup1", 0x000B9, // SUPERSCRIPT ONE -- "sup2", 0x000B2, // SUPERSCRIPT TWO -- "sup3", 0x000B3, // SUPERSCRIPT THREE -- "supdot", 0x02ABE, // SUPERSET WITH DOT -- "supdsub", 0x02AD8, // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET -- "supe", 0x02287, // SUPERSET OF OR EQUAL TO -- "supE", 0x02AC6, // SUPERSET OF ABOVE EQUALS SIGN -- "supedot", 0x02AC4, // SUPERSET OF OR EQUAL TO WITH DOT ABOVE -- "Superset", 0x02283, // SUPERSET OF -- "SupersetEqual", 0x02287, // SUPERSET OF OR EQUAL TO -- "suphsol", 0x027C9, // SUPERSET PRECEDING SOLIDUS -- "suphsub", 0x02AD7, // SUPERSET BESIDE SUBSET -- "suplarr", 0x0297B, // SUPERSET ABOVE LEFTWARDS ARROW -- "supmult", 0x02AC2, // SUPERSET WITH MULTIPLICATION SIGN BELOW -- "supne", 0x0228B, // SUPERSET OF WITH NOT EQUAL TO -- "supnE", 0x02ACC, // SUPERSET OF ABOVE NOT EQUAL TO -- "supplus", 0x02AC0, // SUPERSET WITH PLUS SIGN BELOW -- "supset", 0x02283, // SUPERSET OF -- "Supset", 0x022D1, // DOUBLE SUPERSET -- "supseteq", 0x02287, // SUPERSET OF OR EQUAL TO -- "supseteqq", 0x02AC6, // SUPERSET OF ABOVE EQUALS SIGN -- "supsetneq", 0x0228B, // SUPERSET OF WITH NOT EQUAL TO -- "supsetneqq", 0x02ACC, // SUPERSET OF ABOVE NOT EQUAL TO -- "supsim", 0x02AC8, // SUPERSET OF ABOVE TILDE OPERATOR -- "supsub", 0x02AD4, // SUPERSET ABOVE SUBSET -- "supsup", 0x02AD6, // SUPERSET ABOVE SUPERSET -- "swarhk", 0x02926, // SOUTH WEST ARROW WITH HOOK -- "swarr", 0x02199, // SOUTH WEST ARROW -- "swArr", 0x021D9, // SOUTH WEST DOUBLE ARROW -- "swarrow", 0x02199, // SOUTH WEST ARROW -- "swnwar", 0x0292A, // SOUTH WEST ARROW AND NORTH WEST ARROW -- "szlig", 0x000DF, // LATIN SMALL LETTER SHARP S -- NULL, 0 -+ {"Sacute", 0x0015A}, // LATIN CAPITAL LETTER S WITH ACUTE -+ {"sacute", 0x0015B}, // LATIN SMALL LETTER S WITH ACUTE -+ {"sbquo", 0x0201A}, // SINGLE LOW-9 QUOTATION MARK -+ {"sc", 0x0227B}, // SUCCEEDS -+ {"Sc", 0x02ABC}, // DOUBLE SUCCEEDS -+ {"scap", 0x02AB8}, // SUCCEEDS ABOVE ALMOST EQUAL TO -+ {"Scaron", 0x00160}, // LATIN CAPITAL LETTER S WITH CARON -+ {"scaron", 0x00161}, // LATIN SMALL LETTER S WITH CARON -+ {"sccue", 0x0227D}, // SUCCEEDS OR EQUAL TO -+ {"sce", 0x02AB0}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -+ {"scE", 0x02AB4}, // SUCCEEDS ABOVE EQUALS SIGN -+ {"Scedil", 0x0015E}, // LATIN CAPITAL LETTER S WITH CEDILLA -+ {"scedil", 0x0015F}, // LATIN SMALL LETTER S WITH CEDILLA -+ {"Scirc", 0x0015C}, // LATIN CAPITAL LETTER S WITH CIRCUMFLEX -+ {"scirc", 0x0015D}, // LATIN SMALL LETTER S WITH CIRCUMFLEX -+ {"scnap", 0x02ABA}, // SUCCEEDS ABOVE NOT ALMOST EQUAL TO -+ {"scnE", 0x02AB6}, // SUCCEEDS ABOVE NOT EQUAL TO -+ {"scnsim", 0x022E9}, // SUCCEEDS BUT NOT EQUIVALENT TO -+ {"scpolint", 0x02A13}, // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE -+ {"scsim", 0x0227F}, // SUCCEEDS OR EQUIVALENT TO -+ {"Scy", 0x00421}, // CYRILLIC CAPITAL LETTER ES -+ {"scy", 0x00441}, // CYRILLIC SMALL LETTER ES -+ {"sdot", 0x022C5}, // DOT OPERATOR -+ {"sdotb", 0x022A1}, // SQUARED DOT OPERATOR -+ {"sdote", 0x02A66}, // EQUALS SIGN WITH DOT BELOW -+ {"searhk", 0x02925}, // SOUTH EAST ARROW WITH HOOK -+ {"searr", 0x02198}, // SOUTH EAST ARROW -+ {"seArr", 0x021D8}, // SOUTH EAST DOUBLE ARROW -+ {"searrow", 0x02198}, // SOUTH EAST ARROW -+ {"sect", 0x000A7}, // SECTION SIGN -+ {"semi", 0x0003B}, // SEMICOLON -+ {"seswar", 0x02929}, // SOUTH EAST ARROW AND SOUTH WEST ARROW -+ {"setminus", 0x02216}, // SET MINUS -+ {"setmn", 0x02216}, // SET MINUS -+ {"sext", 0x02736}, // SIX POINTED BLACK STAR -+ {"sfgr", 0x003C2}, // GREEK SMALL LETTER FINAL SIGMA -+ {"Sfr", 0x1D516}, // MATHEMATICAL FRAKTUR CAPITAL S -+ {"sfr", 0x1D530}, // MATHEMATICAL FRAKTUR SMALL S -+ {"sfrown", 0x02322}, // FROWN -+ {"Sgr", 0x003A3}, // GREEK CAPITAL LETTER SIGMA -+ {"sgr", 0x003C3}, // GREEK SMALL LETTER SIGMA -+ {"sharp", 0x0266F}, // MUSIC SHARP SIGN -+ {"SHCHcy", 0x00429}, // CYRILLIC CAPITAL LETTER SHCHA -+ {"shchcy", 0x00449}, // CYRILLIC SMALL LETTER SHCHA -+ {"SHcy", 0x00428}, // CYRILLIC CAPITAL LETTER SHA -+ {"shcy", 0x00448}, // CYRILLIC SMALL LETTER SHA -+ {"ShortDownArrow", 0x02193}, // DOWNWARDS ARROW -+ {"ShortLeftArrow", 0x02190}, // LEFTWARDS ARROW -+ {"shortmid", 0x02223}, // DIVIDES -+ {"shortparallel", 0x02225}, // PARALLEL TO -+ {"ShortRightArrow", 0x02192}, // RIGHTWARDS ARROW -+ {"ShortUpArrow", 0x02191}, // UPWARDS ARROW -+ {"shy", 0x000AD}, // SOFT HYPHEN -+ {"Sigma", 0x003A3}, // GREEK CAPITAL LETTER SIGMA -+ {"sigma", 0x003C3}, // GREEK SMALL LETTER SIGMA -+ {"sigmaf", 0x003C2}, // GREEK SMALL LETTER FINAL SIGMA -+ {"sigmav", 0x003C2}, // GREEK SMALL LETTER FINAL SIGMA -+ {"sim", 0x0223C}, // TILDE OPERATOR -+ {"simdot", 0x02A6A}, // TILDE OPERATOR WITH DOT ABOVE -+ {"sime", 0x02243}, // ASYMPTOTICALLY EQUAL TO -+ {"simeq", 0x02243}, // ASYMPTOTICALLY EQUAL TO -+ {"simg", 0x02A9E}, // SIMILAR OR GREATER-THAN -+ {"simgE", 0x02AA0}, // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN -+ {"siml", 0x02A9D}, // SIMILAR OR LESS-THAN -+ {"simlE", 0x02A9F}, // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN -+ {"simne", 0x02246}, // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO -+ {"simplus", 0x02A24}, // PLUS SIGN WITH TILDE ABOVE -+ {"simrarr", 0x02972}, // TILDE OPERATOR ABOVE RIGHTWARDS ARROW -+ {"slarr", 0x02190}, // LEFTWARDS ARROW -+ {"SmallCircle", 0x02218}, // RING OPERATOR -+ {"smallsetminus", 0x02216}, // SET MINUS -+ {"smashp", 0x02A33}, // SMASH PRODUCT -+ {"smeparsl", 0x029E4}, // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE -+ {"smid", 0x02223}, // DIVIDES -+ {"smile", 0x02323}, // SMILE -+ {"smt", 0x02AAA}, // SMALLER THAN -+ {"smte", 0x02AAC}, // SMALLER THAN OR EQUAL TO -+// "smtes", 0x02AAC;0x0FE00}, // SMALLER THAN OR slanted EQUAL -+ {"SOFTcy", 0x0042C}, // CYRILLIC CAPITAL LETTER SOFT SIGN -+ {"softcy", 0x0044C}, // CYRILLIC SMALL LETTER SOFT SIGN -+ {"sol", 0x0002F}, // SOLIDUS -+ {"solb", 0x029C4}, // SQUARED RISING DIAGONAL SLASH -+ {"solbar", 0x0233F}, // APL FUNCTIONAL SYMBOL SLASH BAR -+ {"Sopf", 0x1D54A}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL S -+ {"sopf", 0x1D564}, // MATHEMATICAL DOUBLE-STRUCK SMALL S -+ {"spades", 0x02660}, // BLACK SPADE SUIT -+ {"spadesuit", 0x02660}, // BLACK SPADE SUIT -+ {"spar", 0x02225}, // PARALLEL TO -+ {"sqcap", 0x02293}, // SQUARE CAP -+// "sqcaps", 0x02293;0x0FE00}, // SQUARE CAP with serifs -+ {"sqcup", 0x02294}, // SQUARE CUP -+// "sqcups", 0x02294;0x0FE00}, // SQUARE CUP with serifs -+ {"Sqrt", 0x0221A}, // SQUARE ROOT -+ {"sqsub", 0x0228F}, // SQUARE IMAGE OF -+ {"sqsube", 0x02291}, // SQUARE IMAGE OF OR EQUAL TO -+ {"sqsubset", 0x0228F}, // SQUARE IMAGE OF -+ {"sqsubseteq", 0x02291}, // SQUARE IMAGE OF OR EQUAL TO -+ {"sqsup", 0x02290}, // SQUARE ORIGINAL OF -+ {"sqsupe", 0x02292}, // SQUARE ORIGINAL OF OR EQUAL TO -+ {"sqsupset", 0x02290}, // SQUARE ORIGINAL OF -+ {"sqsupseteq", 0x02292}, // SQUARE ORIGINAL OF OR EQUAL TO -+ {"squ", 0x025A1}, // WHITE SQUARE -+ {"square", 0x025A1}, // WHITE SQUARE -+ {"Square", 0x025A1}, // WHITE SQUARE -+ {"SquareIntersection", 0x02293}, // SQUARE CAP -+ {"SquareSubset", 0x0228F}, // SQUARE IMAGE OF -+ {"SquareSubsetEqual", 0x02291}, // SQUARE IMAGE OF OR EQUAL TO -+ {"SquareSuperset", 0x02290}, // SQUARE ORIGINAL OF -+ {"SquareSupersetEqual", 0x02292}, // SQUARE ORIGINAL OF OR EQUAL TO -+ {"SquareUnion", 0x02294}, // SQUARE CUP -+ {"squarf", 0x025AA}, // BLACK SMALL SQUARE -+ {"squf", 0x025AA}, // BLACK SMALL SQUARE -+ {"srarr", 0x02192}, // RIGHTWARDS ARROW -+ {"Sscr", 0x1D4AE}, // MATHEMATICAL SCRIPT CAPITAL S -+ {"sscr", 0x1D4C8}, // MATHEMATICAL SCRIPT SMALL S -+ {"ssetmn", 0x02216}, // SET MINUS -+ {"ssmile", 0x02323}, // SMILE -+ {"sstarf", 0x022C6}, // STAR OPERATOR -+ {"Star", 0x022C6}, // STAR OPERATOR -+ {"star", 0x02606}, // WHITE STAR -+ {"starf", 0x02605}, // BLACK STAR -+ {"straightepsilon", 0x003F5}, // GREEK LUNATE EPSILON SYMBOL -+ {"straightphi", 0x003D5}, // GREEK PHI SYMBOL -+ {"strns", 0x000AF}, // MACRON -+ {"sub", 0x02282}, // SUBSET OF -+ {"Sub", 0x022D0}, // DOUBLE SUBSET -+ {"subdot", 0x02ABD}, // SUBSET WITH DOT -+ {"sube", 0x02286}, // SUBSET OF OR EQUAL TO -+ {"subE", 0x02AC5}, // SUBSET OF ABOVE EQUALS SIGN -+ {"subedot", 0x02AC3}, // SUBSET OF OR EQUAL TO WITH DOT ABOVE -+ {"submult", 0x02AC1}, // SUBSET WITH MULTIPLICATION SIGN BELOW -+ {"subne", 0x0228A}, // SUBSET OF WITH NOT EQUAL TO -+ {"subnE", 0x02ACB}, // SUBSET OF ABOVE NOT EQUAL TO -+ {"subplus", 0x02ABF}, // SUBSET WITH PLUS SIGN BELOW -+ {"subrarr", 0x02979}, // SUBSET ABOVE RIGHTWARDS ARROW -+ {"subset", 0x02282}, // SUBSET OF -+ {"Subset", 0x022D0}, // DOUBLE SUBSET -+ {"subseteq", 0x02286}, // SUBSET OF OR EQUAL TO -+ {"subseteqq", 0x02AC5}, // SUBSET OF ABOVE EQUALS SIGN -+ {"SubsetEqual", 0x02286}, // SUBSET OF OR EQUAL TO -+ {"subsetneq", 0x0228A}, // SUBSET OF WITH NOT EQUAL TO -+ {"subsetneqq", 0x02ACB}, // SUBSET OF ABOVE NOT EQUAL TO -+ {"subsim", 0x02AC7}, // SUBSET OF ABOVE TILDE OPERATOR -+ {"subsub", 0x02AD5}, // SUBSET ABOVE SUBSET -+ {"subsup", 0x02AD3}, // SUBSET ABOVE SUPERSET -+ {"succ", 0x0227B}, // SUCCEEDS -+ {"succapprox", 0x02AB8}, // SUCCEEDS ABOVE ALMOST EQUAL TO -+ {"succcurlyeq", 0x0227D}, // SUCCEEDS OR EQUAL TO -+ {"Succeeds", 0x0227B}, // SUCCEEDS -+ {"SucceedsEqual", 0x02AB0}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -+ {"SucceedsSlantEqual", 0x0227D}, // SUCCEEDS OR EQUAL TO -+ {"SucceedsTilde", 0x0227F}, // SUCCEEDS OR EQUIVALENT TO -+ {"succeq", 0x02AB0}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -+ {"succnapprox", 0x02ABA}, // SUCCEEDS ABOVE NOT ALMOST EQUAL TO -+ {"succneqq", 0x02AB6}, // SUCCEEDS ABOVE NOT EQUAL TO -+ {"succnsim", 0x022E9}, // SUCCEEDS BUT NOT EQUIVALENT TO -+ {"succsim", 0x0227F}, // SUCCEEDS OR EQUIVALENT TO -+ {"SuchThat", 0x0220B}, // CONTAINS AS MEMBER -+ {"sum", 0x02211}, // N-ARY SUMMATION -+ {"Sum", 0x02211}, // N-ARY SUMMATION -+ {"sung", 0x0266A}, // EIGHTH NOTE -+ {"sup", 0x02283}, // SUPERSET OF -+ {"Sup", 0x022D1}, // DOUBLE SUPERSET -+ {"sup1", 0x000B9}, // SUPERSCRIPT ONE -+ {"sup2", 0x000B2}, // SUPERSCRIPT TWO -+ {"sup3", 0x000B3}, // SUPERSCRIPT THREE -+ {"supdot", 0x02ABE}, // SUPERSET WITH DOT -+ {"supdsub", 0x02AD8}, // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET -+ {"supe", 0x02287}, // SUPERSET OF OR EQUAL TO -+ {"supE", 0x02AC6}, // SUPERSET OF ABOVE EQUALS SIGN -+ {"supedot", 0x02AC4}, // SUPERSET OF OR EQUAL TO WITH DOT ABOVE -+ {"Superset", 0x02283}, // SUPERSET OF -+ {"SupersetEqual", 0x02287}, // SUPERSET OF OR EQUAL TO -+ {"suphsol", 0x027C9}, // SUPERSET PRECEDING SOLIDUS -+ {"suphsub", 0x02AD7}, // SUPERSET BESIDE SUBSET -+ {"suplarr", 0x0297B}, // SUPERSET ABOVE LEFTWARDS ARROW -+ {"supmult", 0x02AC2}, // SUPERSET WITH MULTIPLICATION SIGN BELOW -+ {"supne", 0x0228B}, // SUPERSET OF WITH NOT EQUAL TO -+ {"supnE", 0x02ACC}, // SUPERSET OF ABOVE NOT EQUAL TO -+ {"supplus", 0x02AC0}, // SUPERSET WITH PLUS SIGN BELOW -+ {"supset", 0x02283}, // SUPERSET OF -+ {"Supset", 0x022D1}, // DOUBLE SUPERSET -+ {"supseteq", 0x02287}, // SUPERSET OF OR EQUAL TO -+ {"supseteqq", 0x02AC6}, // SUPERSET OF ABOVE EQUALS SIGN -+ {"supsetneq", 0x0228B}, // SUPERSET OF WITH NOT EQUAL TO -+ {"supsetneqq", 0x02ACC}, // SUPERSET OF ABOVE NOT EQUAL TO -+ {"supsim", 0x02AC8}, // SUPERSET OF ABOVE TILDE OPERATOR -+ {"supsub", 0x02AD4}, // SUPERSET ABOVE SUBSET -+ {"supsup", 0x02AD6}, // SUPERSET ABOVE SUPERSET -+ {"swarhk", 0x02926}, // SOUTH WEST ARROW WITH HOOK -+ {"swarr", 0x02199}, // SOUTH WEST ARROW -+ {"swArr", 0x021D9}, // SOUTH WEST DOUBLE ARROW -+ {"swarrow", 0x02199}, // SOUTH WEST ARROW -+ {"swnwar", 0x0292A}, // SOUTH WEST ARROW AND NORTH WEST ARROW -+ {"szlig", 0x000DF}, // LATIN SMALL LETTER SHARP S -+ {NULL, 0} - }; - - static NameId namesT[]={ -- "Tab", 0x00009, // CHARACTER TABULATION -- "target", 0x02316, // POSITION INDICATOR -- "Tau", 0x003A4, // GREEK CAPITAL LETTER TAU -- "tau", 0x003C4, // GREEK SMALL LETTER TAU -- "tbrk", 0x023B4, // TOP SQUARE BRACKET -- "Tcaron", 0x00164, // LATIN CAPITAL LETTER T WITH CARON -- "tcaron", 0x00165, // LATIN SMALL LETTER T WITH CARON -- "Tcedil", 0x00162, // LATIN CAPITAL LETTER T WITH CEDILLA -- "tcedil", 0x00163, // LATIN SMALL LETTER T WITH CEDILLA -- "Tcy", 0x00422, // CYRILLIC CAPITAL LETTER TE -- "tcy", 0x00442, // CYRILLIC SMALL LETTER TE -- "tdot", 0x020DB, // COMBINING THREE DOTS ABOVE -- "telrec", 0x02315, // TELEPHONE RECORDER -- "Tfr", 0x1D517, // MATHEMATICAL FRAKTUR CAPITAL T -- "tfr", 0x1D531, // MATHEMATICAL FRAKTUR SMALL T -- "Tgr", 0x003A4, // GREEK CAPITAL LETTER TAU -- "tgr", 0x003C4, // GREEK SMALL LETTER TAU -- "there4", 0x02234, // THEREFORE -- "therefore", 0x02234, // THEREFORE -- "Therefore", 0x02234, // THEREFORE -- "Theta", 0x00398, // GREEK CAPITAL LETTER THETA -- "theta", 0x003B8, // GREEK SMALL LETTER THETA -- "thetasym", 0x003D1, // GREEK THETA SYMBOL -- "thetav", 0x003D1, // GREEK THETA SYMBOL -- "THgr", 0x00398, // GREEK CAPITAL LETTER THETA -- "thgr", 0x003B8, // GREEK SMALL LETTER THETA -- "thickapprox", 0x02248, // ALMOST EQUAL TO -- "thicksim", 0x0223C, // TILDE OPERATOR --// "ThickSpace", 0x0205F;0x0200A, // space of width 5/18 em -- "thinsp", 0x02009, // THIN SPACE -- "ThinSpace", 0x02009, // THIN SPACE -- "thkap", 0x02248, // ALMOST EQUAL TO -- "thksim", 0x0223C, // TILDE OPERATOR -- "THORN", 0x000DE, // LATIN CAPITAL LETTER THORN -- "thorn", 0x000FE, // LATIN SMALL LETTER THORN -- "tilde", 0x002DC, // SMALL TILDE -- "Tilde", 0x0223C, // TILDE OPERATOR -- "TildeEqual", 0x02243, // ASYMPTOTICALLY EQUAL TO -- "TildeFullEqual", 0x02245, // APPROXIMATELY EQUAL TO -- "TildeTilde", 0x02248, // ALMOST EQUAL TO -- "times", 0x000D7, // MULTIPLICATION SIGN -- "timesb", 0x022A0, // SQUARED TIMES -- "timesbar", 0x02A31, // MULTIPLICATION SIGN WITH UNDERBAR -- "timesd", 0x02A30, // MULTIPLICATION SIGN WITH DOT ABOVE -- "tint", 0x0222D, // TRIPLE INTEGRAL -- "toea", 0x02928, // NORTH EAST ARROW AND SOUTH EAST ARROW -- "top", 0x022A4, // DOWN TACK -- "topbot", 0x02336, // APL FUNCTIONAL SYMBOL I-BEAM -- "topcir", 0x02AF1, // DOWN TACK WITH CIRCLE BELOW -- "Topf", 0x1D54B, // MATHEMATICAL DOUBLE-STRUCK CAPITAL T -- "topf", 0x1D565, // MATHEMATICAL DOUBLE-STRUCK SMALL T -- "topfork", 0x02ADA, // PITCHFORK WITH TEE TOP -- "tosa", 0x02929, // SOUTH EAST ARROW AND SOUTH WEST ARROW -- "tprime", 0x02034, // TRIPLE PRIME -- "trade", 0x02122, // TRADE MARK SIGN -- "TRADE", 0x02122, // TRADE MARK SIGN -- "triangle", 0x025B5, // WHITE UP-POINTING SMALL TRIANGLE -- "triangledown", 0x025BF, // WHITE DOWN-POINTING SMALL TRIANGLE -- "triangleleft", 0x025C3, // WHITE LEFT-POINTING SMALL TRIANGLE -- "trianglelefteq", 0x022B4, // NORMAL SUBGROUP OF OR EQUAL TO -- "triangleq", 0x0225C, // DELTA EQUAL TO -- "triangleright", 0x025B9, // WHITE RIGHT-POINTING SMALL TRIANGLE -- "trianglerighteq", 0x022B5, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -- "tridot", 0x025EC, // WHITE UP-POINTING TRIANGLE WITH DOT -- "trie", 0x0225C, // DELTA EQUAL TO -- "triminus", 0x02A3A, // MINUS SIGN IN TRIANGLE -- "TripleDot", 0x020DB, // COMBINING THREE DOTS ABOVE -- "triplus", 0x02A39, // PLUS SIGN IN TRIANGLE -- "trisb", 0x029CD, // TRIANGLE WITH SERIFS AT BOTTOM -- "tritime", 0x02A3B, // MULTIPLICATION SIGN IN TRIANGLE -- "trpezium", 0x023E2, // WHITE TRAPEZIUM -- "Tscr", 0x1D4AF, // MATHEMATICAL SCRIPT CAPITAL T -- "tscr", 0x1D4C9, // MATHEMATICAL SCRIPT SMALL T -- "TScy", 0x00426, // CYRILLIC CAPITAL LETTER TSE -- "tscy", 0x00446, // CYRILLIC SMALL LETTER TSE -- "TSHcy", 0x0040B, // CYRILLIC CAPITAL LETTER TSHE -- "tshcy", 0x0045B, // CYRILLIC SMALL LETTER TSHE -- "Tstrok", 0x00166, // LATIN CAPITAL LETTER T WITH STROKE -- "tstrok", 0x00167, // LATIN SMALL LETTER T WITH STROKE -- "twixt", 0x0226C, // BETWEEN -- "twoheadleftarrow", 0x0219E, // LEFTWARDS TWO HEADED ARROW -- "twoheadrightarrow", 0x021A0, // RIGHTWARDS TWO HEADED ARROW -- NULL, 0 -+ {"Tab", 0x00009}, // CHARACTER TABULATION -+ {"target", 0x02316}, // POSITION INDICATOR -+ {"Tau", 0x003A4}, // GREEK CAPITAL LETTER TAU -+ {"tau", 0x003C4}, // GREEK SMALL LETTER TAU -+ {"tbrk", 0x023B4}, // TOP SQUARE BRACKET -+ {"Tcaron", 0x00164}, // LATIN CAPITAL LETTER T WITH CARON -+ {"tcaron", 0x00165}, // LATIN SMALL LETTER T WITH CARON -+ {"Tcedil", 0x00162}, // LATIN CAPITAL LETTER T WITH CEDILLA -+ {"tcedil", 0x00163}, // LATIN SMALL LETTER T WITH CEDILLA -+ {"Tcy", 0x00422}, // CYRILLIC CAPITAL LETTER TE -+ {"tcy", 0x00442}, // CYRILLIC SMALL LETTER TE -+ {"tdot", 0x020DB}, // COMBINING THREE DOTS ABOVE -+ {"telrec", 0x02315}, // TELEPHONE RECORDER -+ {"Tfr", 0x1D517}, // MATHEMATICAL FRAKTUR CAPITAL T -+ {"tfr", 0x1D531}, // MATHEMATICAL FRAKTUR SMALL T -+ {"Tgr", 0x003A4}, // GREEK CAPITAL LETTER TAU -+ {"tgr", 0x003C4}, // GREEK SMALL LETTER TAU -+ {"there4", 0x02234}, // THEREFORE -+ {"therefore", 0x02234}, // THEREFORE -+ {"Therefore", 0x02234}, // THEREFORE -+ {"Theta", 0x00398}, // GREEK CAPITAL LETTER THETA -+ {"theta", 0x003B8}, // GREEK SMALL LETTER THETA -+ {"thetasym", 0x003D1}, // GREEK THETA SYMBOL -+ {"thetav", 0x003D1}, // GREEK THETA SYMBOL -+ {"THgr", 0x00398}, // GREEK CAPITAL LETTER THETA -+ {"thgr", 0x003B8}, // GREEK SMALL LETTER THETA -+ {"thickapprox", 0x02248}, // ALMOST EQUAL TO -+ {"thicksim", 0x0223C}, // TILDE OPERATOR -+// "ThickSpace", 0x0205F;0x0200A}, // space of width 5/18 em -+ {"thinsp", 0x02009}, // THIN SPACE -+ {"ThinSpace", 0x02009}, // THIN SPACE -+ {"thkap", 0x02248}, // ALMOST EQUAL TO -+ {"thksim", 0x0223C}, // TILDE OPERATOR -+ {"THORN", 0x000DE}, // LATIN CAPITAL LETTER THORN -+ {"thorn", 0x000FE}, // LATIN SMALL LETTER THORN -+ {"tilde", 0x002DC}, // SMALL TILDE -+ {"Tilde", 0x0223C}, // TILDE OPERATOR -+ {"TildeEqual", 0x02243}, // ASYMPTOTICALLY EQUAL TO -+ {"TildeFullEqual", 0x02245}, // APPROXIMATELY EQUAL TO -+ {"TildeTilde", 0x02248}, // ALMOST EQUAL TO -+ {"times", 0x000D7}, // MULTIPLICATION SIGN -+ {"timesb", 0x022A0}, // SQUARED TIMES -+ {"timesbar", 0x02A31}, // MULTIPLICATION SIGN WITH UNDERBAR -+ {"timesd", 0x02A30}, // MULTIPLICATION SIGN WITH DOT ABOVE -+ {"tint", 0x0222D}, // TRIPLE INTEGRAL -+ {"toea", 0x02928}, // NORTH EAST ARROW AND SOUTH EAST ARROW -+ {"top", 0x022A4}, // DOWN TACK -+ {"topbot", 0x02336}, // APL FUNCTIONAL SYMBOL I-BEAM -+ {"topcir", 0x02AF1}, // DOWN TACK WITH CIRCLE BELOW -+ {"Topf", 0x1D54B}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL T -+ {"topf", 0x1D565}, // MATHEMATICAL DOUBLE-STRUCK SMALL T -+ {"topfork", 0x02ADA}, // PITCHFORK WITH TEE TOP -+ {"tosa", 0x02929}, // SOUTH EAST ARROW AND SOUTH WEST ARROW -+ {"tprime", 0x02034}, // TRIPLE PRIME -+ {"trade", 0x02122}, // TRADE MARK SIGN -+ {"TRADE", 0x02122}, // TRADE MARK SIGN -+ {"triangle", 0x025B5}, // WHITE UP-POINTING SMALL TRIANGLE -+ {"triangledown", 0x025BF}, // WHITE DOWN-POINTING SMALL TRIANGLE -+ {"triangleleft", 0x025C3}, // WHITE LEFT-POINTING SMALL TRIANGLE -+ {"trianglelefteq", 0x022B4}, // NORMAL SUBGROUP OF OR EQUAL TO -+ {"triangleq", 0x0225C}, // DELTA EQUAL TO -+ {"triangleright", 0x025B9}, // WHITE RIGHT-POINTING SMALL TRIANGLE -+ {"trianglerighteq", 0x022B5}, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -+ {"tridot", 0x025EC}, // WHITE UP-POINTING TRIANGLE WITH DOT -+ {"trie", 0x0225C}, // DELTA EQUAL TO -+ {"triminus", 0x02A3A}, // MINUS SIGN IN TRIANGLE -+ {"TripleDot", 0x020DB}, // COMBINING THREE DOTS ABOVE -+ {"triplus", 0x02A39}, // PLUS SIGN IN TRIANGLE -+ {"trisb", 0x029CD}, // TRIANGLE WITH SERIFS AT BOTTOM -+ {"tritime", 0x02A3B}, // MULTIPLICATION SIGN IN TRIANGLE -+ {"trpezium", 0x023E2}, // WHITE TRAPEZIUM -+ {"Tscr", 0x1D4AF}, // MATHEMATICAL SCRIPT CAPITAL T -+ {"tscr", 0x1D4C9}, // MATHEMATICAL SCRIPT SMALL T -+ {"TScy", 0x00426}, // CYRILLIC CAPITAL LETTER TSE -+ {"tscy", 0x00446}, // CYRILLIC SMALL LETTER TSE -+ {"TSHcy", 0x0040B}, // CYRILLIC CAPITAL LETTER TSHE -+ {"tshcy", 0x0045B}, // CYRILLIC SMALL LETTER TSHE -+ {"Tstrok", 0x00166}, // LATIN CAPITAL LETTER T WITH STROKE -+ {"tstrok", 0x00167}, // LATIN SMALL LETTER T WITH STROKE -+ {"twixt", 0x0226C}, // BETWEEN -+ {"twoheadleftarrow", 0x0219E}, // LEFTWARDS TWO HEADED ARROW -+ {"twoheadrightarrow", 0x021A0}, // RIGHTWARDS TWO HEADED ARROW -+ {NULL, 0} - }; - - static NameId namesU[]={ -- "Uacgr", 0x0038E, // GREEK CAPITAL LETTER UPSILON WITH TONOS -- "uacgr", 0x003CD, // GREEK SMALL LETTER UPSILON WITH TONOS -- "Uacute", 0x000DA, // LATIN CAPITAL LETTER U WITH ACUTE -- "uacute", 0x000FA, // LATIN SMALL LETTER U WITH ACUTE -- "uarr", 0x02191, // UPWARDS ARROW -- "Uarr", 0x0219F, // UPWARDS TWO HEADED ARROW -- "uArr", 0x021D1, // UPWARDS DOUBLE ARROW -- "Uarrocir", 0x02949, // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE -- "Ubrcy", 0x0040E, // CYRILLIC CAPITAL LETTER SHORT U -- "ubrcy", 0x0045E, // CYRILLIC SMALL LETTER SHORT U -- "Ubreve", 0x0016C, // LATIN CAPITAL LETTER U WITH BREVE -- "ubreve", 0x0016D, // LATIN SMALL LETTER U WITH BREVE -- "Ucirc", 0x000DB, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX -- "ucirc", 0x000FB, // LATIN SMALL LETTER U WITH CIRCUMFLEX -- "Ucy", 0x00423, // CYRILLIC CAPITAL LETTER U -- "ucy", 0x00443, // CYRILLIC SMALL LETTER U -- "udarr", 0x021C5, // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW -- "Udblac", 0x00170, // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -- "udblac", 0x00171, // LATIN SMALL LETTER U WITH DOUBLE ACUTE -- "udhar", 0x0296E, // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -- "udiagr", 0x003B0, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -- "Udigr", 0x003AB, // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -- "udigr", 0x003CB, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA -- "ufisht", 0x0297E, // UP FISH TAIL -- "Ufr", 0x1D518, // MATHEMATICAL FRAKTUR CAPITAL U -- "ufr", 0x1D532, // MATHEMATICAL FRAKTUR SMALL U -- "Ugr", 0x003A5, // GREEK CAPITAL LETTER UPSILON -- "ugr", 0x003C5, // GREEK SMALL LETTER UPSILON -- "Ugrave", 0x000D9, // LATIN CAPITAL LETTER U WITH GRAVE -- "ugrave", 0x000F9, // LATIN SMALL LETTER U WITH GRAVE -- "uHar", 0x02963, // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -- "uharl", 0x021BF, // UPWARDS HARPOON WITH BARB LEFTWARDS -- "uharr", 0x021BE, // UPWARDS HARPOON WITH BARB RIGHTWARDS -- "uhblk", 0x02580, // UPPER HALF BLOCK -- "ulcorn", 0x0231C, // TOP LEFT CORNER -- "ulcorner", 0x0231C, // TOP LEFT CORNER -- "ulcrop", 0x0230F, // TOP LEFT CROP -- "ultri", 0x025F8, // UPPER LEFT TRIANGLE -- "Umacr", 0x0016A, // LATIN CAPITAL LETTER U WITH MACRON -- "umacr", 0x0016B, // LATIN SMALL LETTER U WITH MACRON -- "uml", 0x000A8, // DIAERESIS -- "UnderBar", 0x0005F, // LOW LINE -- "UnderBrace", 0x023DF, // BOTTOM CURLY BRACKET -- "UnderBracket", 0x023B5, // BOTTOM SQUARE BRACKET -- "UnderParenthesis", 0x023DD, // BOTTOM PARENTHESIS -- "Union", 0x022C3, // N-ARY UNION -- "UnionPlus", 0x0228E, // MULTISET UNION -- "Uogon", 0x00172, // LATIN CAPITAL LETTER U WITH OGONEK -- "uogon", 0x00173, // LATIN SMALL LETTER U WITH OGONEK -- "Uopf", 0x1D54C, // MATHEMATICAL DOUBLE-STRUCK CAPITAL U -- "uopf", 0x1D566, // MATHEMATICAL DOUBLE-STRUCK SMALL U -- "uparrow", 0x02191, // UPWARDS ARROW -- "UpArrow", 0x02191, // UPWARDS ARROW -- "Uparrow", 0x021D1, // UPWARDS DOUBLE ARROW -- "UpArrowBar", 0x02912, // UPWARDS ARROW TO BAR -- "UpArrowDownArrow", 0x021C5, // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW -- "updownarrow", 0x02195, // UP DOWN ARROW -- "UpDownArrow", 0x02195, // UP DOWN ARROW -- "Updownarrow", 0x021D5, // UP DOWN DOUBLE ARROW -- "UpEquilibrium", 0x0296E, // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -- "upharpoonleft", 0x021BF, // UPWARDS HARPOON WITH BARB LEFTWARDS -- "upharpoonright", 0x021BE, // UPWARDS HARPOON WITH BARB RIGHTWARDS -- "uplus", 0x0228E, // MULTISET UNION -- "UpperLeftArrow", 0x02196, // NORTH WEST ARROW -- "UpperRightArrow", 0x02197, // NORTH EAST ARROW -- "upsi", 0x003C5, // GREEK SMALL LETTER UPSILON -- "Upsi", 0x003D2, // GREEK UPSILON WITH HOOK SYMBOL -- "upsih", 0x003D2, // GREEK UPSILON WITH HOOK SYMBOL -- "Upsilon", 0x003A5, // GREEK CAPITAL LETTER UPSILON -- "upsilon", 0x003C5, // GREEK SMALL LETTER UPSILON -- "UpTee", 0x022A5, // UP TACK -- "UpTeeArrow", 0x021A5, // UPWARDS ARROW FROM BAR -- "upuparrows", 0x021C8, // UPWARDS PAIRED ARROWS -- "urcorn", 0x0231D, // TOP RIGHT CORNER -- "urcorner", 0x0231D, // TOP RIGHT CORNER -- "urcrop", 0x0230E, // TOP RIGHT CROP -- "Uring", 0x0016E, // LATIN CAPITAL LETTER U WITH RING ABOVE -- "uring", 0x0016F, // LATIN SMALL LETTER U WITH RING ABOVE -- "urtri", 0x025F9, // UPPER RIGHT TRIANGLE -- "Uscr", 0x1D4B0, // MATHEMATICAL SCRIPT CAPITAL U -- "uscr", 0x1D4CA, // MATHEMATICAL SCRIPT SMALL U -- "utdot", 0x022F0, // UP RIGHT DIAGONAL ELLIPSIS -- "Utilde", 0x00168, // LATIN CAPITAL LETTER U WITH TILDE -- "utilde", 0x00169, // LATIN SMALL LETTER U WITH TILDE -- "utri", 0x025B5, // WHITE UP-POINTING SMALL TRIANGLE -- "utrif", 0x025B4, // BLACK UP-POINTING SMALL TRIANGLE -- "uuarr", 0x021C8, // UPWARDS PAIRED ARROWS -- "Uuml", 0x000DC, // LATIN CAPITAL LETTER U WITH DIAERESIS -- "uuml", 0x000FC, // LATIN SMALL LETTER U WITH DIAERESIS -- "uwangle", 0x029A7, // OBLIQUE ANGLE OPENING DOWN -- NULL, 0 -+ {"Uacgr", 0x0038E}, // GREEK CAPITAL LETTER UPSILON WITH TONOS -+ {"uacgr", 0x003CD}, // GREEK SMALL LETTER UPSILON WITH TONOS -+ {"Uacute", 0x000DA}, // LATIN CAPITAL LETTER U WITH ACUTE -+ {"uacute", 0x000FA}, // LATIN SMALL LETTER U WITH ACUTE -+ {"uarr", 0x02191}, // UPWARDS ARROW -+ {"Uarr", 0x0219F}, // UPWARDS TWO HEADED ARROW -+ {"uArr", 0x021D1}, // UPWARDS DOUBLE ARROW -+ {"Uarrocir", 0x02949}, // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE -+ {"Ubrcy", 0x0040E}, // CYRILLIC CAPITAL LETTER SHORT U -+ {"ubrcy", 0x0045E}, // CYRILLIC SMALL LETTER SHORT U -+ {"Ubreve", 0x0016C}, // LATIN CAPITAL LETTER U WITH BREVE -+ {"ubreve", 0x0016D}, // LATIN SMALL LETTER U WITH BREVE -+ {"Ucirc", 0x000DB}, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX -+ {"ucirc", 0x000FB}, // LATIN SMALL LETTER U WITH CIRCUMFLEX -+ {"Ucy", 0x00423}, // CYRILLIC CAPITAL LETTER U -+ {"ucy", 0x00443}, // CYRILLIC SMALL LETTER U -+ {"udarr", 0x021C5}, // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW -+ {"Udblac", 0x00170}, // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -+ {"udblac", 0x00171}, // LATIN SMALL LETTER U WITH DOUBLE ACUTE -+ {"udhar", 0x0296E}, // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -+ {"udiagr", 0x003B0}, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -+ {"Udigr", 0x003AB}, // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -+ {"udigr", 0x003CB}, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA -+ {"ufisht", 0x0297E}, // UP FISH TAIL -+ {"Ufr", 0x1D518}, // MATHEMATICAL FRAKTUR CAPITAL U -+ {"ufr", 0x1D532}, // MATHEMATICAL FRAKTUR SMALL U -+ {"Ugr", 0x003A5}, // GREEK CAPITAL LETTER UPSILON -+ {"ugr", 0x003C5}, // GREEK SMALL LETTER UPSILON -+ {"Ugrave", 0x000D9}, // LATIN CAPITAL LETTER U WITH GRAVE -+ {"ugrave", 0x000F9}, // LATIN SMALL LETTER U WITH GRAVE -+ {"uHar", 0x02963}, // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -+ {"uharl", 0x021BF}, // UPWARDS HARPOON WITH BARB LEFTWARDS -+ {"uharr", 0x021BE}, // UPWARDS HARPOON WITH BARB RIGHTWARDS -+ {"uhblk", 0x02580}, // UPPER HALF BLOCK -+ {"ulcorn", 0x0231C}, // TOP LEFT CORNER -+ {"ulcorner", 0x0231C}, // TOP LEFT CORNER -+ {"ulcrop", 0x0230F}, // TOP LEFT CROP -+ {"ultri", 0x025F8}, // UPPER LEFT TRIANGLE -+ {"Umacr", 0x0016A}, // LATIN CAPITAL LETTER U WITH MACRON -+ {"umacr", 0x0016B}, // LATIN SMALL LETTER U WITH MACRON -+ {"uml", 0x000A8}, // DIAERESIS -+ {"UnderBar", 0x0005F}, // LOW LINE -+ {"UnderBrace", 0x023DF}, // BOTTOM CURLY BRACKET -+ {"UnderBracket", 0x023B5}, // BOTTOM SQUARE BRACKET -+ {"UnderParenthesis", 0x023DD}, // BOTTOM PARENTHESIS -+ {"Union", 0x022C3}, // N-ARY UNION -+ {"UnionPlus", 0x0228E}, // MULTISET UNION -+ {"Uogon", 0x00172}, // LATIN CAPITAL LETTER U WITH OGONEK -+ {"uogon", 0x00173}, // LATIN SMALL LETTER U WITH OGONEK -+ {"Uopf", 0x1D54C}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL U -+ {"uopf", 0x1D566}, // MATHEMATICAL DOUBLE-STRUCK SMALL U -+ {"uparrow", 0x02191}, // UPWARDS ARROW -+ {"UpArrow", 0x02191}, // UPWARDS ARROW -+ {"Uparrow", 0x021D1}, // UPWARDS DOUBLE ARROW -+ {"UpArrowBar", 0x02912}, // UPWARDS ARROW TO BAR -+ {"UpArrowDownArrow", 0x021C5}, // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW -+ {"updownarrow", 0x02195}, // UP DOWN ARROW -+ {"UpDownArrow", 0x02195}, // UP DOWN ARROW -+ {"Updownarrow", 0x021D5}, // UP DOWN DOUBLE ARROW -+ {"UpEquilibrium", 0x0296E}, // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -+ {"upharpoonleft", 0x021BF}, // UPWARDS HARPOON WITH BARB LEFTWARDS -+ {"upharpoonright", 0x021BE}, // UPWARDS HARPOON WITH BARB RIGHTWARDS -+ {"uplus", 0x0228E}, // MULTISET UNION -+ {"UpperLeftArrow", 0x02196}, // NORTH WEST ARROW -+ {"UpperRightArrow", 0x02197}, // NORTH EAST ARROW -+ {"upsi", 0x003C5}, // GREEK SMALL LETTER UPSILON -+ {"Upsi", 0x003D2}, // GREEK UPSILON WITH HOOK SYMBOL -+ {"upsih", 0x003D2}, // GREEK UPSILON WITH HOOK SYMBOL -+ {"Upsilon", 0x003A5}, // GREEK CAPITAL LETTER UPSILON -+ {"upsilon", 0x003C5}, // GREEK SMALL LETTER UPSILON -+ {"UpTee", 0x022A5}, // UP TACK -+ {"UpTeeArrow", 0x021A5}, // UPWARDS ARROW FROM BAR -+ {"upuparrows", 0x021C8}, // UPWARDS PAIRED ARROWS -+ {"urcorn", 0x0231D}, // TOP RIGHT CORNER -+ {"urcorner", 0x0231D}, // TOP RIGHT CORNER -+ {"urcrop", 0x0230E}, // TOP RIGHT CROP -+ {"Uring", 0x0016E}, // LATIN CAPITAL LETTER U WITH RING ABOVE -+ {"uring", 0x0016F}, // LATIN SMALL LETTER U WITH RING ABOVE -+ {"urtri", 0x025F9}, // UPPER RIGHT TRIANGLE -+ {"Uscr", 0x1D4B0}, // MATHEMATICAL SCRIPT CAPITAL U -+ {"uscr", 0x1D4CA}, // MATHEMATICAL SCRIPT SMALL U -+ {"utdot", 0x022F0}, // UP RIGHT DIAGONAL ELLIPSIS -+ {"Utilde", 0x00168}, // LATIN CAPITAL LETTER U WITH TILDE -+ {"utilde", 0x00169}, // LATIN SMALL LETTER U WITH TILDE -+ {"utri", 0x025B5}, // WHITE UP-POINTING SMALL TRIANGLE -+ {"utrif", 0x025B4}, // BLACK UP-POINTING SMALL TRIANGLE -+ {"uuarr", 0x021C8}, // UPWARDS PAIRED ARROWS -+ {"Uuml", 0x000DC}, // LATIN CAPITAL LETTER U WITH DIAERESIS -+ {"uuml", 0x000FC}, // LATIN SMALL LETTER U WITH DIAERESIS -+ {"uwangle", 0x029A7}, // OBLIQUE ANGLE OPENING DOWN -+ {NULL, 0} - }; - - static NameId namesV[]={ -- "vangrt", 0x0299C, // RIGHT ANGLE VARIANT WITH SQUARE -- "varepsilon", 0x003F5, // GREEK LUNATE EPSILON SYMBOL -- "varkappa", 0x003F0, // GREEK KAPPA SYMBOL -- "varnothing", 0x02205, // EMPTY SET -- "varphi", 0x003D5, // GREEK PHI SYMBOL -- "varpi", 0x003D6, // GREEK PI SYMBOL -- "varpropto", 0x0221D, // PROPORTIONAL TO -- "varr", 0x02195, // UP DOWN ARROW -- "vArr", 0x021D5, // UP DOWN DOUBLE ARROW -- "varrho", 0x003F1, // GREEK RHO SYMBOL -- "varsigma", 0x003C2, // GREEK SMALL LETTER FINAL SIGMA --// "varsubsetneq", 0x0228A;0x0FE00, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members --// "varsubsetneqq", 0x02ACB;0x0FE00, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members --// "varsupsetneq", 0x0228B;0x0FE00, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members --// "varsupsetneqq", 0x02ACC;0x0FE00, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -- "vartheta", 0x003D1, // GREEK THETA SYMBOL -- "vartriangleleft", 0x022B2, // NORMAL SUBGROUP OF -- "vartriangleright", 0x022B3, // CONTAINS AS NORMAL SUBGROUP -- "vBar", 0x02AE8, // SHORT UP TACK WITH UNDERBAR -- "Vbar", 0x02AEB, // DOUBLE UP TACK -- "vBarv", 0x02AE9, // SHORT UP TACK ABOVE SHORT DOWN TACK -- "Vcy", 0x00412, // CYRILLIC CAPITAL LETTER VE -- "vcy", 0x00432, // CYRILLIC SMALL LETTER VE -- "vdash", 0x022A2, // RIGHT TACK -- "vDash", 0x022A8, // TRUE -- "Vdash", 0x022A9, // FORCES -- "VDash", 0x022AB, // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE -- "Vdashl", 0x02AE6, // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL -- "vee", 0x02228, // LOGICAL OR -- "Vee", 0x022C1, // N-ARY LOGICAL OR -- "veebar", 0x022BB, // XOR -- "veeeq", 0x0225A, // EQUIANGULAR TO -- "vellip", 0x022EE, // VERTICAL ELLIPSIS -- "verbar", 0x0007C, // VERTICAL LINE -- "Verbar", 0x02016, // DOUBLE VERTICAL LINE -- "vert", 0x0007C, // VERTICAL LINE -- "Vert", 0x02016, // DOUBLE VERTICAL LINE -- "VerticalBar", 0x02223, // DIVIDES -- "VerticalLine", 0x0007C, // VERTICAL LINE -- "VerticalSeparator", 0x02758, // LIGHT VERTICAL BAR -- "VerticalTilde", 0x02240, // WREATH PRODUCT -- "VeryThinSpace", 0x0200A, // HAIR SPACE -- "Vfr", 0x1D519, // MATHEMATICAL FRAKTUR CAPITAL V -- "vfr", 0x1D533, // MATHEMATICAL FRAKTUR SMALL V -- "vltri", 0x022B2, // NORMAL SUBGROUP OF --// "vnsub", 0x02282;0x020D2, // SUBSET OF with vertical line --// "vnsup", 0x02283;0x020D2, // SUPERSET OF with vertical line -- "Vopf", 0x1D54D, // MATHEMATICAL DOUBLE-STRUCK CAPITAL V -- "vopf", 0x1D567, // MATHEMATICAL DOUBLE-STRUCK SMALL V -- "vprop", 0x0221D, // PROPORTIONAL TO -- "vrtri", 0x022B3, // CONTAINS AS NORMAL SUBGROUP -- "Vscr", 0x1D4B1, // MATHEMATICAL SCRIPT CAPITAL V -- "vscr", 0x1D4CB, // MATHEMATICAL SCRIPT SMALL V --// "vsubne", 0x0228A;0x0FE00, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members --// "vsubnE", 0x02ACB;0x0FE00, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members --// "vsupne", 0x0228B;0x0FE00, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members --// "vsupnE", 0x02ACC;0x0FE00, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -- "Vvdash", 0x022AA, // TRIPLE VERTICAL BAR RIGHT TURNSTILE -- "vzigzag", 0x0299A, // VERTICAL ZIGZAG LINE -- NULL, 0 -+ {"vangrt", 0x0299C}, // RIGHT ANGLE VARIANT WITH SQUARE -+ {"varepsilon", 0x003F5}, // GREEK LUNATE EPSILON SYMBOL -+ {"varkappa", 0x003F0}, // GREEK KAPPA SYMBOL -+ {"varnothing", 0x02205}, // EMPTY SET -+ {"varphi", 0x003D5}, // GREEK PHI SYMBOL -+ {"varpi", 0x003D6}, // GREEK PI SYMBOL -+ {"varpropto", 0x0221D}, // PROPORTIONAL TO -+ {"varr", 0x02195}, // UP DOWN ARROW -+ {"vArr", 0x021D5}, // UP DOWN DOUBLE ARROW -+ {"varrho", 0x003F1}, // GREEK RHO SYMBOL -+ {"varsigma", 0x003C2}, // GREEK SMALL LETTER FINAL SIGMA -+// "varsubsetneq", 0x0228A;0x0FE00}, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -+// "varsubsetneqq", 0x02ACB;0x0FE00}, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -+// "varsupsetneq", 0x0228B;0x0FE00}, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -+// "varsupsetneqq", 0x02ACC;0x0FE00}, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -+ {"vartheta", 0x003D1}, // GREEK THETA SYMBOL -+ {"vartriangleleft", 0x022B2}, // NORMAL SUBGROUP OF -+ {"vartriangleright", 0x022B3}, // CONTAINS AS NORMAL SUBGROUP -+ {"vBar", 0x02AE8}, // SHORT UP TACK WITH UNDERBAR -+ {"Vbar", 0x02AEB}, // DOUBLE UP TACK -+ {"vBarv", 0x02AE9}, // SHORT UP TACK ABOVE SHORT DOWN TACK -+ {"Vcy", 0x00412}, // CYRILLIC CAPITAL LETTER VE -+ {"vcy", 0x00432}, // CYRILLIC SMALL LETTER VE -+ {"vdash", 0x022A2}, // RIGHT TACK -+ {"vDash", 0x022A8}, // TRUE -+ {"Vdash", 0x022A9}, // FORCES -+ {"VDash", 0x022AB}, // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE -+ {"Vdashl", 0x02AE6}, // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL -+ {"vee", 0x02228}, // LOGICAL OR -+ {"Vee", 0x022C1}, // N-ARY LOGICAL OR -+ {"veebar", 0x022BB}, // XOR -+ {"veeeq", 0x0225A}, // EQUIANGULAR TO -+ {"vellip", 0x022EE}, // VERTICAL ELLIPSIS -+ {"verbar", 0x0007C}, // VERTICAL LINE -+ {"Verbar", 0x02016}, // DOUBLE VERTICAL LINE -+ {"vert", 0x0007C}, // VERTICAL LINE -+ {"Vert", 0x02016}, // DOUBLE VERTICAL LINE -+ {"VerticalBar", 0x02223}, // DIVIDES -+ {"VerticalLine", 0x0007C}, // VERTICAL LINE -+ {"VerticalSeparator", 0x02758}, // LIGHT VERTICAL BAR -+ {"VerticalTilde", 0x02240}, // WREATH PRODUCT -+ {"VeryThinSpace", 0x0200A}, // HAIR SPACE -+ {"Vfr", 0x1D519}, // MATHEMATICAL FRAKTUR CAPITAL V -+ {"vfr", 0x1D533}, // MATHEMATICAL FRAKTUR SMALL V -+ {"vltri", 0x022B2}, // NORMAL SUBGROUP OF -+// "vnsub", 0x02282;0x020D2}, // SUBSET OF with vertical line -+// "vnsup", 0x02283;0x020D2}, // SUPERSET OF with vertical line -+ {"Vopf", 0x1D54D}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL V -+ {"vopf", 0x1D567}, // MATHEMATICAL DOUBLE-STRUCK SMALL V -+ {"vprop", 0x0221D}, // PROPORTIONAL TO -+ {"vrtri", 0x022B3}, // CONTAINS AS NORMAL SUBGROUP -+ {"Vscr", 0x1D4B1}, // MATHEMATICAL SCRIPT CAPITAL V -+ {"vscr", 0x1D4CB}, // MATHEMATICAL SCRIPT SMALL V -+// "vsubne", 0x0228A;0x0FE00}, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -+// "vsubnE", 0x02ACB;0x0FE00}, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -+// "vsupne", 0x0228B;0x0FE00}, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -+// "vsupnE", 0x02ACC;0x0FE00}, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -+ {"Vvdash", 0x022AA}, // TRIPLE VERTICAL BAR RIGHT TURNSTILE -+ {"vzigzag", 0x0299A}, // VERTICAL ZIGZAG LINE -+ {NULL, 0} - }; - - static NameId namesW[]={ -- "Wcirc", 0x00174, // LATIN CAPITAL LETTER W WITH CIRCUMFLEX -- "wcirc", 0x00175, // LATIN SMALL LETTER W WITH CIRCUMFLEX -- "wedbar", 0x02A5F, // LOGICAL AND WITH UNDERBAR -- "wedge", 0x02227, // LOGICAL AND -- "Wedge", 0x022C0, // N-ARY LOGICAL AND -- "wedgeq", 0x02259, // ESTIMATES -- "weierp", 0x02118, // SCRIPT CAPITAL P -- "Wfr", 0x1D51A, // MATHEMATICAL FRAKTUR CAPITAL W -- "wfr", 0x1D534, // MATHEMATICAL FRAKTUR SMALL W -- "Wopf", 0x1D54E, // MATHEMATICAL DOUBLE-STRUCK CAPITAL W -- "wopf", 0x1D568, // MATHEMATICAL DOUBLE-STRUCK SMALL W -- "wp", 0x02118, // SCRIPT CAPITAL P -- "wr", 0x02240, // WREATH PRODUCT -- "wreath", 0x02240, // WREATH PRODUCT -- "Wscr", 0x1D4B2, // MATHEMATICAL SCRIPT CAPITAL W -- "wscr", 0x1D4CC, // MATHEMATICAL SCRIPT SMALL W -- NULL, 0 -+ {"Wcirc", 0x00174}, // LATIN CAPITAL LETTER W WITH CIRCUMFLEX -+ {"wcirc", 0x00175}, // LATIN SMALL LETTER W WITH CIRCUMFLEX -+ {"wedbar", 0x02A5F}, // LOGICAL AND WITH UNDERBAR -+ {"wedge", 0x02227}, // LOGICAL AND -+ {"Wedge", 0x022C0}, // N-ARY LOGICAL AND -+ {"wedgeq", 0x02259}, // ESTIMATES -+ {"weierp", 0x02118}, // SCRIPT CAPITAL P -+ {"Wfr", 0x1D51A}, // MATHEMATICAL FRAKTUR CAPITAL W -+ {"wfr", 0x1D534}, // MATHEMATICAL FRAKTUR SMALL W -+ {"Wopf", 0x1D54E}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL W -+ {"wopf", 0x1D568}, // MATHEMATICAL DOUBLE-STRUCK SMALL W -+ {"wp", 0x02118}, // SCRIPT CAPITAL P -+ {"wr", 0x02240}, // WREATH PRODUCT -+ {"wreath", 0x02240}, // WREATH PRODUCT -+ {"Wscr", 0x1D4B2}, // MATHEMATICAL SCRIPT CAPITAL W -+ {"wscr", 0x1D4CC}, // MATHEMATICAL SCRIPT SMALL W -+ {NULL, 0} - }; - - static NameId namesX[]={ -- "xcap", 0x022C2, // N-ARY INTERSECTION -- "xcirc", 0x025EF, // LARGE CIRCLE -- "xcup", 0x022C3, // N-ARY UNION -- "xdtri", 0x025BD, // WHITE DOWN-POINTING TRIANGLE -- "Xfr", 0x1D51B, // MATHEMATICAL FRAKTUR CAPITAL X -- "xfr", 0x1D535, // MATHEMATICAL FRAKTUR SMALL X -- "Xgr", 0x0039E, // GREEK CAPITAL LETTER XI -- "xgr", 0x003BE, // GREEK SMALL LETTER XI -- "xharr", 0x027F7, // LONG LEFT RIGHT ARROW -- "xhArr", 0x027FA, // LONG LEFT RIGHT DOUBLE ARROW -- "Xi", 0x0039E, // GREEK CAPITAL LETTER XI -- "xi", 0x003BE, // GREEK SMALL LETTER XI -- "xlarr", 0x027F5, // LONG LEFTWARDS ARROW -- "xlArr", 0x027F8, // LONG LEFTWARDS DOUBLE ARROW -- "xmap", 0x027FC, // LONG RIGHTWARDS ARROW FROM BAR -- "xnis", 0x022FB, // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -- "xodot", 0x02A00, // N-ARY CIRCLED DOT OPERATOR -- "Xopf", 0x1D54F, // MATHEMATICAL DOUBLE-STRUCK CAPITAL X -- "xopf", 0x1D569, // MATHEMATICAL DOUBLE-STRUCK SMALL X -- "xoplus", 0x02A01, // N-ARY CIRCLED PLUS OPERATOR -- "xotime", 0x02A02, // N-ARY CIRCLED TIMES OPERATOR -- "xrarr", 0x027F6, // LONG RIGHTWARDS ARROW -- "xrArr", 0x027F9, // LONG RIGHTWARDS DOUBLE ARROW -- "Xscr", 0x1D4B3, // MATHEMATICAL SCRIPT CAPITAL X -- "xscr", 0x1D4CD, // MATHEMATICAL SCRIPT SMALL X -- "xsqcup", 0x02A06, // N-ARY SQUARE UNION OPERATOR -- "xuplus", 0x02A04, // N-ARY UNION OPERATOR WITH PLUS -- "xutri", 0x025B3, // WHITE UP-POINTING TRIANGLE -- "xvee", 0x022C1, // N-ARY LOGICAL OR -- "xwedge", 0x022C0, // N-ARY LOGICAL AND -- NULL, 0 -+ {"xcap", 0x022C2}, // N-ARY INTERSECTION -+ {"xcirc", 0x025EF}, // LARGE CIRCLE -+ {"xcup", 0x022C3}, // N-ARY UNION -+ {"xdtri", 0x025BD}, // WHITE DOWN-POINTING TRIANGLE -+ {"Xfr", 0x1D51B}, // MATHEMATICAL FRAKTUR CAPITAL X -+ {"xfr", 0x1D535}, // MATHEMATICAL FRAKTUR SMALL X -+ {"Xgr", 0x0039E}, // GREEK CAPITAL LETTER XI -+ {"xgr", 0x003BE}, // GREEK SMALL LETTER XI -+ {"xharr", 0x027F7}, // LONG LEFT RIGHT ARROW -+ {"xhArr", 0x027FA}, // LONG LEFT RIGHT DOUBLE ARROW -+ {"Xi", 0x0039E}, // GREEK CAPITAL LETTER XI -+ {"xi", 0x003BE}, // GREEK SMALL LETTER XI -+ {"xlarr", 0x027F5}, // LONG LEFTWARDS ARROW -+ {"xlArr", 0x027F8}, // LONG LEFTWARDS DOUBLE ARROW -+ {"xmap", 0x027FC}, // LONG RIGHTWARDS ARROW FROM BAR -+ {"xnis", 0x022FB}, // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -+ {"xodot", 0x02A00}, // N-ARY CIRCLED DOT OPERATOR -+ {"Xopf", 0x1D54F}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL X -+ {"xopf", 0x1D569}, // MATHEMATICAL DOUBLE-STRUCK SMALL X -+ {"xoplus", 0x02A01}, // N-ARY CIRCLED PLUS OPERATOR -+ {"xotime", 0x02A02}, // N-ARY CIRCLED TIMES OPERATOR -+ {"xrarr", 0x027F6}, // LONG RIGHTWARDS ARROW -+ {"xrArr", 0x027F9}, // LONG RIGHTWARDS DOUBLE ARROW -+ {"Xscr", 0x1D4B3}, // MATHEMATICAL SCRIPT CAPITAL X -+ {"xscr", 0x1D4CD}, // MATHEMATICAL SCRIPT SMALL X -+ {"xsqcup", 0x02A06}, // N-ARY SQUARE UNION OPERATOR -+ {"xuplus", 0x02A04}, // N-ARY UNION OPERATOR WITH PLUS -+ {"xutri", 0x025B3}, // WHITE UP-POINTING TRIANGLE -+ {"xvee", 0x022C1}, // N-ARY LOGICAL OR -+ {"xwedge", 0x022C0}, // N-ARY LOGICAL AND -+ {NULL, 0} - }; - - static NameId namesY[]={ -- "Yacute", 0x000DD, // LATIN CAPITAL LETTER Y WITH ACUTE -- "yacute", 0x000FD, // LATIN SMALL LETTER Y WITH ACUTE -- "YAcy", 0x0042F, // CYRILLIC CAPITAL LETTER YA -- "yacy", 0x0044F, // CYRILLIC SMALL LETTER YA -- "Ycirc", 0x00176, // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -- "ycirc", 0x00177, // LATIN SMALL LETTER Y WITH CIRCUMFLEX -- "Ycy", 0x0042B, // CYRILLIC CAPITAL LETTER YERU -- "ycy", 0x0044B, // CYRILLIC SMALL LETTER YERU -- "yen", 0x000A5, // YEN SIGN -- "Yfr", 0x1D51C, // MATHEMATICAL FRAKTUR CAPITAL Y -- "yfr", 0x1D536, // MATHEMATICAL FRAKTUR SMALL Y -- "YIcy", 0x00407, // CYRILLIC CAPITAL LETTER YI -- "yicy", 0x00457, // CYRILLIC SMALL LETTER YI -- "Yopf", 0x1D550, // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y -- "yopf", 0x1D56A, // MATHEMATICAL DOUBLE-STRUCK SMALL Y -- "Yscr", 0x1D4B4, // MATHEMATICAL SCRIPT CAPITAL Y -- "yscr", 0x1D4CE, // MATHEMATICAL SCRIPT SMALL Y -- "YUcy", 0x0042E, // CYRILLIC CAPITAL LETTER YU -- "yucy", 0x0044E, // CYRILLIC SMALL LETTER YU -- "yuml", 0x000FF, // LATIN SMALL LETTER Y WITH DIAERESIS -- "Yuml", 0x00178, // LATIN CAPITAL LETTER Y WITH DIAERESIS -- NULL, 0 -+ {"Yacute", 0x000DD}, // LATIN CAPITAL LETTER Y WITH ACUTE -+ {"yacute", 0x000FD}, // LATIN SMALL LETTER Y WITH ACUTE -+ {"YAcy", 0x0042F}, // CYRILLIC CAPITAL LETTER YA -+ {"yacy", 0x0044F}, // CYRILLIC SMALL LETTER YA -+ {"Ycirc", 0x00176}, // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -+ {"ycirc", 0x00177}, // LATIN SMALL LETTER Y WITH CIRCUMFLEX -+ {"Ycy", 0x0042B}, // CYRILLIC CAPITAL LETTER YERU -+ {"ycy", 0x0044B}, // CYRILLIC SMALL LETTER YERU -+ {"yen", 0x000A5}, // YEN SIGN -+ {"Yfr", 0x1D51C}, // MATHEMATICAL FRAKTUR CAPITAL Y -+ {"yfr", 0x1D536}, // MATHEMATICAL FRAKTUR SMALL Y -+ {"YIcy", 0x00407}, // CYRILLIC CAPITAL LETTER YI -+ {"yicy", 0x00457}, // CYRILLIC SMALL LETTER YI -+ {"Yopf", 0x1D550}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y -+ {"yopf", 0x1D56A}, // MATHEMATICAL DOUBLE-STRUCK SMALL Y -+ {"Yscr", 0x1D4B4}, // MATHEMATICAL SCRIPT CAPITAL Y -+ {"yscr", 0x1D4CE}, // MATHEMATICAL SCRIPT SMALL Y -+ {"YUcy", 0x0042E}, // CYRILLIC CAPITAL LETTER YU -+ {"yucy", 0x0044E}, // CYRILLIC SMALL LETTER YU -+ {"yuml", 0x000FF}, // LATIN SMALL LETTER Y WITH DIAERESIS -+ {"Yuml", 0x00178}, // LATIN CAPITAL LETTER Y WITH DIAERESIS -+ {NULL, 0} - }; - - static NameId namesZ[]={ -- "Zacute", 0x00179, // LATIN CAPITAL LETTER Z WITH ACUTE -- "zacute", 0x0017A, // LATIN SMALL LETTER Z WITH ACUTE -- "Zcaron", 0x0017D, // LATIN CAPITAL LETTER Z WITH CARON -- "zcaron", 0x0017E, // LATIN SMALL LETTER Z WITH CARON -- "Zcy", 0x00417, // CYRILLIC CAPITAL LETTER ZE -- "zcy", 0x00437, // CYRILLIC SMALL LETTER ZE -- "Zdot", 0x0017B, // LATIN CAPITAL LETTER Z WITH DOT ABOVE -- "zdot", 0x0017C, // LATIN SMALL LETTER Z WITH DOT ABOVE -- "zeetrf", 0x02128, // BLACK-LETTER CAPITAL Z -- "ZeroWidthSpace", 0x0200B, // ZERO WIDTH SPACE -- "Zeta", 0x00396, // GREEK CAPITAL LETTER ZETA -- "zeta", 0x003B6, // GREEK SMALL LETTER ZETA -- "Zfr", 0x02128, // BLACK-LETTER CAPITAL Z -- "zfr", 0x1D537, // MATHEMATICAL FRAKTUR SMALL Z -- "Zgr", 0x00396, // GREEK CAPITAL LETTER ZETA -- "zgr", 0x003B6, // GREEK SMALL LETTER ZETA -- "ZHcy", 0x00416, // CYRILLIC CAPITAL LETTER ZHE -- "zhcy", 0x00436, // CYRILLIC SMALL LETTER ZHE -- "zigrarr", 0x021DD, // RIGHTWARDS SQUIGGLE ARROW -- "Zopf", 0x02124, // DOUBLE-STRUCK CAPITAL Z -- "zopf", 0x1D56B, // MATHEMATICAL DOUBLE-STRUCK SMALL Z -- "Zscr", 0x1D4B5, // MATHEMATICAL SCRIPT CAPITAL Z -- "zscr", 0x1D4CF, // MATHEMATICAL SCRIPT SMALL Z -- "zwj", 0x0200D, // ZERO WIDTH JOINER -- "zwnj", 0x0200C, // ZERO WIDTH NON-JOINER -- NULL, 0 -+ {"Zacute", 0x00179}, // LATIN CAPITAL LETTER Z WITH ACUTE -+ {"zacute", 0x0017A}, // LATIN SMALL LETTER Z WITH ACUTE -+ {"Zcaron", 0x0017D}, // LATIN CAPITAL LETTER Z WITH CARON -+ {"zcaron", 0x0017E}, // LATIN SMALL LETTER Z WITH CARON -+ {"Zcy", 0x00417}, // CYRILLIC CAPITAL LETTER ZE -+ {"zcy", 0x00437}, // CYRILLIC SMALL LETTER ZE -+ {"Zdot", 0x0017B}, // LATIN CAPITAL LETTER Z WITH DOT ABOVE -+ {"zdot", 0x0017C}, // LATIN SMALL LETTER Z WITH DOT ABOVE -+ {"zeetrf", 0x02128}, // BLACK-LETTER CAPITAL Z -+ {"ZeroWidthSpace", 0x0200B}, // ZERO WIDTH SPACE -+ {"Zeta", 0x00396}, // GREEK CAPITAL LETTER ZETA -+ {"zeta", 0x003B6}, // GREEK SMALL LETTER ZETA -+ {"Zfr", 0x02128}, // BLACK-LETTER CAPITAL Z -+ {"zfr", 0x1D537}, // MATHEMATICAL FRAKTUR SMALL Z -+ {"Zgr", 0x00396}, // GREEK CAPITAL LETTER ZETA -+ {"zgr", 0x003B6}, // GREEK SMALL LETTER ZETA -+ {"ZHcy", 0x00416}, // CYRILLIC CAPITAL LETTER ZHE -+ {"zhcy", 0x00436}, // CYRILLIC SMALL LETTER ZHE -+ {"zigrarr", 0x021DD}, // RIGHTWARDS SQUIGGLE ARROW -+ {"Zopf", 0x02124}, // DOUBLE-STRUCK CAPITAL Z -+ {"zopf", 0x1D56B}, // MATHEMATICAL DOUBLE-STRUCK SMALL Z -+ {"Zscr", 0x1D4B5}, // MATHEMATICAL SCRIPT CAPITAL Z -+ {"zscr", 0x1D4CF}, // MATHEMATICAL SCRIPT SMALL Z -+ {"zwj", 0x0200D}, // ZERO WIDTH JOINER -+ {"zwnj", 0x0200C}, // ZERO WIDTH NON-JOINER -+ {NULL, 0} - }; - - // @todo@ order namesTable and names? by frequency -@@ -2372,7 +2374,7 @@ static NameId* namesTable[] = { - namesS, namesT, namesU, namesV, namesW, namesX, namesY, namesZ, NULL - }; - --int HtmlNamedEntity(unsigned char *p, size_t length) -+int HtmlNamedEntity(utf8_t *p, size_t length) - { - int tableIndex = tolower(*p) - 'a'; - if (tableIndex >= 0 && tableIndex < 26) ---- a/src/gcc/d/dfrontend/enum.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/enum.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - --// Copyright (c) 1999-2011 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -18,12 +18,14 @@ - #include "expression.h" - #include "module.h" - #include "declaration.h" -+#include "init.h" - - /********************************* EnumDeclaration ****************************/ - - EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype) - : ScopeDsymbol(id) - { -+ //printf("EnumDeclaration() %s\n", toChars()); - this->loc = loc; - type = new TypeEnum(this); - this->memtype = memtype; -@@ -31,9 +33,10 @@ EnumDeclaration::EnumDeclaration(Loc loc - minval = NULL; - defaultval = NULL; - sinit = NULL; -- isdeprecated = 0; -- isdone = 0; -- objFileDone = 0; -+ isdeprecated = false; -+ protection = PROTundefined; -+ parent = NULL; -+ added = false; - } - - Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s) -@@ -50,64 +53,73 @@ Dsymbol *EnumDeclaration::syntaxCopy(Dsy - else - ed = new EnumDeclaration(loc, ident, t); - ScopeDsymbol::syntaxCopy(ed); -+ if (isAnonymous()) -+ { -+ for (size_t i = 0; i < members->dim; i++) -+ { -+ EnumMember *em = (*members)[i]->isEnumMember(); -+ em->ed = ed; -+ } -+ } - return ed; - } - - void EnumDeclaration::setScope(Scope *sc) - { -- if (isdone) -+ if (semanticRun > PASSinit) - return; - ScopeDsymbol::setScope(sc); - } - --void EnumDeclaration::semantic0(Scope *sc) -+int EnumDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) - { -- /* This function is a hack to get around a significant problem. -- * The members of anonymous enums, like: -- * enum { A, B, C } -- * don't get installed into the symbol table until after they are -- * semantically analyzed, yet they're supposed to go into the enclosing -- * scope's table. Hence, when forward referenced, they come out as -- * 'undefined'. The real fix is to add them in at addSymbol() time. -- * But to get code to compile, we'll just do this quick hack at the moment -- * to compile it if it doesn't depend on anything else. -- */ -- -- if (isdone || !scope) -- return; -- if (!isAnonymous() || memtype) -- return; -+#if 0 -+ printf("EnumDeclaration::addMember() %s\n", toChars()); - for (size_t i = 0; i < members->dim; i++) - { - EnumMember *em = (*members)[i]->isEnumMember(); -- if (em && (em->type || em->value)) -- return; -+ printf(" member %s\n", em->toChars()); - } -+#endif - -- // Can do it -- semantic(sc); -+ /* Anonymous enum members get added to enclosing scope. -+ */ -+ ScopeDsymbol *scopesym = isAnonymous() ? sd : this; -+ -+ if (!isAnonymous()) -+ { -+ ScopeDsymbol::addMember(sc, sd, memnum); -+ -+ if (!symtab) -+ symtab = new DsymbolTable(); -+ } -+ -+ if (members) -+ { -+ for (size_t i = 0; i < members->dim; i++) -+ { -+ EnumMember *em = (*members)[i]->isEnumMember(); -+ em->ed = this; -+ //printf("add %s to scope %s\n", em->toChars(), scopesym->toChars()); -+ em->addMember(sc, scopesym, 1); -+ } -+ } -+ added = true; -+ return 1; - } - -+ - void EnumDeclaration::semantic(Scope *sc) - { -- Type *t; -- Scope *sce; -- - //printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc->scopesym, sc->scopesym->toChars(), toChars()); -- //printf("EnumDeclaration::semantic() %s\n", toChars()); -- if (!members) // enum ident; -+ //printf("EnumDeclaration::semantic() %p %s\n", this, toChars()); -+ if (!members && !memtype) // enum ident; - return; - -- if (!memtype && !isAnonymous()) -- { // Set memtype if we can to reduce fwd reference errors -- memtype = Type::tint32; // case 1) enum ident { ... } -- } -+ if (semanticRun > PASSinit) -+ return; // semantic() already completed - -- if (symtab) // if already done -- { if (isdone || !scope) -- return; // semantic() already completed -- } -- else -+ if (!symtab) - symtab = new DsymbolTable(); - - Scope *scx = NULL; -@@ -120,7 +132,7 @@ void EnumDeclaration::semantic(Scope *sc - unsigned dprogress_save = Module::dprogress; - - if (sc->stc & STCdeprecated) -- isdeprecated = 1; -+ isdeprecated = true; - userAttributes = sc->userAttributes; - - parent = sc->parent; -@@ -131,8 +143,12 @@ void EnumDeclaration::semantic(Scope *sc - * 2. enum : memtype { ... } - * 3. enum ident { ... } - * 4. enum ident : memtype { ... } -+ * 5. enum ident : memtype; -+ * 6. enum ident; - */ - -+ type = type->semantic(loc, sc); -+ - if (memtype) - { - memtype = memtype->semantic(loc, sc); -@@ -151,183 +167,243 @@ void EnumDeclaration::semantic(Scope *sc - return; - } - } --#if 0 // Decided to abandon this restriction for D 2.0 -- if (!memtype->isintegral()) -- { error("base type must be of integral type, not %s", memtype->toChars()); -- memtype = Type::tint32; -+ if (memtype->ty == Tvoid) -+ { -+ error("base type must not be void"); -+ memtype = Type::terror; - } --#endif -+ if (memtype->ty == Terror) -+ { -+ errors = true; -+ if (members) -+ { -+ for (size_t i = 0; i < members->dim; i++) -+ { -+ Dsymbol *s = (*members)[i]; -+ s->errors = true; // poison all the members -+ } -+ } -+ semanticRun = PASSsemanticdone; -+ return; -+ } -+ } -+ -+ semanticRun = PASSsemanticdone; -+ -+ if (!members) // enum ident : memtype; -+ return; -+ -+ if (members->dim == 0) -+ { -+ error("enum %s must have at least one member", toChars()); -+ errors = true; -+ return; - } - -- isdone = 1; - Module::dprogress++; - -- type = type->semantic(loc, sc); -+ Scope *sce; - if (isAnonymous()) - sce = sc; - else - { sce = sc->push(this); - sce->parent = this; - } -- if (members->dim == 0) -- error("enum %s must have at least one member", toChars()); -- int first = 1; -- Expression *elast = NULL; -+ sce = sce->startCTFE(); -+ sce->setNoFree(); // needed for getMaxMinValue() -+ -+ /* Each enum member gets the sce scope -+ */ - for (size_t i = 0; i < members->dim; i++) - { - EnumMember *em = (*members)[i]->isEnumMember(); -- Expression *e; -- Expression *emax = NULL; -- -- if (!em) -- /* The e->semantic(sce) can insert other symbols, such as -- * template instances and function literals. -- */ -- continue; -- -- //printf(" Enum member '%s'\n",em->toChars()); -- if (em->type) -- em->type = em->type->semantic(em->loc, sce); -- e = em->value; -- if (e) -- { -- assert(e->dyncast() == DYNCAST_EXPRESSION); -- e = e->semantic(sce); -- e = e->ctfeInterpret(); -- if (memtype) -- { -- e = e->implicitCastTo(sce, memtype); -- e = e->ctfeInterpret(); -- if (!isAnonymous()) -- e = e->castTo(sce, type); -- t = memtype; -- } -- else if (em->type) -- { -- e = e->implicitCastTo(sce, em->type); -- e = e->ctfeInterpret(); -- assert(isAnonymous()); -- t = e->type; -- } -- else -- t = e->type; -- } -- else if (first) -- { -- if (memtype) -- t = memtype; -- else if (em->type) -- t = em->type; -- else -- t = Type::tint32; -- e = new IntegerExp(em->loc, 0, Type::tint32); -- e = e->implicitCastTo(sce, t); -- e = e->ctfeInterpret(); -- if (!isAnonymous()) -- e = e->castTo(sce, type); -- } -- else -- { -- // Lazily evaluate enum.max -- if (!emax) -- { -- emax = t->getProperty(0, Id::max); -- emax = emax->semantic(sce); -- emax = emax->ctfeInterpret(); -- } -- -- // Set value to (elast + 1). -- // But first check that (elast != t.max) -- assert(elast); -- e = new EqualExp(TOKequal, em->loc, elast, emax); -- e = e->semantic(sce); -- e = e->ctfeInterpret(); -- if (e->toInteger()) -- error("overflow of enum value %s", elast->toChars()); -- -- // Now set e to (elast + 1) -- e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32)); -- e = e->semantic(sce); -- e = e->castTo(sce, elast->type); -- e = e->ctfeInterpret(); -- -- if (t->isfloating()) -- { -- // Check that e != elast (not always true for floats) -- Expression *etest = new EqualExp(TOKequal, em->loc, e, elast); -- etest = etest->semantic(sce); -- etest = etest->ctfeInterpret(); -- if (etest->toInteger()) -- error("enum member %s has inexact value, due to loss of precision", em->toChars()); -- } -- } -- elast = e; -- em->value = e; -+ if (em) -+ em->scope = sce; -+ } - -- // Add to symbol table only after evaluating 'value' -+ if (!added) -+ { -+ /* addMember() is not called when the EnumDeclaration appears as a function statement, -+ * so we have to do what addMember() does and install the enum members in the right symbol -+ * table -+ */ -+ ScopeDsymbol *scopesym = NULL; - if (isAnonymous()) - { - /* Anonymous enum members get added to enclosing scope. - */ -- for (Scope *sct = sce; sct; sct = sct->enclosing) -+ for (Scope *sct = sce; 1; sct = sct->enclosing) - { -+ assert(sct); - if (sct->scopesym) - { -+ scopesym = sct->scopesym; - if (!sct->scopesym->symtab) - sct->scopesym->symtab = new DsymbolTable(); -- em->addMember(sce, sct->scopesym, 1); - break; - } - } - } - else -- em->addMember(sc, this, 1); -+ // Otherwise enum members are in the EnumDeclaration's symbol table -+ scopesym = this; - -- /* Compute .min, .max and .default values. -- * If enum doesn't have a name, we can never identify the enum type, -- * so there is no purpose for a .min, .max or .default -- */ -- if (!isAnonymous()) -+ for (size_t i = 0; i < members->dim; i++) - { -- if (first) -- { defaultval = e; -- minval = e; -- maxval = e; -- } -- else -- { Expression *ec; -- -- /* In order to work successfully with UDTs, -- * build expressions to do the comparisons, -- * and let the semantic analyzer and constant -- * folder give us the result. -- */ -- -- // Compute if(e < minval) -- ec = new CmpExp(TOKlt, em->loc, e, minval); -- ec = ec->semantic(sce); -- ec = ec->ctfeInterpret(); -- if (ec->toInteger()) -- minval = e; -- -- ec = new CmpExp(TOKgt, em->loc, e, maxval); -- ec = ec->semantic(sce); -- ec = ec->ctfeInterpret(); -- if (ec->toInteger()) -- maxval = e; -+ EnumMember *em = (*members)[i]->isEnumMember(); -+ if (em) -+ { -+ em->ed = this; -+ em->addMember(sc, scopesym, 1); - } - } -- first = 0; -+ } -+ -+ for (size_t i = 0; i < members->dim; i++) -+ { -+ EnumMember *em = (*members)[i]->isEnumMember(); -+ if (em) -+ em->semantic(em->scope); - } - //printf("defaultval = %lld\n", defaultval); - - //if (defaultval) printf("defaultval: %s %s\n", defaultval->toChars(), defaultval->type->toChars()); -- if (sc != sce) -- sce->pop(); - //members->print(); - } - --int EnumDeclaration::oneMember(Dsymbol **ps, Identifier *ident) -+/****************************** -+ * Get the value of the .max/.min property as an Expression -+ * Input: -+ * id Id::max or Id::min -+ */ -+ -+Expression *EnumDeclaration::getMaxMinValue(Loc loc, Identifier *id) -+{ -+ //printf("EnumDeclaration::getMaxValue()\n"); -+ bool first = true; -+ -+ Expression **pval = (id == Id::max) ? &maxval : &minval; -+ -+ if (*pval) -+ return *pval; -+ -+ if (scope) -+ semantic(scope); -+ if (errors) -+ goto Lerrors; -+ if (semanticRun == PASSinit || !members) -+ { -+ error("is forward referenced looking for .%s", id->toChars()); -+ goto Lerrors; -+ } -+ if (!(memtype && memtype->isintegral())) -+ { -+ error(loc, "has no .%s property because base type %s is not an integral type", -+ id->toChars(), -+ memtype ? memtype->toChars() : ""); -+ goto Lerrors; -+ } -+ -+ for (size_t i = 0; i < members->dim; i++) -+ { -+ EnumMember *em = (*members)[i]->isEnumMember(); -+ if (!em) -+ continue; -+ if (em->errors) -+ goto Lerrors; -+ -+ Expression *e = em->value; -+ if (first) -+ { -+ *pval = e; -+ first = false; -+ } -+ else -+ { -+ /* In order to work successfully with UDTs, -+ * build expressions to do the comparisons, -+ * and let the semantic analyzer and constant -+ * folder give us the result. -+ */ -+ -+ /* Compute: -+ * if (e > maxval) -+ * maxval = e; -+ */ -+ Expression *ec = new CmpExp(id == Id::max ? TOKgt : TOKlt, em->loc, e, *pval); -+ ec = ec->semantic(em->scope); -+ ec = ec->ctfeInterpret(); -+ if (ec->toInteger()) -+ *pval = e; -+ } -+ } -+ return *pval; -+ -+Lerrors: -+ *pval = new ErrorExp(); -+ return *pval; -+} -+ -+Expression *EnumDeclaration::getDefaultValue(Loc loc) -+{ -+ //printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars()); -+ if (defaultval) -+ return defaultval; -+ -+ if (scope) -+ semantic(scope); -+ if (errors) -+ goto Lerrors; -+ if (semanticRun == PASSinit || !members) -+ { -+ error(loc, "forward reference of %s.init", toChars()); -+ goto Lerrors; -+ } -+ -+ for (size_t i = 0; i < members->dim; i++) -+ { -+ EnumMember *em = (*members)[i]->isEnumMember(); -+ if (!em) -+ continue; -+ defaultval = em->value; -+ return defaultval; -+ } -+ -+Lerrors: -+ defaultval = new ErrorExp(); -+ return defaultval; -+} -+ -+Type *EnumDeclaration::getMemtype(Loc loc) -+{ -+ if (loc.linnum == 0) -+ loc = this->loc; -+ if (scope) -+ { /* Enum is forward referenced. We don't need to resolve the whole thing, -+ * just the base type -+ */ -+ if (memtype) -+ memtype = memtype->semantic(loc, scope); -+ else -+ { -+ if (!isAnonymous()) -+ memtype = Type::tint32; -+ } -+ } -+ if (!memtype) -+ { -+ if (!isAnonymous()) -+ memtype = Type::tint32; -+ else -+ { -+ error(loc, "is forward referenced looking for base type"); -+ return Type::terror; -+ } -+ } -+ return memtype; -+} -+ -+bool EnumDeclaration::oneMember(Dsymbol **ps, Identifier *ident) - { - if (isAnonymous()) - return Dsymbol::oneMembers(members, ps, ident); -@@ -380,11 +456,16 @@ const char *EnumDeclaration::kind() - return "enum"; - } - --int EnumDeclaration::isDeprecated() -+bool EnumDeclaration::isDeprecated() - { - return isdeprecated; - } - -+PROT EnumDeclaration::prot() -+{ -+ return protection; -+} -+ - Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags) - { - //printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars()); -@@ -407,9 +488,11 @@ Dsymbol *EnumDeclaration::search(Loc loc - EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type) - : Dsymbol(id) - { -+ this->ed = NULL; - this->value = value; - this->type = type; - this->loc = loc; -+ this->vd = NULL; - } - - Dsymbol *EnumMember::syntaxCopy(Dsymbol *s) -@@ -452,4 +535,172 @@ const char *EnumMember::kind() - return "enum member"; - } - -+void EnumMember::semantic(Scope *sc) -+{ -+ //printf("EnumMember::semantic() %s\n", toChars()); -+ if (errors || semanticRun >= PASSsemanticdone) -+ return; -+ if (semanticRun == PASSsemantic) -+ { -+ error("circular reference to enum member"); -+ Lerrors: -+ errors = true; -+ semanticRun = PASSsemanticdone; -+ return; -+ } -+ assert(ed); -+ ed->semantic(sc); -+ if (ed->errors) -+ goto Lerrors; - -+ if (errors || semanticRun >= PASSsemanticdone) -+ return; -+ -+ semanticRun = PASSsemantic; -+ if (scope) -+ sc = scope; -+ -+ // The first enum member is special -+ bool first = (this == (*ed->members)[0]); -+ -+ if (type) -+ { -+ type = type->semantic(loc, sc); -+ assert(value); // "type id;" is not a valid enum member declaration -+ } -+ -+ if (value) -+ { -+ Expression *e = value; -+ assert(e->dyncast() == DYNCAST_EXPRESSION); -+ e = e->semantic(sc); -+ e = resolveProperties(sc, e); -+ e = e->ctfeInterpret(); -+ if (first && !ed->memtype && !ed->isAnonymous()) -+ { -+ ed->memtype = e->type; -+ if (ed->memtype->ty == Terror) -+ { -+ ed->errors = true; -+ goto Lerrors; -+ } -+ } -+ -+ if (ed->memtype && !type) -+ { -+ e = e->implicitCastTo(sc, ed->memtype); -+ e = e->ctfeInterpret(); -+ if (!ed->isAnonymous()) -+ e = e->castTo(sc, ed->type); -+ } -+ else if (type) -+ { -+ e = e->implicitCastTo(sc, type); -+ e = e->ctfeInterpret(); -+ assert(ed->isAnonymous()); -+ } -+ value = e; -+ } -+ else if (first) -+ { -+ Type *t; -+ if (ed->memtype) -+ t = ed->memtype; -+ else -+ { -+ t = Type::tint32; -+ if (!ed->isAnonymous()) -+ ed->memtype = t; -+ } -+ Expression *e = new IntegerExp(loc, 0, Type::tint32); -+ e = e->implicitCastTo(sc, t); -+ e = e->ctfeInterpret(); -+ if (!ed->isAnonymous()) -+ e = e->castTo(sc, ed->type); -+ value = e; -+ } -+ else -+ { -+ /* Find the previous enum member, -+ * and set this to be the previous value + 1 -+ */ -+ EnumMember *emprev = NULL; -+ for (size_t i = 0; i < ed->members->dim; i++) -+ { -+ EnumMember *em = (*ed->members)[i]->isEnumMember(); -+ if (em) -+ { -+ if (em == this) -+ break; -+ emprev = em; -+ } -+ } -+ assert(emprev); -+ if (emprev->semanticRun < PASSsemanticdone) // if forward reference -+ emprev->semantic(emprev->scope); // resolve it -+ if (emprev->errors) -+ goto Lerrors; -+ -+ Expression *eprev = emprev->value; -+ Type *tprev = eprev->type->equals(ed->type) ? ed->memtype : eprev->type; -+ -+ Expression *emax = tprev->getProperty(Loc(), Id::max, 0); -+ emax = emax->semantic(sc); -+ emax = emax->ctfeInterpret(); -+ -+ // Set value to (eprev + 1). -+ // But first check that (eprev != emax) -+ assert(eprev); -+ Expression *e = new EqualExp(TOKequal, loc, eprev, emax); -+ e = e->semantic(sc); -+ e = e->ctfeInterpret(); -+ if (e->toInteger()) -+ { -+ error("initialization with (%s.%s + 1) causes overflow for type '%s'", emprev->ed->toChars(), emprev->toChars(), ed->type->toBasetype()->toChars()); -+ goto Lerrors; -+ } -+ -+ // Now set e to (eprev + 1) -+ e = new AddExp(loc, eprev, new IntegerExp(loc, 1, Type::tint32)); -+ e = e->semantic(sc); -+ e = e->castTo(sc, eprev->type); -+ e = e->ctfeInterpret(); -+ -+ if (e->type->isfloating()) -+ { -+ // Check that e != eprev (not always true for floats) -+ Expression *etest = new EqualExp(TOKequal, loc, e, eprev); -+ etest = etest->semantic(sc); -+ etest = etest->ctfeInterpret(); -+ if (etest->toInteger()) -+ { -+ error("has inexact value, due to loss of precision"); -+ goto Lerrors; -+ } -+ } -+ value = e; -+ } -+ -+ semanticRun = PASSsemanticdone; -+} -+ -+Expression *EnumMember::getVarExp(Loc loc, Scope *sc) -+{ -+ semantic(sc); -+ if (errors) -+ return new ErrorExp(); -+ if (!vd) -+ { -+ assert(value); -+ vd = new VarDeclaration(loc, type, ident, new ExpInitializer(loc, value->copy())); -+ -+ vd->storage_class = STCmanifest; -+ vd->semantic(sc); -+ -+ vd->protection = ed->isAnonymous() ? ed->protection : PROTpublic; -+ vd->parent = ed->isAnonymous() ? ed->parent : ed; -+ vd->userAttributes = ed->isAnonymous() ? ed->userAttributes : NULL; -+ } -+ Expression *e = new VarExp(loc, vd); -+ return e->semantic(sc); -+} ---- a/src/gcc/d/dfrontend/enum.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/enum.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2008 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -18,45 +18,53 @@ - #include "root.h" - #include "dsymbol.h" - --struct Identifier; --struct Type; --struct Expression; -+class Identifier; -+class Type; -+class Expression; - struct HdrGenState; -+class VarDeclaration; - -- --struct EnumDeclaration : ScopeDsymbol --{ /* enum ident : memtype { ... } -+class EnumDeclaration : public ScopeDsymbol -+{ -+public: -+ /* The separate, and distinct, cases are: -+ * 1. enum { ... } -+ * 2. enum : memtype { ... } -+ * 3. enum id { ... } -+ * 4. enum id : memtype { ... } -+ * 5. enum id : memtype; -+ * 6. enum id; - */ - Type *type; // the TypeEnum - Type *memtype; // type of the members -- enum PROT protection; -+ PROT protection; - --#if DMDV1 -- dinteger_t maxval; -- dinteger_t minval; -- dinteger_t defaultval; // default initializer --#else -+private: - Expression *maxval; - Expression *minval; - Expression *defaultval; // default initializer --#endif -- int isdeprecated; -- int isdone; // 0: not done -- // 1: semantic() successfully completed -+ -+public: -+ bool isdeprecated; -+ bool added; - - EnumDeclaration(Loc loc, Identifier *id, Type *memtype); - Dsymbol *syntaxCopy(Dsymbol *s); -+ int addMember(Scope *sc, ScopeDsymbol *sd, int memnum); - void setScope(Scope *sc); -- void semantic0(Scope *sc); - void semantic(Scope *sc); -- int oneMember(Dsymbol **ps, Identifier *ident = NULL); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - Type *getType(); - const char *kind(); - #if DMDV2 - Dsymbol *search(Loc, Identifier *ident, int flags); - #endif -- int isDeprecated(); // is Dsymbol deprecated? -+ bool isDeprecated(); // is Dsymbol deprecated? -+ PROT prot(); -+ Expression *getMaxMinValue(Loc loc, Identifier *id); -+ Expression *getDefaultValue(Loc loc); -+ Type *getMemtype(Loc loc); - - void emitComment(Scope *sc); - void toJson(JsonOut *json); -@@ -64,7 +72,6 @@ struct EnumDeclaration : ScopeDsymbol - - EnumDeclaration *isEnumDeclaration() { return this; } - -- bool objFileDone; // if toObjFile was already called - void toObjFile(int multiobj); // compile to .obj file - void toDebug(); - int cvMember(unsigned char *p); -@@ -74,15 +81,26 @@ struct EnumDeclaration : ScopeDsymbol - }; - - --struct EnumMember : Dsymbol -+class EnumMember : public Dsymbol - { -+public: -+ /* Can take the following forms: -+ * 1. id -+ * 2. id = value -+ * 3. type id = value -+ */ - Expression *value; - Type *type; - -+ EnumDeclaration *ed; -+ VarDeclaration *vd; -+ - EnumMember(Loc loc, Identifier *id, Expression *value, Type *type); - Dsymbol *syntaxCopy(Dsymbol *s); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - const char *kind(); -+ void semantic(Scope *sc); -+ Expression *getVarExp(Loc loc, Scope *sc); - - void emitComment(Scope *sc); - void toJson(JsonOut *json); ---- a/src/gcc/d/dfrontend/expression.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/expression.c 2014-04-01 16:32:51.000000000 +0100 -@@ -18,10 +18,6 @@ - #include - #endif - --#if _WIN32 && __DMC__ --extern "C" char * __cdecl __locale_decpoint; --#endif -- - #include "rmem.h" - #include "port.h" - #include "root.h" -@@ -45,10 +41,11 @@ extern "C" char * __cdecl __locale_decpo - #include "hdrgen.h" - #include "parse.h" - #include "doc.h" -- -+#include "aav.h" - - Expression *createTypeInfoArray(Scope *sc, Expression *args[], size_t dim); - Expression *expandVar(int result, VarDeclaration *v); -+void functionToCBuffer2(TypeFunction *t, OutBuffer *buf, HdrGenState *hgs, int mod, const char *kind); - - #define LOGSEMANTIC 0 - -@@ -157,11 +154,12 @@ Expression *getRightThis(Loc loc, Scope - */ - - FuncDeclaration *hasThis(Scope *sc) --{ FuncDeclaration *fd; -- FuncDeclaration *fdthis; -- -+{ - //printf("hasThis()\n"); -- fdthis = sc->parent->isFuncDeclaration(); -+ Dsymbol *p = sc->parent; -+ while (p && p->isTemplateMixin()) -+ p = p->parent; -+ FuncDeclaration *fdthis = p ? p->isFuncDeclaration() : NULL; - //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : ""); - - /* Special case for inside template constraint -@@ -174,7 +172,7 @@ FuncDeclaration *hasThis(Scope *sc) - } - - // Go upwards until we find the enclosing member function -- fd = fdthis; -+ FuncDeclaration *fd = fdthis; - while (1) - { - if (!fd) -@@ -210,113 +208,318 @@ Lno: - return NULL; // don't have 'this' available - } - -+bool isNeedThisScope(Scope *sc, Declaration *d) -+{ -+ if (sc->intypeof == 1) -+ return false; -+ -+ AggregateDeclaration *ad = d->isThis(); -+ if (!ad) -+ return false; -+ //printf("d = %s, ad = %s\n", d->toChars(), ad->toChars()); -+ -+ for (Dsymbol *s = sc->parent; s; s = s->toParent2()) -+ { -+ //printf("\ts = %s %s, toParent2() = %p\n", s->kind(), s->toChars(), s->toParent2()); -+ if (AggregateDeclaration *ad2 = s->isAggregateDeclaration()) -+ { -+ //printf("\t ad2 = %s\n", ad2->toChars()); -+ if (ad2 == ad) -+ return false; -+ else if (ad2->isNested()) -+ continue; -+ else -+ return true; -+ } -+ if (FuncDeclaration *f = s->isFuncDeclaration()) -+ { -+ if (f->isFuncLiteralDeclaration()) -+ continue; -+ if (f->isMember2()) -+ break; -+ if (TemplateDeclaration *td = f->parent->isTemplateDeclaration()) -+ { -+ if ((td->scope->stc & STCstatic) && td->isMember()) -+ break; // no valid 'this' -+ } -+ } -+ } -+ return true; -+} -+ -+Expression *checkRightThis(Scope *sc, Expression *e) -+{ -+ if (e->op == TOKvar && e->type->ty != Terror) -+ { -+ VarExp *ve = (VarExp *)e; -+ if (isNeedThisScope(sc, ve->var)) -+ { -+ //printf("checkRightThis sc->intypeof = %d, ad = %p, func = %p, fdthis = %p\n", -+ // sc->intypeof, sc->getStructClassScope(), func, fdthis); -+ e->error("need 'this' for '%s' of type '%s'", ve->var->toChars(), ve->var->type->toChars()); -+ e = new ErrorExp(); -+ } -+ } -+ return e; -+} -+ - - /*************************************** - * Pull out any properties. - */ - --Expression *resolveProperties(Scope *sc, Expression *e) -+Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL) - { -- //printf("resolveProperties(%s)\n", e->toChars()); -+ //printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", Token::toChars(e1->op), e1->toChars(), e2 ? e2->toChars() : NULL); -+ Loc loc = e1->loc; - -- TemplateDeclaration *td; -- Objects *targsi; -- Expression *ethis; -- if (e->op == TOKdotti) -- { -- DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e; -- td = dti->getTempdecl(sc); -- dti->ti->semanticTiargs(sc); -- targsi = dti->ti->tiargs; -- ethis = dti->e1; -- goto L1; -- } -- else if (e->op == TOKdottd) -- { -- DotTemplateExp *dte = (DotTemplateExp *)e; -- td = dte->td; -- targsi = NULL; -- ethis = dte->e1; -- goto L1; -- } -- else if (e->op == TOKimport) -+ OverloadSet *os; -+ Dsymbol *s; -+ Objects *tiargs; -+ Type *tthis; -+ if (e1->op == TOKdotexp) - { -- Dsymbol *s = ((ScopeExp *)e)->sds; -- td = s->isTemplateDeclaration(); -- if (td) -+ DotExp *de = (DotExp *)e1; -+ if (de->e2->op == TOKoverloadset) - { -- targsi = NULL; -- ethis = NULL; -- goto L1; -+ tiargs = NULL; -+ tthis = de->e1->type; -+ os = ((OverExp *)de->e2)->vars; -+ goto Los; - } - } -- else if (e->op == TOKtemplate) -+ else if (e1->op == TOKoverloadset) - { -- td = ((TemplateExp *)e)->td; -- targsi = NULL; -- ethis = NULL; -- L1: -- assert(td); -- unsigned errors = global.startGagging(); -- FuncDeclaration *fd = td->deduceFunctionTemplate(sc, e->loc, targsi, ethis, NULL, 1); -- if (global.endGagging(errors)) -- fd = NULL; // eat "is not a function template" error -- if (fd && fd->type) -- { assert(fd->type->ty == Tfunction); -- TypeFunction *tf = (TypeFunction *)fd->type; -- if (!tf->isproperty && global.params.enforcePropertySyntax) -- { error(e->loc, "not a property %s", e->toChars()); -+ tiargs = NULL; -+ tthis = NULL; -+ os = ((OverExp *)e1)->vars; -+ Los: -+ assert(os); -+ FuncDeclaration *fd = NULL; -+ if (e2) -+ { -+ e2 = e2->semantic(sc); -+ if (e2->op == TOKerror) - return new ErrorExp(); -+ e2 = resolveProperties(sc, e2); -+ -+ Expressions a; -+ a.push(e2); -+ -+ for (size_t i = 0; i < os->a.dim; i++) -+ { -+ Dsymbol *s = os->a[i]; -+ FuncDeclaration *f = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, 1); -+ if (f) -+ { -+ fd = f; -+ assert(fd->type->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ if (!tf->isproperty && global.params.enforcePropertySyntax) -+ goto Leprop; -+ } -+ } -+ if (fd) -+ { -+ Expression *e = new CallExp(loc, e1, e2); -+ return e->semantic(sc); -+ } -+ } -+ { -+ for (size_t i = 0; i < os->a.dim; i++) -+ { -+ Dsymbol *s = os->a[i]; -+ FuncDeclaration *f = resolveFuncCall(loc, sc, s, tiargs, tthis, NULL, 1); -+ if (f) -+ { -+ fd = f; -+ assert(fd->type->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ if (!tf->isref && e2) -+ goto Leproplvalue; -+ if (!tf->isproperty && global.params.enforcePropertySyntax) -+ goto Leprop; -+ } -+ } -+ if (fd) -+ { -+ Expression *e = new CallExp(loc, e1); -+ if (e2) -+ e = new AssignExp(loc, e, e2); -+ return e->semantic(sc); - } -- e = new CallExp(e->loc, e); -- e = e->semantic(sc); - } -- goto return_expr; -+ if (e2) -+ goto Leprop; - } -- -- if (e->type && -- e->op != TOKtype) // function type is not a property -+ else if (e1->op == TOKdotti) -+ { -+ DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1; -+ if (!dti->findTempDecl(sc)) -+ goto Leprop; -+ if (!dti->ti->semanticTiargs(sc)) -+ goto Leprop; -+ tiargs = dti->ti->tiargs; -+ tthis = dti->e1->type; -+ if ((os = dti->ti->tempdecl->isOverloadSet()) != NULL) -+ goto Los; -+ if ((s = dti->ti->tempdecl) != NULL) -+ goto Lfd; -+ } -+ else if (e1->op == TOKdottd) -+ { -+ DotTemplateExp *dte = (DotTemplateExp *)e1; -+ s = dte->td; -+ tiargs = NULL; -+ tthis = dte->e1->type; -+ goto Lfd; -+ } -+ else if (e1->op == TOKimport) -+ { -+ s = ((ScopeExp *)e1)->sds; -+ if (s->isTemplateDeclaration()) -+ { -+ tiargs = NULL; -+ tthis = NULL; -+ goto Lfd; -+ } -+ TemplateInstance *ti = s->isTemplateInstance(); -+ if (ti && !ti->semanticRun && ti->tempdecl) -+ { -+ //assert(ti->needsTypeInference(sc)); -+ if (!ti->semanticTiargs(sc)) -+ { -+ ti->inst = ti; -+ ti->inst->errors = true; -+ goto Leprop; -+ } -+ tiargs = ti->tiargs; -+ tthis = NULL; -+ if ((os = ti->tempdecl->isOverloadSet()) != NULL) -+ goto Los; -+ if ((s = ti->tempdecl) != NULL) -+ goto Lfd; -+ } -+ } -+ else if (e1->op == TOKtemplate) - { -- Type *t = e->type->toBasetype(); -+ s = ((TemplateExp *)e1)->td; -+ tiargs = NULL; -+ tthis = NULL; -+ goto Lfd; -+ } -+ else if (e1->op == TOKdotvar && e1->type && e1->type->toBasetype()->ty == Tfunction) -+ { -+ DotVarExp *dve = (DotVarExp *)e1; -+ s = dve->var->isFuncDeclaration(); -+ tiargs = NULL; -+ tthis = dve->e1->type; -+ goto Lfd; -+ } -+ else if (e1->op == TOKvar && e1->type && e1->type->toBasetype()->ty == Tfunction) -+ { -+ s = ((VarExp *)e1)->var->isFuncDeclaration(); -+ tiargs = NULL; -+ tthis = NULL; -+ Lfd: -+ assert(s); -+ FuncDeclaration *fd; -+ if (e2) -+ { -+ e2 = e2->semantic(sc); -+ if (e2->op == TOKerror) -+ return new ErrorExp(); -+ e2 = resolveProperties(sc, e2); -+ -+ Expressions a; -+ a.push(e2); - -- if (t->ty == Tfunction || e->op == TOKoverloadset) -+ fd = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, 1); -+ if (fd && fd->type) -+ { -+ assert(fd->type->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ if (!tf->isproperty && global.params.enforcePropertySyntax) -+ goto Leprop; -+ Expression *e = new CallExp(loc, e1, e2); -+ return e->semantic(sc); -+ } -+ } - { -- if (t->ty == Tfunction && !((TypeFunction *)t)->isproperty && -- global.params.enforcePropertySyntax) -+ fd = resolveFuncCall(loc, sc, s, tiargs, tthis, NULL, 1); -+ if (fd && fd->type) - { -- error(e->loc, "not a property %s", e->toChars()); -- return new ErrorExp(); -+ assert(fd->type->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ if (!tf->isref && e2) -+ goto Leproplvalue; -+ if (!tf->isproperty && global.params.enforcePropertySyntax) -+ goto Leprop; -+ Expression *e = new CallExp(loc, e1); -+ if (e2) -+ e = new AssignExp(loc, e, e2); -+ return e->semantic(sc); - } -- e = new CallExp(e->loc, e); -- e = e->semantic(sc); - } -+ if (FuncDeclaration *fd = s->isFuncDeclaration()) -+ { // Keep better diagnostic message for invalid property usage of functions -+ assert(fd->type->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ if (!tf->isproperty && global.params.enforcePropertySyntax) -+ error(loc, "not a property %s", e1->toChars()); -+ Expression *e = new CallExp(loc, e1, e2); -+ return e->semantic(sc); -+ } -+ if (e2) -+ goto Leprop; -+ } -+ if (e2) -+ return NULL; - -- /* Look for e being a lazy parameter; rewrite as delegate call -+ if (e1->type && -+ e1->op != TOKtype) // function type is not a property -+ { -+ /* Look for e1 being a lazy parameter; rewrite as delegate call - */ -- else if (e->op == TOKvar) -- { VarExp *ve = (VarExp *)e; -+ if (e1->op == TOKvar) -+ { -+ VarExp *ve = (VarExp *)e1; - - if (ve->var->storage_class & STClazy) - { -- e = new CallExp(e->loc, e); -- e = e->semantic(sc); -+ Expression *e = new CallExp(loc, e1); -+ return e->semantic(sc); - } - } -- -- else if (e->op == TOKdotexp) -+ else if (e1->op == TOKdotexp) - { -- e->error("expression has no value"); -+ e1->error("expression has no value"); - return new ErrorExp(); - } -- - } - --return_expr: -- if (!e->type) -+ if (!e1->type) - { -- error(e->loc, "cannot resolve type for %s", e->toChars()); -- e->type = new TypeError(); -+ error(loc, "cannot resolve type for %s", e1->toChars()); -+ e1 = new ErrorExp(); - } -+ return e1; -+ -+Leprop: -+ error(loc, "not a property %s", e1->toChars()); -+ return new ErrorExp(); -+ -+Leproplvalue: -+ error(loc, "%s is not an lvalue", e1->toChars()); -+ return new ErrorExp(); -+} -+ -+Expression *resolveProperties(Scope *sc, Expression *e) -+{ -+ //printf("resolveProperties(%s)\n", e->toChars()); -+ -+ e = resolvePropertiesX(sc, e); -+ e = checkRightThis(sc, e); - return e; - } - -@@ -342,18 +545,313 @@ void checkPropertyCall(Expression *e, Ex - tf = (TypeFunction *)ce->f->type; - } - } -- else if (ce->e1->type->ty == Tfunction) -- tf = (TypeFunction *)ce->e1->type; -- else if (ce->e1->type->ty == Tdelegate) -- tf = (TypeFunction *)ce->e1->type->nextOf(); -- else if (ce->e1->type->ty == Tpointer && ce->e1->type->nextOf()->ty == Tfunction) -- tf = (TypeFunction *)ce->e1->type->nextOf(); -- else -- assert(0); -- -- if (!tf->isproperty && global.params.enforcePropertySyntax) -- ce->e1->error("not a property %s", emsg->toChars()); -+ else if (ce->e1->type->ty == Tfunction) -+ tf = (TypeFunction *)ce->e1->type; -+ else if (ce->e1->type->ty == Tdelegate) -+ tf = (TypeFunction *)ce->e1->type->nextOf(); -+ else if (ce->e1->type->ty == Tpointer && ce->e1->type->nextOf()->ty == Tfunction) -+ tf = (TypeFunction *)ce->e1->type->nextOf(); -+ else -+ assert(0); -+ -+ if (!tf->isproperty && global.params.enforcePropertySyntax) -+ ce->e1->error("not a property %s", emsg->toChars()); -+ } -+} -+ -+/****************************** -+ * If e1 is a property function (template), resolve it. -+ */ -+ -+Expression *resolvePropertiesOnly(Scope *sc, Expression *e1) -+{ -+ OverloadSet *os; -+ FuncDeclaration *fd; -+ TemplateDeclaration *td; -+ -+ if (e1->op == TOKdotexp) -+ { -+ DotExp *de = (DotExp *)e1; -+ if (de->e2->op == TOKoverloadset) -+ { -+ os = ((OverExp *)de->e2)->vars; -+ goto Los; -+ } -+ } -+ else if (e1->op == TOKoverloadset) -+ { -+ os = ((OverExp *)e1)->vars; -+ Los: -+ assert(os); -+ for (size_t i = 0; i < os->a.dim; i++) -+ { -+ Dsymbol *s = os->a[i]; -+ fd = s->isFuncDeclaration(); -+ td = s->isTemplateDeclaration(); -+ if (fd) -+ { -+ if (((TypeFunction *)fd->type)->isproperty) -+ return resolveProperties(sc, e1); -+ } -+ else if (td && td->onemember && -+ (fd = td->onemember->isFuncDeclaration()) != NULL) -+ { -+ if (((TypeFunction *)fd->type)->isproperty || -+ (fd->storage_class2 & STCproperty) || -+ (td->scope->stc & STCproperty)) -+ { -+ return resolveProperties(sc, e1); -+ } -+ } -+ } -+ } -+ else if (e1->op == TOKdotti) -+ { -+ DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1; -+ if (dti->ti->tempdecl && (td = dti->ti->tempdecl->isTemplateDeclaration()) != NULL) -+ goto Ltd; -+ } -+ else if (e1->op == TOKdottd) -+ { -+ td = ((DotTemplateExp *)e1)->td; -+ goto Ltd; -+ } -+ else if (e1->op == TOKimport) -+ { -+ Dsymbol *s = ((ScopeExp *)e1)->sds; -+ td = s->isTemplateDeclaration(); -+ if (td) -+ goto Ltd; -+ TemplateInstance *ti = s->isTemplateInstance(); -+ if (ti && !ti->semanticRun && ti->tempdecl) -+ { -+ if ((td = ti->tempdecl->isTemplateDeclaration()) != NULL) -+ goto Ltd; -+ } -+ } -+ else if (e1->op == TOKtemplate) -+ { -+ td = ((TemplateExp *)e1)->td; -+ Ltd: -+ assert(td); -+ if (td->onemember && -+ (fd = td->onemember->isFuncDeclaration()) != NULL) -+ { -+ if (((TypeFunction *)fd->type)->isproperty || -+ (fd->storage_class2 & STCproperty) || -+ (td->scope->stc & STCproperty)) -+ { -+ return resolveProperties(sc, e1); -+ } -+ } -+ } -+ else if (e1->op == TOKdotvar && e1->type->ty == Tfunction) -+ { -+ DotVarExp *dve = (DotVarExp *)e1; -+ fd = dve->var->isFuncDeclaration(); -+ goto Lfd; -+ } -+ else if (e1->op == TOKvar && e1->type->ty == Tfunction) -+ { -+ fd = ((VarExp *)e1)->var->isFuncDeclaration(); -+ Lfd: -+ assert(fd); -+ if (((TypeFunction *)fd->type)->isproperty) -+ return resolveProperties(sc, e1); -+ } -+ return e1; -+} -+ -+ -+/****************************** -+ * Find symbol in accordance with the UFCS name look up rule -+ */ -+ -+Expression *searchUFCS(Scope *sc, UnaExp *ue, Identifier *ident) -+{ -+ Loc loc = ue->loc; -+ Dsymbol *s = NULL; -+ -+ for (Scope *scx = sc; scx; scx = scx->enclosing) -+ { -+ if (!scx->scopesym) -+ continue; -+ s = scx->scopesym->search(loc, ident, 0); -+ if (s) -+ { -+ // overload set contains only module scope symbols. -+ if (s->isOverloadSet()) -+ break; -+ // selective/renamed imports also be picked up -+ if (AliasDeclaration *ad = s->isAliasDeclaration()) -+ { -+ if (ad->import) -+ break; -+ } -+ // See only module scope symbols for UFCS target. -+ Dsymbol *p = s->toParent2(); -+ if (p && p->isModule()) -+ break; -+ } -+ s = NULL; -+ } -+ if (!s) -+ return ue->e1->type->Type::getProperty(loc, ident, 0); -+ -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ if (f) -+ { -+ TemplateDeclaration *td = getFuncTemplateDecl(f); -+ if (td) -+ { -+ if (td->overroot) -+ td = td->overroot; -+ s = td; -+ } -+ } -+ -+ if (ue->op == TOKdotti) -+ { -+ DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ue; -+ TemplateInstance *ti = new TemplateInstance(loc, s->ident); -+ ti->tiargs = dti->ti->tiargs; // for better diagnostic message -+ if (!ti->updateTemplateDeclaration(sc, s)) -+ return new ErrorExp(); -+ return new ScopeExp(loc, ti); -+ } -+ else -+ { -+ return new DsymbolExp(loc, s, 1); -+ } -+} -+ -+/****************************** -+ * check e is exp.opDispatch!(tiargs) or not -+ * It's used to switch to UFCS the semantic analysis path -+ */ -+ -+bool isDotOpDispatch(Expression *e) -+{ -+ return e->op == TOKdotti && -+ ((DotTemplateInstanceExp *)e)->ti->name == Id::opDispatch; -+} -+ -+/****************************** -+ * Pull out callable entity with UFCS. -+ */ -+ -+Expression *resolveUFCS(Scope *sc, CallExp *ce) -+{ -+ Loc loc = ce->loc; -+ Expression *eleft; -+ Expression *e; -+ -+ if (ce->e1->op == TOKdot) -+ { -+ DotIdExp *die = (DotIdExp *)ce->e1; -+ Identifier *ident = die->ident; -+ -+ Expression *ex = die->semanticX(sc); -+ if (ex != die) -+ { -+ ce->e1 = ex; -+ return NULL; -+ } -+ eleft = die->e1; -+ -+ Type *t = eleft->type->toBasetype(); -+ if (t->ty == Tarray || t->ty == Tsarray || -+ t->ty == Tnull || (t->isTypeBasic() && t->ty != Tvoid)) -+ { -+ /* Built-in types and arrays have no callable properties, so do shortcut. -+ * It is necessary in: e.init() -+ */ -+ } -+ else if (t->ty == Taarray) -+ { -+ if (ident == Id::remove) -+ { -+ /* Transform: -+ * aa.remove(arg) into delete aa[arg] -+ */ -+ if (!ce->arguments || ce->arguments->dim != 1) -+ { -+ ce->error("expected key as argument to aa.remove()"); -+ return new ErrorExp(); -+ } -+ if (!eleft->type->isMutable()) -+ { -+ ce->error("cannot remove key from %s associative array %s", -+ MODtoChars(t->mod), eleft->toChars()); -+ return new ErrorExp(); -+ } -+ Expression *key = (*ce->arguments)[0]; -+ key = key->semantic(sc); -+ key = resolveProperties(sc, key); -+ -+ TypeAArray *taa = (TypeAArray *)t; -+ key = key->implicitCastTo(sc, taa->index); -+ -+ if (!key->rvalue()) -+ return new ErrorExp(); -+ -+ return new RemoveExp(loc, eleft, key); -+ } -+ else if (ident == Id::apply || ident == Id::applyReverse) -+ { -+ return NULL; -+ } -+ else -+ { -+ TypeAArray *taa = (TypeAArray *)t; -+ assert(taa->ty == Taarray); -+ StructDeclaration *sd = taa->getImpl(); -+ Dsymbol *s = sd->search(Loc(), ident, 2); -+ if (s) -+ return NULL; -+ } -+ } -+ else -+ { -+ if (Expression *ey = die->semanticY(sc, 1)) -+ { -+ ce->e1 = ey; -+ if (isDotOpDispatch(ey)) -+ { -+ unsigned errors = global.startGagging(); -+ e = ce->semantic(sc); -+ if (global.endGagging(errors)) -+ {} /* fall down to UFCS */ -+ else -+ return e; -+ } -+ else -+ return NULL; -+ } -+ } -+ e = searchUFCS(sc, die, ident); -+ } -+ else if (ce->e1->op == TOKdotti) -+ { -+ DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ce->e1; -+ if (Expression *ey = dti->semanticY(sc, 1)) -+ { -+ ce->e1 = ey; -+ return NULL; -+ } -+ eleft = dti->e1; -+ e = searchUFCS(sc, dti, dti->ti->name); - } -+ else -+ return NULL; -+ -+ // Rewrite -+ ce->e1 = e; -+ if (!ce->arguments) -+ ce->arguments = new Expressions(); -+ ce->arguments->shift(eleft); -+ -+ return NULL; - } - - /****************************** -@@ -362,130 +860,76 @@ void checkPropertyCall(Expression *e, Ex - - Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NULL) - { -- Expression *e = NULL; -- Expression *eleft; -- Identifier *ident; -- Objects* tiargs; - Loc loc = e1->loc; -+ Expression *eleft; -+ Expression *e; - - if (e1->op == TOKdot) - { - DotIdExp *die = (DotIdExp *)e1; -- eleft = die->e1; -- ident = die->ident; -- tiargs = NULL; -- goto L1; -+ eleft = die->e1; -+ e = searchUFCS(sc, die, die->ident); - } - else if (e1->op == TOKdotti) - { - DotTemplateInstanceExp *dti; - dti = (DotTemplateInstanceExp *)e1; -- eleft = dti->e1; -- ident = dti->ti->name; -- tiargs = dti->ti->tiargs; -- L1: -- /* .ident -- * .ident!tiargs -- */ -- e = new IdentifierExp(loc, Id::empty); -- if (tiargs) -- e = new DotTemplateInstanceExp(loc, e, ident, tiargs); -- else -- e = new DotIdExp(loc, e, ident); -+ eleft = dti->e1; -+ e = searchUFCS(sc, dti, dti->ti->name); -+ } -+ else -+ return NULL; - -- if (e2) -- { -- // run semantic without gagging -- e2 = e2->semantic(sc); -+ // Rewrite -+ if (e2) -+ { -+ // run semantic without gagging -+ e2 = e2->semantic(sc); - -- /* .f(e1) = e2 -- */ -- Expression *ex = e->syntaxCopy(); -- Expressions *a1 = new Expressions(); -- a1->setDim(1); -- (*a1)[0] = eleft; -- ex = new CallExp(loc, ex, a1); -- ex = ex->trySemantic(sc); -- -- /* .f(e1, e2) -- */ -- Expressions *a2 = new Expressions(); -- a2->setDim(2); -- (*a2)[0] = eleft; -- (*a2)[1] = e2; -- e = new CallExp(loc, e, a2); -- if (ex) -- { // if fallback setter exists, gag errors -- e = e->trySemantic(sc); -- if (!e) -- { checkPropertyCall(ex, e1); -- ex = new AssignExp(loc, ex, e2); -- return ex->semantic(sc); -- } -- } -- else -- { // strict setter prints errors if fails -- e = e->semantic(sc); -+ /* f(e1) = e2 -+ */ -+ Expression *ex = e->copy(); -+ Expressions *a1 = new Expressions(); -+ a1->setDim(1); -+ (*a1)[0] = eleft; -+ ex = new CallExp(loc, ex, a1); -+ ex = ex->trySemantic(sc); -+ -+ /* f(e1, e2) -+ */ -+ Expressions *a2 = new Expressions(); -+ a2->setDim(2); -+ (*a2)[0] = eleft; -+ (*a2)[1] = e2; -+ e = new CallExp(loc, e, a2); -+ if (ex) -+ { // if fallback setter exists, gag errors -+ e = e->trySemantic(sc); -+ if (!e) -+ { checkPropertyCall(ex, e1); -+ ex = new AssignExp(loc, ex, e2); -+ return ex->semantic(sc); - } -- checkPropertyCall(e, e1); -- return e; - } - else -- { -- /* .f(e1) -- */ -- Expressions *arguments = new Expressions(); -- arguments->setDim(1); -- (*arguments)[0] = eleft; -- e = new CallExp(loc, e, arguments); -+ { // strict setter prints errors if fails - e = e->semantic(sc); -- checkPropertyCall(e, e1); -- return e->semantic(sc); - } -+ checkPropertyCall(e, e1); -+ return e; - } -- return e; --} -- --/********************************* -- * Attempt to find a type property. If failed, attempt to find -- * UFCS property. If UFCS found, return expression. Otherwise -- * show type property error message. -- * Returns non-NULL only if UFCS property found. -- */ --Expression * resolveProperty(Scope *sc, Expression **e1, Expression *e2) --{ -- enum TOK op = (*e1)->op; -- UnaExp *una = (UnaExp *)(*e1); -- Type *t = una->e1->type; -- int olderrors = global.errors; -- una->e1 = una->e1->semantic(sc); -- if (global.errors == olderrors && una->e1->type) -+ else - { -- unsigned errors = global.startGagging(); -- // try property gagged -- if (op == TOKdotti) -- *e1 = ((DotTemplateInstanceExp *)una)->semantic(sc, 1); -- else if (op == TOKdot) -- *e1 = ((DotIdExp *)una)->semantic(sc, 1); -- -- if (global.endGagging(errors) || (*e1)->op == TOKerror) -- { -- (*e1)->op = op; -- errors = global.startGagging(); // try UFCS gagged -- Expression *e = resolveUFCSProperties(sc, una, e2); -- if (!global.endGagging(errors) && (*e1)->op != TOKerror) -- return e; // found UFCS -- -- // try property non-gagged -- una->type = t; // restore type -- if (op == TOKdotti) -- *e1 = ((DotTemplateInstanceExp *)una)->semantic(sc, 1); -- else if (op == TOKdot) -- *e1 = ((DotIdExp *)una)->semantic(sc, 1); -- } -+ /* f(e1) -+ */ -+ Expressions *arguments = new Expressions(); -+ arguments->setDim(1); -+ (*arguments)[0] = eleft; -+ e = new CallExp(loc, e, arguments); -+ e = e->semantic(sc); -+ checkPropertyCall(e, e1); -+ return e->semantic(sc); - } -- -- return NULL; - } - - /****************************** -@@ -560,12 +1004,13 @@ void expandTuples(Expressions *exps) - - // Inline expand all the tuples - while (arg->op == TOKtuple) -- { TupleExp *te = (TupleExp *)arg; -- -+ { -+ TupleExp *te = (TupleExp *)arg; - exps->remove(i); // remove arg - exps->insert(i, te->exps); // replace with tuple contents - if (i == exps->dim) - return; // empty tuple, no more arguments -+ (*exps)[i] = Expression::combine(te->e0, (*exps)[i]); - arg = (*exps)[i]; - } - } -@@ -578,26 +1023,28 @@ void expandTuples(Expressions *exps) - - TupleDeclaration *isAliasThisTuple(Expression *e) - { -- if (e->type) -+ if (!e->type) -+ return NULL; -+ -+ Type *t = e->type->toBasetype(); -+Lagain: -+ if (Dsymbol *s = t->toDsymbol(NULL)) - { -- Type *t = e->type->toBasetype(); -- AggregateDeclaration *ad; -- if (t->ty == Tstruct) -- { -- ad = ((TypeStruct *)t)->sym; -- goto L1; -- } -- else if (t->ty == Tclass) -+ AggregateDeclaration *ad = s->isAggregateDeclaration(); -+ if (ad) - { -- ad = ((TypeClass *)t)->sym; -- L1: -- Dsymbol *s = ad->aliasthis; -+ s = ad->aliasthis; - if (s && s->isVarDeclaration()) - { - TupleDeclaration *td = s->isVarDeclaration()->toAlias()->isTupleDeclaration(); - if (td && td->isexp) - return td; - } -+ if (Type *att = t->aliasthisOf()) -+ { -+ t = att; -+ goto Lagain; -+ } - } - } - return NULL; -@@ -683,24 +1130,28 @@ Expressions *arrayExpressionToCommonType - */ - //printf("arrayExpressionToCommonType()\n"); - IntegerExp integerexp(0); -- CondExp condexp(0, &integerexp, NULL, NULL); -+ CondExp condexp(Loc(), &integerexp, NULL, NULL); - - Type *t0 = NULL; - Expression *e0; - size_t j0; - for (size_t i = 0; i < exps->dim; i++) -- { Expression *e = (*exps)[i]; -- -+ { -+ Expression *e = (*exps)[i]; - e = resolveProperties(sc, e); - if (!e->type) -- { e->error("%s has no value", e->toChars()); -+ { -+ e->error("%s has no value", e->toChars()); - e = new ErrorExp(); - } - -- e = callCpCtor(e->loc, sc, e, 1); -+ if (Expression *ex = e->isTemp()) -+ e = ex; -+ e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e); - - if (t0) -- { if (t0 != e->type) -+ { -+ if (t0 != e->type) - { - /* This applies ?: to merge the types. It's backwards; - * ?: should call this function to merge types. -@@ -718,7 +1169,8 @@ Expressions *arrayExpressionToCommonType - } - } - else -- { j0 = i; -+ { -+ j0 = i; - e0 = e; - t0 = e->type; - } -@@ -751,16 +1203,19 @@ TemplateDeclaration *getFuncTemplateDecl - { - FuncDeclaration *f = s->isFuncDeclaration(); - if (f && f->parent) -- { TemplateInstance *ti = f->parent->isTemplateInstance(); -- -+ { -+ TemplateInstance *ti = f->parent->isTemplateInstance(); -+ TemplateDeclaration *td; - if (ti && - !ti->isTemplateMixin() && - (ti->name == f->ident || - ti->toAlias()->ident == f->ident) - && -- ti->tempdecl && ti->tempdecl->onemember) -+ ti->tempdecl && -+ (td = ti->tempdecl->isTemplateDeclaration()) != NULL && -+ td->onemember) - { -- return ti->tempdecl; -+ return td; - } - } - return NULL; -@@ -782,6 +1237,9 @@ void preFunctionParameters(Loc loc, Scop - arg = resolveProperties(sc, arg); - (*exps)[i] = arg; - -+ if (arg->op == TOKtype) -+ arg->error("%s is not an expression", arg->toChars()); -+ - //arg->rvalue(); - } - } -@@ -792,7 +1250,7 @@ void preFunctionParameters(Loc loc, Scop - * the destructor on it. - */ - --void valueNoDtor(Expression *e) -+Expression *valueNoDtor(Expression *e) - { - if (e->op == TOKcall) - { -@@ -805,70 +1263,94 @@ void valueNoDtor(Expression *e) - */ - CallExp *ce = (CallExp *)e; - if (ce->e1->op == TOKdotvar) -- { DotVarExp *dve = (DotVarExp *)ce->e1; -+ { -+ DotVarExp *dve = (DotVarExp *)ce->e1; - if (dve->var->isCtorDeclaration()) -- { // It's a constructor call -+ { -+ // It's a constructor call - if (dve->e1->op == TOKcomma) -- { CommaExp *comma = (CommaExp *)dve->e1; -+ { -+ CommaExp *comma = (CommaExp *)dve->e1; - if (comma->e2->op == TOKvar) -- { VarExp *ve = (VarExp *)comma->e2; -+ { -+ VarExp *ve = (VarExp *)comma->e2; - VarDeclaration *ctmp = ve->var->isVarDeclaration(); - if (ctmp) -+ { - ctmp->noscope = 1; -+ assert(!ce->isLvalue()); -+ } - } - } - } - } - } -+ return e; - } - - /******************************************** -- * Determine if t is an array of structs that need a postblit. -+ * Determine if t is an array of structs that need a default construction. - */ - #if DMDV2 --int checkPostblit(Loc loc, Type *t) -+bool checkDefCtor(Loc loc, Type *t) - { -- t = t->toBasetype(); -- while (t->ty == Tsarray) -- t = t->nextOf()->toBasetype(); -+ t = t->baseElemOf(); - if (t->ty == Tstruct) -- { FuncDeclaration *fd = ((TypeStruct *)t)->sym->postblit; -- if (fd) -- { if (fd->storage_class & STCdisable) -- fd->toParent()->error(loc, "is not copyable because it is annotated with @disable"); -- return 1; -+ { -+ StructDeclaration *sd = ((TypeStruct *)t)->sym; -+ if (sd->noDefaultCtor) -+ { -+ sd->error(loc, "default construction is disabled"); -+ return true; - } - } -- return 0; -+ return false; - } - #endif - --/********************************************* -- * Call copy constructor for struct value argument. -+/******************************************** -+ * Determine if t is an array of structs that need a postblit. - */ - #if DMDV2 --Expression *callCpCtor(Loc loc, Scope *sc, Expression *e, int noscope) -+bool Expression::checkPostblit(Scope *sc, Type *t) - { -- if (e->op == TOKarrayliteral) -+ t = t->baseElemOf(); -+ if (t->ty == Tstruct) - { -- ArrayLiteralExp *ae = (ArrayLiteralExp *)e; -- for (size_t i = 0; i < ae->elements->dim; i++) -+ // Bugzilla 11395: Require TypeInfo generation for array concatenation -+ if (!t->vtinfo) -+ t->getTypeInfo(sc); -+ -+ StructDeclaration *sd = ((TypeStruct *)t)->sym; -+ if (sd->postblit) - { -- ae->elements->tdata()[i] = -- callCpCtor(loc, sc, ae->elements->tdata()[i], noscope); -+ if (sd->postblit->storage_class & STCdisable) -+ sd->error(loc, "is not copyable because it is annotated with @disable"); -+ else -+ { -+ checkPurity(sc, sd->postblit); -+ checkSafety(sc, sd->postblit); -+ } -+ return true; - } -- e = ae->semantic(sc); -- return e; - } -+ return false; -+} -+#endif - -- Type *tb = e->type->toBasetype(); -- Type *tv = tb; -- while (tv->ty == Tsarray) -- tv = tv->nextOf()->toBasetype(); -+/********************************************* -+ * Call copy constructor for struct value argument. -+ * Input: -+ * sc just used to specify the scope of created temporary variable -+ */ -+#if DMDV2 -+Expression *callCpCtor(Scope *sc, Expression *e) -+{ -+ Type *tv = e->type->baseElemOf(); - if (tv->ty == Tstruct) - { - StructDeclaration *sd = ((TypeStruct *)tv)->sym; -- if (sd->cpctor && e->isLvalue()) -+ if (sd->cpctor) - { - /* Create a variable tmp, and replace the argument e with: - * (tmp = e),tmp -@@ -877,12 +1359,15 @@ Expression *callCpCtor(Loc loc, Scope *s - * directly onto the stack. - */ - Identifier *idtmp = Lexer::uniqueId("__cpcttmp"); -- VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e)); -+ VarDeclaration *tmp = new VarDeclaration(e->loc, e->type, idtmp, new ExpInitializer(e->loc, e)); - tmp->storage_class |= STCctfe; -- tmp->noscope = noscope; -- Expression *ae = new DeclarationExp(loc, tmp); -- e = new CommaExp(loc, ae, new VarExp(loc, tmp)); -- e = e->semantic(sc); -+ tmp->noscope = 1; -+ tmp->semantic(sc); -+ Expression *de = new DeclarationExp(e->loc, tmp); -+ Expression *ve = new VarExp(e->loc, tmp); -+ de->type = Type::tvoid; -+ ve->type = e->type; -+ e = Expression::combine(de, ve); - } - } - return e; -@@ -904,7 +1389,7 @@ Expression *callCpCtor(Loc loc, Scope *s - */ - - Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, -- Expression *ethis, Expressions *arguments, FuncDeclaration *fd) -+ Type *tthis, Expressions *arguments, FuncDeclaration *fd) - { - //printf("functionParameters()\n"); - assert(arguments); -@@ -930,13 +1415,14 @@ Type *functionParameters(Loc loc, Scope - fd->functionSemantic3(); - } - } -+ bool isCtorCall = fd && fd->needThis() && fd->isCtorDeclaration(); - - size_t n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) - - unsigned wildmatch = 0; -- if (ethis && tf->isWild()) -+ if (tthis && tf->isWild() && !isCtorCall) - { -- Type *t = ethis->type; -+ Type *t = tthis; - if (t->isWild()) - wildmatch |= MODwild; - else if (t->isConst()) -@@ -963,7 +1449,7 @@ Type *functionParameters(Loc loc, Scope - - if (!arg) - { -- if (!p->defaultArg || !fd) -+ if (!p->defaultArg) - { - if (tf->varargs == 2 && i + 1 == nparams) - goto L2; -@@ -973,19 +1459,12 @@ Type *functionParameters(Loc loc, Scope - arg = p->defaultArg; - arg = arg->inlineCopy(sc); - #if DMDV2 -- arg = arg->resolveLoc(loc, sc); // __FILE__ and __LINE__ -+ // __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__ -+ arg = arg->resolveLoc(loc, sc); - #endif - arguments->push(arg); - nargs++; - } -- else -- { -- Type *pt = p->type; -- if (tf->varargs == 2 && i + 1 == nparams && pt->nextOf()) -- pt = pt->nextOf(); -- arg = arg->inferType(pt); -- (*arguments)[i] = arg; -- } - - if (tf->varargs == 2 && i + 1 == nparams) - { -@@ -1009,35 +1488,28 @@ Type *functionParameters(Loc loc, Scope - case Tsarray: - case Tarray: - { // Create a static array variable v of type arg->type --#ifdef IN_GCC -- /* GCC 4.0 does not like zero length arrays used like -- this; pass a null array value instead. Could also -- just make a one-element array. */ -- if (nargs - i == 0) -- { -- arg = new NullExp(loc); -- break; -- } --#endif - Identifier *id = Lexer::uniqueId("__arrayArg"); - Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i)); - t = t->semantic(loc, sc); -- bool isSafe = fd ? fd->isSafe() : tf->trust == TRUSTsafe; - VarDeclaration *v = new VarDeclaration(loc, t, id, -- (isSafe && sc->func) ? NULL : new VoidInitializer(loc)); -+ (sc->func && sc->func->isSafe()) ? NULL : new VoidInitializer(loc)); - v->storage_class |= STCctfe; - v->semantic(sc); - v->parent = sc->parent; - //sc->insert(v); - -- Expression *c = new DeclarationExp(0, v); -+ Expression *c = new DeclarationExp(Loc(), v); - c->type = v->type; - - for (size_t u = i; u < nargs; u++) -- { Expression *a = (*arguments)[u]; -+ { -+ Expression *a = (*arguments)[u]; - TypeArray *ta = (TypeArray *)tb; -+ a = a->inferType(ta->next); -+ (*arguments)[u] = a; - if (tret && !ta->next->equals(a->type)) -- { if (tret->toBasetype()->ty == Tvoid || -+ { -+ if (tret->toBasetype()->ty == Tvoid || - a->implicitConvTo(tret)) - { - a = a->toDelegate(sc, tret); -@@ -1097,7 +1569,8 @@ Type *functionParameters(Loc loc, Scope - break; - } - if (wildmatch) -- { /* Calculate wild matching modifier -+ { -+ /* Calculate wild matching modifier - */ - if (wildmatch & MODconst || wildmatch & (wildmatch - 1)) - wildmatch = MODconst; -@@ -1106,9 +1579,52 @@ Type *functionParameters(Loc loc, Scope - else if (wildmatch & MODwild) - wildmatch = MODwild; - else -- { assert(wildmatch & MODmutable); -+ { -+ assert(wildmatch & MODmutable); - wildmatch = MODmutable; - } -+ -+ if ((wildmatch == MODmutable || wildmatch == MODimmutable) && -+ tf->next->hasWild() && -+ (tf->isref || !tf->next->implicitConvTo(tf->next->immutableOf()))) -+ { -+ if (fd) -+ { -+ /* If the called function may return the reference to -+ * outer inout data, it should be rejected. -+ * -+ * void foo(ref inout(int) x) { -+ * ref inout(int) bar(inout(int)) { return x; } -+ * struct S { ref inout(int) bar() inout { return x; } } -+ * bar(int.init) = 1; // bad! -+ * S().bar() = 1; // bad! -+ * } -+ */ -+ FuncDeclaration *f; -+ if (AggregateDeclaration *ad = fd->isThis()) -+ { -+ f = ad->toParent2()->isFuncDeclaration(); -+ goto Linoutnest; -+ } -+ else if (fd->isNested()) -+ { -+ f = fd->toParent2()->isFuncDeclaration(); -+ Linoutnest: -+ for (; f; f = f->toParent2()->isFuncDeclaration()) -+ { -+ if (((TypeFunction *)f->type)->iswild) -+ goto Linouterr; -+ } -+ } -+ } -+ else if (tf->isWild()) -+ { -+ Linouterr: -+ const char *s = wildmatch == MODmutable ? "mutable" : MODtoChars(wildmatch); -+ error(loc, "modify inout to %s is not allowed inside inout function", s); -+ return Type::terror; -+ } -+ } - } - - assert(nargs >= nparams); -@@ -1128,7 +1644,7 @@ Type *functionParameters(Loc loc, Scope - arg = arg->implicitCastTo(sc, p->type->substWildTo(wildmatch)); - arg = arg->optimize(WANTvalue, p->storageClass & STCref); - } -- else if (p->type != arg->type) -+ else if (!p->type->equals(arg->type)) - { - //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars()); - if (arg->op == TOKtype) -@@ -1150,6 +1666,8 @@ Type *functionParameters(Loc loc, Scope - Type *t = arg->type; - if (!t->isMutable() || !t->isAssignable()) // check blit assignable - arg->error("cannot modify struct %s with immutable members", arg->toChars()); -+ else -+ checkDefCtor(arg->loc, t); - arg = arg->toLvalue(sc, arg); - } - else if (p->storageClass & STClazy) -@@ -1158,30 +1676,9 @@ Type *functionParameters(Loc loc, Scope - } - else - { -- Type *tb = arg->type->toBasetype(); -- if (tb->ty == Tsarray) -- { -- // call copy constructor of each element -- arg = callCpCtor(loc, sc, arg, 1); -- } --#if DMDV2 -- else if (tb->ty == Tstruct) -- { -- if (arg->op == TOKcall && !arg->isLvalue()) -- { -- /* The struct value returned from the function is transferred -- * to the function, so the callee should not call the destructor -- * on it. -- */ -- valueNoDtor(arg); -- } -- else -- { /* Not transferring it, so call the copy constructor -- */ -- arg = callCpCtor(loc, sc, arg, 1); -- } -- } --#endif -+ if (Expression *e = arg->isTemp()) -+ arg = e; -+ arg = arg->isLvalue() ? callCpCtor(sc, arg) : valueNoDtor(arg); - } - - //printf("arg: %s\n", arg->toChars()); -@@ -1247,25 +1744,29 @@ Type *functionParameters(Loc loc, Scope - - // Do not allow types that need destructors - if (arg->type->needsDestruction()) -- { arg->error("cannot pass types that need destruction as variadic arguments"); -+ { -+ arg->error("cannot pass types that need destruction as variadic arguments"); - arg = new ErrorExp(); - } - -+#if 0 -+ arg = arg->isLvalue() ? callCpCtor(sc, arg) : valueNoDtor(arg); -+#else - // Convert static arrays to dynamic arrays - // BUG: I don't think this is right for D2 - Type *tb = arg->type->toBasetype(); - if (tb->ty == Tsarray) -- { TypeSArray *ts = (TypeSArray *)tb; -+ { -+ TypeSArray *ts = (TypeSArray *)tb; - Type *ta = ts->next->arrayOf(); - if (ts->size(arg->loc) == 0) - arg = new NullExp(arg->loc, ta); - else - arg = arg->castTo(sc, ta); - } --#if DMDV2 - if (tb->ty == Tstruct) - { -- arg = callCpCtor(loc, sc, arg, 1); -+ arg = callCpCtor(sc, arg); - } - #endif - -@@ -1298,7 +1799,29 @@ Type *functionParameters(Loc loc, Scope - } - - Type *tret = tf->next; -- if (wildmatch) -+ if (isCtorCall) -+ { -+ //printf("[%s] fd = %s %s, %d %d %d\n", loc.toChars(), fd->toChars(), fd->type->toChars(), -+ // wildmatch, tf->isWild(), fd->isolateReturn()); -+ if (!tthis) -+ { assert(sc->intypeof || global.errors); -+ tthis = fd->isThis()->type->addMod(fd->type->mod); -+ } -+ if (tf->isWild() && !fd->isolateReturn()) -+ { -+ if (wildmatch) -+ tret = tret->substWildTo(wildmatch); -+ if (!tret->implicitConvTo(tthis)) -+ { -+ const char* s1 = tret ->isNaked() ? " mutable" : tret ->modToChars(); -+ const char* s2 = tthis->isNaked() ? " mutable" : tthis->modToChars(); -+ ::error(loc, "inout constructor %s creates%s object, not%s", -+ fd->toPrettyChars(), s1, s2); -+ } -+ } -+ tret = tthis; -+ } -+ else if (wildmatch) - { /* Adjust function return type based on wildmatch - */ - //printf("wildmatch = x%x, tret = %s\n", wildmatch, tret->toChars()); -@@ -1312,7 +1835,7 @@ Type *functionParameters(Loc loc, Scope - * in ( ) if its precedence is less than pr. - */ - --void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr) -+void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, PREC pr) - { - #ifdef DEBUG - if (precedence[e->op] == PREC_zero) -@@ -1336,6 +1859,33 @@ void expToCBuffer(OutBuffer *buf, HdrGen - e->toCBuffer(buf, hgs); - } - -+void sizeToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e) -+{ -+ if (e->type == Type::tsize_t) -+ { -+ Expression *ex = (e->op == TOKcast ? ((CastExp *)e)->e1 : e); -+ ex = ex->optimize(WANTvalue); -+ -+ dinteger_t uval = ex->op == TOKint64 ? ex->toInteger() : (dinteger_t)-1; -+ if ((sinteger_t)uval >= 0) -+ { -+ dinteger_t sizemax; -+ if (Target::ptrsize == 4) -+ sizemax = 0xFFFFFFFFUL; -+ else if (Target::ptrsize == 8) -+ sizemax = 0xFFFFFFFFFFFFFFFFULL; -+ else -+ assert(0); -+ if (uval <= sizemax && uval <= 0x7FFFFFFFFFFFFFFFULL) -+ { -+ buf->printf("%llu", uval); -+ return; -+ } -+ } -+ } -+ expToCBuffer(buf, hgs, e, PREC_assign); -+} -+ - /************************************************** - * Write out argument list to buf. - */ -@@ -1361,14 +1911,14 @@ void argsToCBuffer(OutBuffer *buf, Expre - - void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs) - { -- if (arguments) -- { OutBuffer argbuf; -- -+ if (arguments && arguments->dim) -+ { -+ OutBuffer argbuf; - for (size_t i = 0; i < arguments->dim; i++) -- { Expression *e = (*arguments)[i]; -- -+ { -+ Expression *e = (*arguments)[i]; - if (i) -- buf->writeByte(','); -+ buf->writestring(", "); - argbuf.reset(); - e->type->toCBuffer2(&argbuf, hgs, 0); - buf->write(&argbuf); -@@ -1378,8 +1928,7 @@ void argExpTypesToCBuffer(OutBuffer *buf - - /******************************** Expression **************************/ - --Expression::Expression(Loc loc, enum TOK op, int size) -- : loc(loc) -+Expression::Expression(Loc loc, TOK op, int size) - { - //printf("Expression::Expression(op = %d) this = %p\n", op, this); - this->loc = loc; -@@ -1389,6 +1938,21 @@ Expression::Expression(Loc loc, enum TOK - type = NULL; - } - -+Expression *EXP_CANT_INTERPRET; -+Expression *EXP_CONTINUE_INTERPRET; -+Expression *EXP_BREAK_INTERPRET; -+Expression *EXP_GOTO_INTERPRET; -+Expression *EXP_VOID_INTERPRET; -+ -+void Expression::init() -+{ -+ EXP_CANT_INTERPRET = new ErrorExp(); -+ EXP_CONTINUE_INTERPRET = new ErrorExp(); -+ EXP_BREAK_INTERPRET = new ErrorExp(); -+ EXP_GOTO_INTERPRET = new ErrorExp(); -+ EXP_VOID_INTERPRET = new ErrorExp(); -+} -+ - Expression *Expression::syntaxCopy() - { - //printf("Expression::syntaxCopy()\n"); -@@ -1406,7 +1970,7 @@ Expression *Expression::copy() - if (!size) - { - #ifdef DEBUG -- fprintf(stdmsg, "No expression copy for: %s\n", toChars()); -+ fprintf(stderr, "No expression copy for: %s\n", toChars()); - printf("op = %d\n", op); - dump(0); - #endif -@@ -1414,7 +1978,7 @@ Expression *Expression::copy() - } - e = (Expression *)mem.malloc(size); - //printf("Expression::copy(op = %d) e = %p\n", op, e); -- return (Expression *)memcpy(e, this, size); -+ return (Expression *)memcpy((void*)e, (void*)this, size); - } - - /************************** -@@ -1454,8 +2018,8 @@ Expression *Expression::trySemantic(Scop - - void Expression::print() - { -- fprintf(stdmsg, "%s\n", toChars()); -- fflush(stdmsg); -+ fprintf(stderr, "%s\n", toChars()); -+ fflush(stderr); - } - - char *Expression::toChars() -@@ -1562,11 +2126,7 @@ real_t Expression::toImaginary() - complex_t Expression::toComplex() - { - error("Floating point constant expression expected instead of %s", toChars()); --#ifdef IN_GCC -- return complex_t(real_t(0)); // %% nicer --#else -- return 0.0; --#endif -+ return (complex_t)0.0; - } - - StringExp *Expression::toString() -@@ -1634,7 +2194,9 @@ Expression *Expression::modifiableLvalue - if (type->isMutable()) - { - if (!type->isAssignable()) -- error("cannot modify struct %s %s with immutable members", toChars(), type->toChars()); -+ { error("cannot modify struct %s %s with immutable members", toChars(), type->toChars()); -+ goto Lerror; -+ } - } - else - { -@@ -1653,9 +2215,13 @@ Expression *Expression::modifiableLvalue - { - error("cannot modify %s expression %s", MODtoChars(type->mod), toChars()); - } -+ goto Lerror; - } - } - return toLvalue(sc, e); -+ -+Lerror: -+ return new ErrorExp(); - } - - -@@ -1749,12 +2315,13 @@ void Expression::checkPurity(Scope *sc, - } - - // Find the closest pure parent of the called function -- if (getFuncTemplateDecl(f)) -- { // The closest pure parent of instantiated template function is -+ if (getFuncTemplateDecl(f) && !f->isNested() && -+ f->parent->isTemplateInstance()->enclosing == NULL) -+ { // The closest pure parent of instantiated non-nested template function is - // always itself. -- if (!f->isPure() && outerfunc->setImpure()) -+ if (!f->isPure() && outerfunc->setImpure() && !(sc->flags & SCOPEctfe)) - error("pure function '%s' cannot call impure function '%s'", -- outerfunc->toChars(), f->toChars()); -+ outerfunc->toPrettyChars(), f->toPrettyChars()); - return; - } - FuncDeclaration *calledparent = f; -@@ -1791,7 +2358,8 @@ void Expression::checkPurity(Scope *sc, - // If the caller has a pure parent, then either the called func must be pure, - // OR, they must have the same pure parent. - if (/*outerfunc->isPure() &&*/ // comment out because we deduce purity now -- !f->isPure() && calledparent != outerfunc) -+ !f->isPure() && calledparent != outerfunc && -+ !(sc->flags & SCOPEctfe)) - { - if (outerfunc->setImpure()) - error("pure function '%s' cannot call impure function '%s'", -@@ -1808,10 +2376,9 @@ void Expression::checkPurity(Scope *sc, - /******************************************* - * Accessing variable v. - * Check for purity and safety violations. -- * If ethis is not NULL, then ethis is the 'this' pointer as in ethis.v - */ - --void Expression::checkPurity(Scope *sc, VarDeclaration *v, Expression *ethis) -+void Expression::checkPurity(Scope *sc, VarDeclaration *v) - { - /* Look for purity and safety violations when accessing variable v - * from current function. -@@ -1822,7 +2389,7 @@ void Expression::checkPurity(Scope *sc, - v->ident != Id::ctfe && // magic variable never violates pure and safe - !v->isImmutable() && // always safe and pure to access immutables... - !(v->isConst() && !v->isRef() && (v->isDataseg() || v->isParameter()) && -- v->type->implicitConvTo(v->type->invariantOf())) && -+ v->type->implicitConvTo(v->type->immutableOf())) && - // or const global/parameter values which have no mutable indirections - !(v->storage_class & STCmanifest) // ...or manifest constants - ) -@@ -1839,7 +2406,8 @@ void Expression::checkPurity(Scope *sc, - FuncDeclaration *ff = s->isFuncDeclaration(); - if (!ff) - break; -- if (ff->setImpure() && !msg) -+ // Accessing implicit generated __gate is pure. -+ if (ff->setImpure() && !msg && strcmp(v->ident->toChars(), "__gate")) - { error("pure function '%s' cannot access mutable static data '%s'", - sc->func->toPrettyChars(), v->toChars()); - msg = TRUE; // only need the innermost message -@@ -1848,6 +2416,26 @@ void Expression::checkPurity(Scope *sc, - } - else - { -+ /* Bugzilla 10981: Special case for the contracts of pure virtual function. -+ * Rewrite: -+ * tret foo(int i) pure -+ * in { assert(i); } out { assert(i); } body { ... } -+ * -+ * as: -+ * tret foo(int i) pure { -+ * void __require() pure { assert(i); } // allow accessing to i -+ * void __ensure() pure { assert(i); } // allow accessing to i -+ * __require(); -+ * ... -+ * __ensure(); -+ * } -+ */ -+ if ((sc->func->ident == Id::require || sc->func->ident == Id::ensure) && -+ v->isParameter() && sc->func->parent == v->parent) -+ { -+ return; -+ } -+ - /* Given: - * void f() - * { int fx; -@@ -1892,6 +2480,7 @@ void Expression::checkPurity(Scope *sc, - void Expression::checkSafety(Scope *sc, FuncDeclaration *f) - { - if (sc->func && !sc->intypeof && -+ !(sc->flags & SCOPEctfe) && - !f->isSafe() && !f->isTrusted()) - { - if (sc->func->setUnsafe()) -@@ -1920,8 +2509,12 @@ Expression *Expression::checkToBoolean(S - assert(type); - #endif - -- // Structs can be converted to bool using opCast(bool)() -+ Expression *e = this; -+ Type *t = type; - Type *tb = type->toBasetype(); -+ Type *att = NULL; -+Lagain: -+ // Structs can be converted to bool using opCast(bool)() - if (tb->ty == Tstruct) - { AggregateDeclaration *ad = ((TypeStruct *)tb)->sym; - /* Don't really need to check for opCast first, but by doing so we -@@ -1930,26 +2523,29 @@ Expression *Expression::checkToBoolean(S - Dsymbol *fd = search_function(ad, Id::cast); - if (fd) - { -- Expression *e = new CastExp(loc, this, Type::tbool); -+ e = new CastExp(loc, e, Type::tbool); - e = e->semantic(sc); - return e; - } - - // Forward to aliasthis. -- if (ad->aliasthis) -+ if (ad->aliasthis && tb != att) - { -- Expression *e = resolveAliasThis(sc, this); -- e = e->checkToBoolean(sc); -- return e; -+ if (!att && tb->checkAliasThisRec()) -+ att = tb; -+ e = resolveAliasThis(sc, e); -+ t = e->type; -+ tb = e->type->toBasetype(); -+ goto Lagain; - } - } - -- if (!type->checkBoolean()) -- { if (type->toBasetype() != Type::terror) -- error("expression %s of type %s does not have a boolean value", toChars(), type->toChars()); -+ if (!t->checkBoolean()) -+ { if (tb != Type::terror) -+ error("expression %s of type %s does not have a boolean value", toChars(), t->toChars()); - return new ErrorExp(); - } -- return this; -+ return e; - } - - /**************************** -@@ -2015,7 +2611,7 @@ int Expression::isBit() - } - - /**************************************** -- * Resolve __LINE__ and __FILE__ to loc. -+ * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__ to loc. - */ - - Expression *Expression::resolveLoc(Loc loc, Scope *sc) -@@ -2053,20 +2649,25 @@ Expression *Expression::isTemp() - { - //printf("isTemp() %s\n", toChars()); - if (op == TOKcomma) -- { CommaExp *ec = (CommaExp *)this; -+ { -+ CommaExp *ec = (CommaExp *)this; - if (ec->e1->op == TOKdeclaration && - ec->e2->op == TOKvar) -- { DeclarationExp *de = (DeclarationExp *)ec->e1; -+ { -+ DeclarationExp *de = (DeclarationExp *)ec->e1; - VarExp *ve = (VarExp *)ec->e2; -- if (ve->var == de->declaration && ve->var->storage_class & STCctfe) -- { VarDeclaration *v = ve->var->isVarDeclaration(); -+ if (de->declaration == ve->var && ve->var->storage_class & STCctfe) -+ { -+ VarDeclaration *v = ve->var->isVarDeclaration(); - if (v && v->init) - { - ExpInitializer *ei = v->init->isExpInitializer(); - if (ei) -- { Expression *e = ei->exp; -+ { -+ Expression *e = ei->exp; - if (e->op == TOKconstruct) -- { ConstructExp *ce = (ConstructExp *)e; -+ { -+ ConstructExp *ce = (ConstructExp *)e; - if (ce->e1->op == TOKvar && ((VarExp *)ce->e1)->var == ve->var) - e = ce->e2; - } -@@ -2108,21 +2709,26 @@ IntegerExp::IntegerExp(Loc loc, dinteger - } - - IntegerExp::IntegerExp(dinteger_t value) -- : Expression(0, TOKint64, sizeof(IntegerExp)) -+ : Expression(Loc(), TOKint64, sizeof(IntegerExp)) - { - this->type = Type::tint32; - this->value = value; - } - --int IntegerExp::equals(Object *o) --{ IntegerExp *ne; -- -- if (this == o || -- (((Expression *)o)->op == TOKint64 && -- ((ne = (IntegerExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && -- value == ne->value)) -- return 1; -- return 0; -+bool IntegerExp::equals(RootObject *o) -+{ -+ if (this == o) -+ return true; -+ if (((Expression *)o)->op == TOKint64) -+ { -+ IntegerExp *ne = (IntegerExp *)o; -+ if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && -+ value == ne->value) -+ { -+ return true; -+ } -+ } -+ return false; - } - - char *IntegerExp::toChars() -@@ -2209,7 +2815,7 @@ real_t IntegerExp::toImaginary() - - complex_t IntegerExp::toComplex() - { -- return toReal(); -+ return (complex_t)toReal(); - } - - int IntegerExp::isBool(int result) -@@ -2390,7 +2996,7 @@ void IntegerExp::toMangleBuffer(OutBuffe - */ - - ErrorExp::ErrorExp() -- : IntegerExp(0, 0, Type::terror) -+ : IntegerExp(Loc(), 0, Type::terror) - { - op = TOKerror; - } -@@ -2417,31 +3023,29 @@ RealExp::RealExp(Loc loc, real_t value, - - char *RealExp::toChars() - { -+ /** sizeof(value)*3 is because each byte of mantissa is max -+ of 256 (3 characters). The string will be "-M.MMMMe-4932". -+ (ie, 8 chars more than mantissa). Plus one for trailing \0. -+ Plus one for rounding. */ - char buffer[sizeof(value) * 3 + 8 + 1 + 1]; - - ld_sprint(buffer, 'g', value); -+ - if (type->isimaginary()) - strcat(buffer, "i"); -- assert(strlen(buffer) < sizeof(buffer)); -+ -+ assert(strlen(buffer) < sizeof(buffer) / sizeof(buffer[0])); - return mem.strdup(buffer); - } - - dinteger_t RealExp::toInteger() - { --#ifdef IN_GCC -- return (sinteger_t) toReal().toInt(); --#else - return (sinteger_t) toReal(); --#endif - } - - uinteger_t RealExp::toUInteger() - { --#ifdef IN_GCC -- return (uinteger_t) toReal().toInt(); --#else - return (uinteger_t) toReal(); --#endif - } - - real_t RealExp::toReal() -@@ -2471,29 +3075,24 @@ complex_t RealExp::toComplex() - - int RealEquals(real_t x1, real_t x2) - { --#ifndef IN_GCC - return (Port::isNan(x1) && Port::isNan(x2)) || -- /* In some cases, the REALPAD bytes get garbage in them, -- * so be sure and ignore them. -- */ -- memcmp(&x1, &x2, Target::realsize - Target::realpad) == 0; --#else -- return (Port::isNan(x1) && Port::isNan(x2)) || -- x1.isIdenticalTo(x2); --#endif -+ Port::fequal(x1, x2); - } - --int RealExp::equals(Object *o) --{ RealExp *ne; -- -- if (this == o || -- (((Expression *)o)->op == TOKfloat64 && -- ((ne = (RealExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && -- RealEquals(value, ne->value) -- ) -- ) -- return 1; -- return 0; -+bool RealExp::equals(RootObject *o) -+{ -+ if (this == o) -+ return true; -+ if (((Expression *)o)->op == TOKfloat64) -+ { -+ RealExp *ne = (RealExp *)o; -+ if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && -+ RealEquals(value, ne->value)) -+ { -+ return true; -+ } -+ } -+ return false; - } - - Expression *RealExp::semantic(Scope *sc) -@@ -2507,12 +3106,8 @@ Expression *RealExp::semantic(Scope *sc) - - int RealExp::isBool(int result) - { --#ifdef IN_GCC -- return result ? (! value.isZero()) : (value.isZero()); --#else - return result ? (value != 0) - : (value == 0); --#endif - } - - void floatToBuffer(OutBuffer *buf, Type *type, const real_t& value) -@@ -2525,35 +3120,14 @@ void floatToBuffer(OutBuffer *buf, Type - * "-1.18973e+4932\0".length == 17 - * "-0xf.fffffffffffffffp+16380\0".length == 28 - */ --#ifdef IN_GCC -- char buffer[48]; -- real_t parsed_value; -- -- value.format(buffer, sizeof(buffer)); -- parsed_value = real_t::parse(buffer, real_t::LongDouble); -- if (parsed_value.isIdenticalTo(value)) -- buf->writestring(buffer); -- else -- { -- value.formatHex(buffer, sizeof(buffer)); -- buf->writestring(buffer); -- } --#else - char buffer[32]; - ld_sprint(buffer, 'g', value); -- assert(strlen(buffer) < sizeof(buffer)); --#if _WIN32 && __DMC__ -- char *save = __locale_decpoint; -- __locale_decpoint = "."; -- real_t r = strtold(buffer, NULL); -- __locale_decpoint = save; --#else -- real_t r = strtold(buffer, NULL); --#endif -+ assert(strlen(buffer) < sizeof(buffer) / sizeof(buffer[0])); -+ -+ real_t r = Port::strtold(buffer, NULL); - if (r != value) // if exact duplication - ld_sprint(buffer, 'a', value); - buf->writestring(buffer); --#endif - - if (type) - { -@@ -2600,15 +3174,13 @@ void realToMangleBuffer(OutBuffer *buf, - - if (Port::isNan(value)) - buf->writestring("NAN"); // no -NAN bugs --#ifdef IN_GCC - else if (Port::isInfinity(value)) -- buf->writestring(value.isNegative() ? "NINF" : "INF"); --#endif -+ buf->writestring(value < 0 ? "NINF" : "INF"); - else - { -- char buffer[32]; -+ char buffer[36]; - int n = ld_sprint(buffer, 'A', value); -- assert(n > 0 && n < sizeof(buffer)); -+ assert(n > 0 && n < sizeof(buffer) / sizeof(buffer[0])); - for (int i = 0; i < n; i++) - { char c = buffer[i]; - -@@ -2654,32 +3226,25 @@ ComplexExp::ComplexExp(Loc loc, complex_ - char *ComplexExp::toChars() - { - char buffer[sizeof(value) * 3 + 8 + 1]; -+ - char buf1[sizeof(value) * 3 + 8 + 1]; - char buf2[sizeof(value) * 3 + 8 + 1]; - - ld_sprint(buf1, 'g', creall(value)); - ld_sprint(buf2, 'g', cimagl(value)); - sprintf(buffer, "(%s+%si)", buf1, buf2); -- assert(strlen(buffer) < sizeof(buffer)); -+ assert(strlen(buffer) < sizeof(buffer) / sizeof(buffer[0])); - return mem.strdup(buffer); - } - - dinteger_t ComplexExp::toInteger() - { --#ifdef IN_GCC -- return (sinteger_t) toReal().toInt(); --#else - return (sinteger_t) toReal(); --#endif - } - - uinteger_t ComplexExp::toUInteger() - { --#ifdef IN_GCC -- return (uinteger_t) toReal().toInt(); --#else - return (uinteger_t) toReal(); --#endif - } - - real_t ComplexExp::toReal() -@@ -2697,18 +3262,21 @@ complex_t ComplexExp::toComplex() - return value; - } - --int ComplexExp::equals(Object *o) --{ ComplexExp *ne; -- -- if (this == o || -- (((Expression *)o)->op == TOKcomplex80 && -- ((ne = (ComplexExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && -- RealEquals(creall(value), creall(ne->value)) && -- RealEquals(cimagl(value), cimagl(ne->value)) -- ) -- ) -- return 1; -- return 0; -+bool ComplexExp::equals(RootObject *o) -+{ -+ if (this == o) -+ return true; -+ if (((Expression *)o)->op == TOKcomplex80) -+ { -+ ComplexExp *ne = (ComplexExp *)o; -+ if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && -+ RealEquals(creall(value), creall(ne->value)) && -+ RealEquals(cimagl(value), cimagl(ne->value))) -+ { -+ return true; -+ } -+ } -+ return false; - } - - Expression *ComplexExp::semantic(Scope *sc) -@@ -2733,19 +3301,11 @@ void ComplexExp::toCBuffer(OutBuffer *bu - /* Print as: - * (re+imi) - */ --#ifdef IN_GCC -- char buf1[sizeof(value) * 3 + 8 + 1]; -- char buf2[sizeof(value) * 3 + 8 + 1]; -- creall(value).format(buf1, sizeof(buf1)); -- cimagl(value).format(buf2, sizeof(buf2)); -- buf->printf("(%s+%si)", buf1, buf2); --#else - buf->writeByte('('); - floatToBuffer(buf, type, creall(value)); - buf->writeByte('+'); - floatToBuffer(buf, type, cimagl(value)); - buf->writestring("i)"); --#endif - } - - void ComplexExp::toMangleBuffer(OutBuffer *buf) -@@ -2777,11 +3337,13 @@ Expression *IdentifierExp::semantic(Scop - s = sc->search(loc, ident, &scopesym); - if (s) - { Expression *e; -- WithScopeSymbol *withsym; -+ -+ if (s->errors) -+ return new ErrorExp(); - - /* See if the symbol was a member of an enclosing 'with' - */ -- withsym = scopesym->isWithScopeSymbol(); -+ WithScopeSymbol *withsym = scopesym->isWithScopeSymbol(); - if (withsym) - { - #if DMDV2 -@@ -2829,12 +3391,13 @@ Expression *IdentifierExp::semantic(Scop - */ - FuncDeclaration *f = s->isFuncDeclaration(); - if (f) -- { TemplateDeclaration *tempdecl = getFuncTemplateDecl(f); -- if (tempdecl) -+ { -+ TemplateDeclaration *td = getFuncTemplateDecl(f); -+ if (td) - { -- if (tempdecl->overroot) // if not start of overloaded list of TemplateDeclaration's -- tempdecl = tempdecl->overroot; // then get the start -- e = new TemplateExp(loc, tempdecl); -+ if (td->overroot) // if not start of overloaded list of TemplateDeclaration's -+ td = td->overroot; // then get the start -+ e = new TemplateExp(loc, td, f); - e = e->semantic(sc); - return e; - } -@@ -2914,7 +3477,7 @@ DollarExp::DollarExp(Loc loc) - - /******************************** DsymbolExp **************************/ - --DsymbolExp::DsymbolExp(Loc loc, Dsymbol *s, int hasOverloads) -+DsymbolExp::DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads) - : Expression(loc, TOKdsymbol, sizeof(DsymbolExp)) - { - this->s = s; -@@ -2942,8 +3505,6 @@ Lagain: - - //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars()); - //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind()); -- if (type && !s->needThis()) -- return this; - if (!s->isFuncDeclaration()) // functions are checked after overloading - checkDeprecated(sc, s); - Dsymbol *olds = s; -@@ -2974,10 +3535,7 @@ Lagain: - em = s->isEnumMember(); - if (em) - { -- e = em->value; -- e->loc = loc; -- e = e->semantic(sc); -- return e; -+ return em->getVarExp(loc, sc); - } - v = s->isVarDeclaration(); - if (v) -@@ -2988,14 +3546,21 @@ Lagain: - v->semantic(v->scope); - type = v->type; - if (!v->type) -- { error("forward reference of %s %s", v->kind(), v->toChars()); -+ { error("forward reference of %s %s", s->kind(), s->toChars()); - return new ErrorExp(); - } - } - - if ((v->storage_class & STCmanifest) && v->init) - { -- e = v->init->toExpression(); -+ if (v->scope) -+ { -+ v->inuse++; -+ v->init = v->init->semantic(v->scope, v->type, INITinterpret); -+ v->scope = NULL; -+ v->inuse--; -+ } -+ e = v->init->toExpression(v->type); - if (!e) - { error("cannot make expression out of initializer for %s", v->toChars()); - return new ErrorExp(); -@@ -3024,11 +3589,6 @@ Lagain: - if (!f->functionSemantic()) - return new ErrorExp(); - -- if (f->isUnitTestDeclaration()) -- { -- error("cannot call unittest function %s", toChars()); -- return new ErrorExp(); -- } - if (!f->type->deco) - { - error("forward reference to %s", toChars()); -@@ -3041,7 +3601,7 @@ Lagain: - o = s->isOverloadSet(); - if (o) - { //printf("'%s' is an overload set\n", o->toChars()); -- return new OverExp(o); -+ return new OverExp(loc, o); - } - imp = s->isImport(); - if (imp) -@@ -3080,24 +3640,6 @@ Lagain: - TupleDeclaration *tup = s->isTupleDeclaration(); - if (tup) - { -- for (size_t i = 0; i < tup->objects->dim; i++) -- { -- Dsymbol *sa = getDsymbol((*tup->objects)[i]); -- if (sa && sa->needThis()) -- { -- if (hasThis(sc) --#if DMDV2 -- && !sa->isFuncDeclaration() --#endif -- ) -- { -- // Supply an implicit 'this', as in -- // this.ident -- (*tup->objects)[i] = new DotVarExp(loc, new ThisExp(loc), sa->isDeclaration()); -- } -- } -- } -- - e = new TupleExp(loc, tup); - e = e->semantic(sc); - return e; -@@ -3123,7 +3665,8 @@ Lagain: - Dsymbol *p = td->toParent2(); - FuncDeclaration *fdthis = hasThis(sc); - AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL; -- if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad) -+ if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad && -+ (td->scope->stc & STCstatic) == 0) - { - e = new DotTemplateExp(loc, new ThisExp(loc), td); - } -@@ -3182,7 +3725,7 @@ Expression *ThisExp::semantic(Scope *sc) - /* Special case for typeof(this) and typeof(super) since both - * should work even if they are not inside a non-static member function - */ -- if (!fd && sc->intypeof) -+ if (!fd && sc->intypeof == 1) - { - // Find enclosing struct or class - for (Dsymbol *s = sc->getStructClassScope(); 1; s = s->parent) -@@ -3278,7 +3821,7 @@ Expression *SuperExp::semantic(Scope *sc - /* Special case for typeof(this) and typeof(super) since both - * should work even if they are not inside a non-static member function - */ -- if (!fd && sc->intypeof) -+ if (!fd && sc->intypeof == 1) - { - // Find enclosing class - for (Dsymbol *s = sc->getStructClassScope(); 1; s = s->parent) -@@ -3356,15 +3899,15 @@ NullExp::NullExp(Loc loc, Type *type) - this->type = type; - } - --int NullExp::equals(Object *o) -+bool NullExp::equals(RootObject *o) - { - if (o && o->dyncast() == DYNCAST_EXPRESSION) -- { Expression *e = (Expression *)o; -- -+ { -+ Expression *e = (Expression *)o; - if (e->op == TOKnull) -- return TRUE; -+ return true; - } -- return FALSE; -+ return false; - } - - Expression *NullExp::semantic(Scope *sc) -@@ -3428,7 +3971,7 @@ StringExp::StringExp(Loc loc, void *stri - this->ownedByCtfe = false; - } - --StringExp::StringExp(Loc loc, void *string, size_t len, unsigned char postfix) -+StringExp::StringExp(Loc loc, void *string, size_t len, utf8_t postfix) - : Expression(loc, TOKstring, sizeof(StringExp)) - { - this->string = string; -@@ -3447,18 +3990,18 @@ Expression *StringExp::syntaxCopy() - } - #endif - --int StringExp::equals(Object *o) -+bool StringExp::equals(RootObject *o) - { - //printf("StringExp::equals('%s') %s\n", o->toChars(), toChars()); - if (o && o->dyncast() == DYNCAST_EXPRESSION) -- { Expression *e = (Expression *)o; -- -+ { -+ Expression *e = (Expression *)o; - if (e->op == TOKstring) - { - return compare(o) == 0; - } - } -- return FALSE; -+ return false; - } - - Expression *StringExp::semantic(Scope *sc) -@@ -3478,7 +4021,7 @@ Expression *StringExp::semantic(Scope *s - case 'd': - for (u = 0; u < len;) - { -- p = utf_decodeChar((unsigned char *)string, len, &u, &c); -+ p = utf_decodeChar((utf8_t *)string, len, &u, &c); - if (p) - { error("%s", p); - return new ErrorExp(); -@@ -3493,14 +4036,14 @@ Expression *StringExp::semantic(Scope *s - len = newlen; - sz = 4; - //type = new TypeSArray(Type::tdchar, new IntegerExp(loc, len, Type::tindex)); -- type = new TypeDArray(Type::tdchar->invariantOf()); -+ type = new TypeDArray(Type::tdchar->immutableOf()); - committed = 1; - break; - - case 'w': - for (u = 0; u < len;) - { -- p = utf_decodeChar((unsigned char *)string, len, &u, &c); -+ p = utf_decodeChar((utf8_t *)string, len, &u, &c); - if (p) - { error("%s", p); - return new ErrorExp(); -@@ -3517,7 +4060,7 @@ Expression *StringExp::semantic(Scope *s - len = newlen; - sz = 2; - //type = new TypeSArray(Type::twchar, new IntegerExp(loc, len, Type::tindex)); -- type = new TypeDArray(Type::twchar->invariantOf()); -+ type = new TypeDArray(Type::twchar->immutableOf()); - committed = 1; - break; - -@@ -3525,11 +4068,11 @@ Expression *StringExp::semantic(Scope *s - committed = 1; - default: - //type = new TypeSArray(Type::tchar, new IntegerExp(loc, len, Type::tindex)); -- type = new TypeDArray(Type::tchar->invariantOf()); -+ type = new TypeDArray(Type::tchar->immutableOf()); - break; - } - type = type->semantic(loc, sc); -- //type = type->invariantOf(); -+ //type = type->immutableOf(); - //printf("type = %s\n", type->toChars()); - } - return this; -@@ -3550,7 +4093,7 @@ size_t StringExp::length() - case 1: - for (size_t u = 0; u < len;) - { -- p = utf_decodeChar((unsigned char *)string, len, &u, &c); -+ p = utf_decodeChar((utf8_t *)string, len, &u, &c); - if (p) - { error("%s", p); - return 0; -@@ -3607,7 +4150,7 @@ StringExp *StringExp::toUTF8(Scope *sc) - return this; - } - --int StringExp::compare(Object *obj) -+int StringExp::compare(RootObject *obj) - { - //printf("StringExp::compare()\n"); - // Used to sort case statement expressions so we can do an efficient lookup -@@ -3674,13 +4217,14 @@ int StringExp::isLvalue() - /* string literal is rvalue in default, but - * conversion to reference of static array is only allowed. - */ -- return 0; -+ return (type && type->toBasetype()->ty == Tsarray); - } - - Expression *StringExp::toLvalue(Scope *sc, Expression *e) - { -- //printf("StringExp::toLvalue(%s)\n", toChars()); -- return this; -+ //printf("StringExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL); -+ return (type && type->toBasetype()->ty == Tsarray) -+ ? this : Expression::toLvalue(sc, e); - } - - Expression *StringExp::modifiableLvalue(Scope *sc, Expression *e) -@@ -3695,7 +4239,7 @@ unsigned StringExp::charAt(size_t i) - switch (sz) - { - case 1: -- value = ((unsigned char *)string)[i]; -+ value = ((utf8_t *)string)[i]; - break; - - case 2: -@@ -3754,7 +4298,7 @@ void StringExp::toMangleBuffer(OutBuffer - const char *p; - unsigned c; - size_t u; -- unsigned char *q; -+ utf8_t *q; - size_t qlen; - - /* Write string in UTF-8 format -@@ -3762,7 +4306,7 @@ void StringExp::toMangleBuffer(OutBuffer - switch (sz) - { case 1: - m = 'a'; -- q = (unsigned char *)string; -+ q = (utf8_t *)string; - qlen = len; - break; - case 2: -@@ -3798,12 +4342,12 @@ void StringExp::toMangleBuffer(OutBuffer - buf->writeByte(m); - buf->printf("%d_", (int)qlen); // nbytes <= 11 - -- for (unsigned char *p = buf->data + buf->offset, *pend = p + 2 * qlen; -+ for (utf8_t *p = buf->data + buf->offset, *pend = p + 2 * qlen; - p < pend; p += 2, ++q) - { -- unsigned char hi = *q >> 4 & 0xF; -+ utf8_t hi = *q >> 4 & 0xF; - p[0] = (hi < 10 ? hi + '0' : hi - 10 + 'a'); -- unsigned char lo = *q & 0xF; -+ utf8_t lo = *q & 0xF; - p[1] = (lo < 10 ? lo + '0' : lo - 10 + 'a'); - } - buf->offset += 2 * qlen; -@@ -3828,6 +4372,29 @@ ArrayLiteralExp::ArrayLiteralExp(Loc loc - this->ownedByCtfe = false; - } - -+bool ArrayLiteralExp::equals(RootObject *o) -+{ -+ if (this == o) -+ return true; -+ if (o && o->dyncast() == DYNCAST_EXPRESSION && -+ ((Expression *)o)->op == TOKarrayliteral) -+ { -+ ArrayLiteralExp *ae = (ArrayLiteralExp *)o; -+ if (elements->dim != ae->elements->dim) -+ return false; -+ for (size_t i = 0; i < elements->dim; i++) -+ { -+ Expression *e1 = (*elements)[i]; -+ Expression *e2 = (*ae->elements)[i]; -+ if (e1 != e2 && -+ (!e1 || !e2 || !e1->equals(e2))) -+ return false; -+ } -+ return true; -+ } -+ return false; -+} -+ - Expression *ArrayLiteralExp::syntaxCopy() - { - return new ArrayLiteralExp(loc, arraySyntaxCopy(elements)); -@@ -3877,23 +4444,31 @@ StringExp *ArrayLiteralExp::toString() - if (telem == Tchar || telem == Twchar || telem == Tdchar || - (telem == Tvoid && (!elements || elements->dim == 0))) - { -+ unsigned char sz = 1; -+ if (telem == Twchar) sz = 2; -+ else if (telem == Tdchar) sz = 4; -+ - OutBuffer buf; - if (elements) -+ { - for (int i = 0; i < elements->dim; ++i) - { - Expression *ch = (*elements)[i]; - if (ch->op != TOKint64) - return NULL; -- buf.writeUTF8(ch->toInteger()); -+ if (sz == 1) buf.writebyte(ch->toInteger()); -+ else if (sz == 2) buf.writeword(ch->toInteger()); -+ else buf.write4(ch->toInteger()); - } -- buf.writebyte(0); -- -- char prefix = 'c'; -- if (telem == Twchar) prefix = 'w'; -- else if (telem == Tdchar) prefix = 'd'; -+ } -+ char prefix; -+ if (sz == 1) { prefix = 'c'; buf.writebyte(0); } -+ else if (sz == 2) { prefix = 'w'; buf.writeword(0); } -+ else { prefix = 'd'; buf.write4(0); } - -- const size_t len = buf.offset - 1; -+ const size_t len = buf.offset / sz - 1; - StringExp *se = new StringExp(loc, buf.extractData(), len, prefix); -+ se->sz = sz; - se->type = type; - return se; - } -@@ -3985,7 +4560,7 @@ void AssocArrayLiteralExp::toCBuffer(Out - Expression *value = (*values)[i]; - - if (i) -- buf->writeByte(','); -+ buf->writestring(", "); - expToCBuffer(buf, hgs, key, PREC_assign); - buf->writeByte(':'); - expToCBuffer(buf, hgs, value, PREC_assign); -@@ -4023,18 +4598,46 @@ StructLiteralExp::StructLiteralExp(Loc l - this->soffset = 0; - this->fillHoles = 1; - this->ownedByCtfe = false; -- this->ctorinit = 0; -+ this->origin = this; -+ this->stageflags = 0; -+ this->inlinecopy = NULL; - //printf("StructLiteralExp::StructLiteralExp(%s)\n", toChars()); - } - -+bool StructLiteralExp::equals(RootObject *o) -+{ -+ if (this == o) -+ return true; -+ if (o && o->dyncast() == DYNCAST_EXPRESSION && -+ ((Expression *)o)->op == TOKstructliteral) -+ { -+ StructLiteralExp *se = (StructLiteralExp *)o; -+ if (sd != se->sd) -+ return false; -+ if (elements->dim != se->elements->dim) -+ return false; -+ for (size_t i = 0; i < elements->dim; i++) -+ { -+ Expression *e1 = (*elements)[i]; -+ Expression *e2 = (*se->elements)[i]; -+ if (e1 != e2 && -+ (!e1 || !e2 || !e1->equals(e2))) -+ return false; -+ } -+ return true; -+ } -+ return false; -+} -+ - Expression *StructLiteralExp::syntaxCopy() - { -- return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), stype); -+ StructLiteralExp *exp = new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), stype); -+ exp->origin = this; -+ return exp; - } - - Expression *StructLiteralExp::semantic(Scope *sc) --{ Expression *e; -- -+{ - #if LOGSEMANTIC - printf("StructLiteralExp::semantic('%s')\n", toChars()); - #endif -@@ -4044,19 +4647,24 @@ Expression *StructLiteralExp::semantic(S - sd->size(loc); - if (sd->sizeok != SIZEOKdone) - return new ErrorExp(); -- size_t nfields = sd->fields.dim - sd->isnested; -+ size_t nfields = sd->fields.dim - sd->isNested(); - - elements = arrayExpressionSemantic(elements, sc); // run semantic() on each element - expandTuples(elements); - size_t offset = 0; - for (size_t i = 0; i < elements->dim; i++) -- { e = (*elements)[i]; -+ { -+ Expression *e = (*elements)[i]; - if (!e) - continue; - - e = resolveProperties(sc, e); - if (i >= nfields) - { -+ if (i == sd->fields.dim - 1 && sd->isNested() && e->op == TOKnull) -+ { // CTFE sometimes creates null as hidden pointer; we'll allow this. -+ continue; -+ } - #if 0 - for (size_t i = 0; i < sd->fields.dim; i++) - printf("[%d] = %s\n", i, sd->fields[i]->toChars()); -@@ -4064,11 +4672,10 @@ Expression *StructLiteralExp::semantic(S - error("more initializers than fields (%d) of %s", nfields, sd->toChars()); - return new ErrorExp(); - } -- Dsymbol *s = sd->fields[i]; -- VarDeclaration *v = s->isVarDeclaration(); -- assert(v); -+ VarDeclaration *v = sd->fields[i]; - if (v->offset < offset) -- { error("overlapping initialization for %s", v->toChars()); -+ { -+ error("overlapping initialization for %s", v->toChars()); - return new ErrorExp(); - } - offset = v->offset + v->type->size(); -@@ -4078,7 +4685,8 @@ Expression *StructLiteralExp::semantic(S - telem = telem->addMod(stype->mod); - Type *origType = telem; - while (!e->implicitConvTo(telem) && telem->toBasetype()->ty == Tsarray) -- { /* Static array initialization, as in: -+ { -+ /* Static array initialization, as in: - * T[3][5] = e; - */ - telem = telem->toBasetype()->nextOf(); -@@ -4091,55 +4699,22 @@ Expression *StructLiteralExp::semantic(S - if (e->op == TOKerror) - return e; - -- (*elements)[i] = e; -+ (*elements)[i] = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e); - } - - /* Fill out remainder of elements[] with default initializers for fields[] - */ -- for (size_t i = elements->dim; i < nfields; i++) -- { Dsymbol *s = sd->fields[i]; -- VarDeclaration *v = s->isVarDeclaration(); -- assert(v); -- assert(!v->isThisDeclaration()); -- -- if (v->offset < offset) -- { e = NULL; -- sd->hasUnions = 1; -- } -- else -- { -- if (v->init) -- { if (v->init->isVoidInitializer()) -- e = NULL; -- else -- { e = v->init->toExpression(); -- if (!e) -- { error("cannot make expression out of initializer for %s", v->toChars()); -- return new ErrorExp(); -- } -- else if (v->scope) -- { // Do deferred semantic analysis -- Initializer *i2 = v->init->syntaxCopy(); -- i2 = i2->semantic(v->scope, v->type, INITinterpret); -- e = i2->toExpression(); -- // remove v->scope (see bug 3426) -- // but not if gagged, for we might be called again. -- if (!global.gag) -- { v->scope = NULL; -- v->init = i2; // save result -- } -- } -- } -- } -- else if (v->type->needsNested() && ctorinit) -- e = v->type->defaultInit(loc); -- else -- e = v->type->defaultInitLiteral(loc); -- offset = v->offset + v->type->size(); -- } -- elements->push(e); -+ Expression *e = fill(false); -+ if (e->op == TOKerror) -+ { -+ /* An error in the initializer needs to be recorded as an error -+ * in the enclosing function or template, since the initializer -+ * will be part of the stuct declaration. -+ */ -+ global.increaseErrorCount(); -+ return e; - } -- -+ assert(e == this); - type = stype ? stype : sd->type; - - /* If struct requires a destructor, rewrite as: -@@ -4149,7 +4724,7 @@ Expression *StructLiteralExp::semantic(S - if (sd->dtor && sc->func) - { - Identifier *idtmp = Lexer::uniqueId("__sl"); -- VarDeclaration *tmp = new VarDeclaration(loc, type, idtmp, new ExpInitializer(0, this)); -+ VarDeclaration *tmp = new VarDeclaration(loc, type, idtmp, new ExpInitializer(Loc(), this)); - tmp->storage_class |= STCctfe; - Expression *ae = new DeclarationExp(loc, tmp); - Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp)); -@@ -4160,6 +4735,115 @@ Expression *StructLiteralExp::semantic(S - return this; - } - -+Expression *StructLiteralExp::fill(bool ctorinit) -+{ -+ assert(sd && sd->sizeok == SIZEOKdone); -+ size_t nfields = sd->fields.dim - sd->isNested(); -+ -+ size_t dim = elements->dim; -+ elements->setDim(nfields); -+ for (size_t i = dim; i < nfields; i++) -+ (*elements)[i] = NULL; -+ -+ // Fill in missing any elements with default initializers -+ for (size_t i = 0; i < nfields; i++) -+ { -+ if ((*elements)[i]) -+ continue; -+ VarDeclaration *vd = sd->fields[i]; -+ VarDeclaration *vx = vd; -+ if (vd->init && vd->init->isVoidInitializer()) -+ vx = NULL; -+ // Find overlapped fields with the hole [vd->offset .. vd->offset->size()]. -+ size_t fieldi = i; -+ for (size_t j = 0; j < nfields; j++) -+ { -+ if (i == j) -+ continue; -+ VarDeclaration *v2 = sd->fields[j]; -+ if (v2->init && v2->init->isVoidInitializer()) -+ continue; -+ -+ bool overlap = (vd->offset < v2->offset + v2->type->size() && -+ v2->offset < vd->offset + vd->type->size()); -+ if (!overlap) -+ continue; -+ -+ sd->hasUnions = 1; // note that directly unrelated... -+ -+ if ((*elements)[j]) -+ { -+ vx = NULL; -+ break; -+ } -+ -+#if 1 -+ /* Prefer first found non-void-initialized field -+ * union U { int a; int b = 2; } -+ * U u; // Error: overlapping initialization for field a and b -+ */ -+ if (!vx) -+ vx = v2, fieldi = j; -+ else if (v2->init) -+ { -+ error("overlapping initialization for field %s and %s", -+ v2->toChars(), vd->toChars()); -+ } -+#else // fix Bugzilla 1432 -+ /* Prefer explicitly initialized field -+ * union U { int a; int b = 2; } -+ * U u; // OK (u.b == 2) -+ */ -+ if (!vx || !vx->init && v2->init) -+ vx = v2, fieldi = j; -+ else if (vx != vd && -+ !(vx->offset < v2->offset + v2->type->size() && -+ v2->offset < vx->offset + vx->type->size())) -+ { -+ // Both vx and v2 fills vd, but vx and v2 does not overlap -+ } -+ else if (vx->init && v2->init) -+ { -+ error("overlapping default initialization for field %s and %s", -+ v2->toChars(), vd->toChars()); -+ } -+ else -+ assert(vx->init || !vx->init && !v2->init); -+#endif -+ } -+ if (vx) -+ { -+ Expression *e; -+ if (vx->init) -+ { -+ assert(!vx->init->isVoidInitializer()); -+ e = vx->getConstInitializer(false); -+ } -+ else -+ { -+ if ((vx->storage_class & STCnodefaultctor) && !ctorinit) -+ { -+ error("field %s.%s must be initialized because it has no default constructor", -+ sd->type->toChars(), vx->toChars()); -+ } -+ if (vx->type->needsNested() && ctorinit) -+ e = vx->type->defaultInit(loc); -+ else -+ e = vx->type->defaultInitLiteral(loc); -+ } -+ (*elements)[fieldi] = e; -+ } -+ } -+ -+ for (size_t i = 0; i < elements->dim; i++) -+ { -+ Expression *e = (*elements)[i]; -+ if (e && e->op == TOKerror) -+ return e; -+ } -+ return this; -+} -+ - /************************************** - * Gets expression at offset of type. - * Returns NULL if not found. -@@ -4252,7 +4936,21 @@ void StructLiteralExp::toCBuffer(OutBuff - { - buf->writestring(sd->toChars()); - buf->writeByte('('); -- argsToCBuffer(buf, elements, hgs); -+ -+ // CTFE can generate struct literals that contain an AddrExp pointing -+ // to themselves, need to avoid infinite recursion: -+ // struct S { this(int){ this.s = &this; } S* s; } -+ // const foo = new S(0); -+ if (stageflags & stageToCBuffer) -+ buf->writestring(""); -+ else -+ { -+ int old = stageflags; -+ stageflags |= stageToCBuffer; -+ argsToCBuffer(buf, elements, hgs); -+ stageflags = old; -+ } -+ - buf->writeByte(')'); - } - -@@ -4278,7 +4976,7 @@ void StructLiteralExp::toMangleBuffer(Ou - * cast(foo).size - */ - --Expression *typeDotIdExp(Loc loc, Type *type, Identifier *ident) -+DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident) - { - return new DotIdExp(loc, new TypeExp(loc, type), ident); - } -@@ -4363,16 +5061,49 @@ Expression *ScopeExp::syntaxCopy() - - Expression *ScopeExp::semantic(Scope *sc) - { -- TemplateInstance *ti; -- ScopeDsymbol *sds2; -- - #if LOGSEMANTIC - printf("+ScopeExp::semantic('%s')\n", toChars()); - #endif -+ //if (type == Type::tvoid) -+ // return this; -+ - Lagain: -- ti = sds->isTemplateInstance(); -- if (ti && !ti->errors) -+ TemplateInstance *ti = sds->isTemplateInstance(); -+ if (ti) - { -+ if (!ti->findTemplateDeclaration(sc) || -+ !ti->semanticTiargs(sc)) -+ { -+ ti->inst = ti; -+ ti->inst->errors = true; -+ return new ErrorExp(); -+ } -+ if (ti->needsTypeInference(sc)) -+ { -+ if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration()) -+ { -+ Dsymbol *p = td->toParent2(); -+ FuncDeclaration *fdthis = hasThis(sc); -+ AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL; -+ if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad && -+ (td->scope->stc & STCstatic) == 0) -+ { -+ Expression *e = new DotTemplateInstanceExp(loc, new ThisExp(loc), ti->name, ti->tiargs); -+ return e->semantic(sc); -+ } -+ } -+ else if (OverloadSet *os = ti->tempdecl->isOverloadSet()) -+ { -+ FuncDeclaration *fdthis = hasThis(sc); -+ AggregateDeclaration *ad = os->parent->isAggregateDeclaration(); -+ if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad) -+ { -+ Expression *e = new DotTemplateInstanceExp(loc, new ThisExp(loc), ti->name, ti->tiargs); -+ return e->semantic(sc); -+ } -+ } -+ return this; -+ } - unsigned olderrs = global.errors; - if (!ti->semanticRun) - ti->semantic(sc); -@@ -4381,9 +5112,10 @@ Lagain: - if (ti->inst->errors) - return new ErrorExp(); - Dsymbol *s = ti->inst->toAlias(); -- sds2 = s->isScopeDsymbol(); -+ ScopeDsymbol *sds2 = s->isScopeDsymbol(); - if (!sds2) -- { Expression *e; -+ { -+ Expression *e; - - //printf("s = %s, '%s'\n", s->kind(), s->toChars()); - if (ti->withsym) -@@ -4449,11 +5181,12 @@ void ScopeExp::toCBuffer(OutBuffer *buf, - - // Mainly just a placeholder - --TemplateExp::TemplateExp(Loc loc, TemplateDeclaration *td) -+TemplateExp::TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd) - : Expression(loc, TOKtemplate, sizeof(TemplateExp)) - { - //printf("TemplateExp(): %s\n", td->toChars()); - this->td = td; -+ this->fd = fd; - } - - void TemplateExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -4467,6 +5200,20 @@ int TemplateExp::rvalue() - return 0; - } - -+int TemplateExp::isLvalue() -+{ -+ return fd != NULL; -+} -+ -+Expression *TemplateExp::toLvalue(Scope *sc, Expression *e) -+{ -+ if (!fd) -+ return Expression::toLvalue(sc, e); -+ Expression *ex = new DsymbolExp(loc, fd, 1); -+ ex = ex->semantic(sc); -+ return ex; -+} -+ - /********************** NewExp **************************************/ - - /* thisexp.new(newargs) newtype(arguments) */ -@@ -4497,6 +5244,7 @@ Expression *NewExp::semantic(Scope *sc) - { - Type *tb; - ClassDeclaration *cdthis = NULL; -+ size_t nargs; - - #if LOGSEMANTIC - printf("NewExp::semantic() %s\n", toChars()); -@@ -4541,6 +5289,8 @@ Lagain: - arrayExpressionSemantic(arguments, sc); - preFunctionParameters(loc, sc, arguments); - -+ nargs = arguments ? arguments->dim : 0; -+ - if (thisexp && tb->ty != Tclass) - { error("e.new is only for allocating nested classes, not %s", tb->toChars()); - goto Lerr; -@@ -4561,13 +5311,13 @@ Lagain: - for (size_t i = 0; i < cd->vtbl.dim; i++) - { FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration(); - if (fd && fd->isAbstract()) -- error("function %s is abstract", fd->toChars()); -+ errorSupplemental(loc, "function '%s' is not implemented", fd->toFullSignature()); - } - goto Lerr; - } - -- if (cd->noDefaultCtor && (!arguments || !arguments->dim)) -- { error("default construction is disabled for type %s", cd->toChars()); -+ if (cd->noDefaultCtor && !nargs && !cd->defaultCtor) -+ { error("default construction is disabled for type %s", cd->type->toChars()); - goto Lerr; - } - checkDeprecated(sc, cd); -@@ -4611,7 +5361,7 @@ Lagain: - goto Lerr; - } - } -- } -+ } - else if (thisexp) - { error("e.new is only for allocating nested classes"); - goto Lerr; -@@ -4641,10 +5391,14 @@ Lagain: - - FuncDeclaration *f = NULL; - if (cd->ctor) -- f = resolveFuncCall(sc, loc, cd->ctor, NULL, NULL, arguments, 0); -+ f = resolveFuncCall(loc, sc, cd->ctor, NULL, tb, arguments, 0); - if (f) - { - checkDeprecated(sc, f); -+#if DMDV2 -+ checkPurity(sc, f); -+ checkSafety(sc, f); -+#endif - member = f->isCtorDeclaration(); - assert(member); - -@@ -4655,14 +5409,13 @@ Lagain: - if (!arguments) - arguments = new Expressions(); - unsigned olderrors = global.errors; -- functionParameters(loc, sc, tf, NULL, arguments, f); -+ type = functionParameters(loc, sc, tf, type, arguments, f); - if (olderrors != global.errors) - return new ErrorExp(); -- type = type->addMod(tf->nextOf()->mod); - } - else - { -- if (arguments && arguments->dim) -+ if (nargs) - { error("no constructor for %s", cd->toChars()); - goto Lerr; - } -@@ -4676,7 +5429,9 @@ Lagain: - newargs = new Expressions(); - newargs->shift(e); - -- f = cd->aggNew->overloadResolve(loc, NULL, newargs); -+ f = resolveFuncCall(loc, sc, cd->aggNew, NULL, tb, newargs); -+ if (!f) -+ goto Lerr; - allocator = f->isNewDeclaration(); - assert(allocator); - -@@ -4685,7 +5440,6 @@ Lagain: - functionParameters(loc, sc, tf, NULL, newargs, f); - if (olderrors != global.errors) - return new ErrorExp(); -- - } - else - { -@@ -4701,8 +5455,8 @@ Lagain: - StructDeclaration *sd = ts->sym; - if (sd->scope) - sd->semantic(NULL); -- if (sd->noDefaultCtor && (!arguments || !arguments->dim)) -- { error("default construction is disabled for type %s", sd->toChars()); -+ if (sd->noDefaultCtor && !nargs) -+ { error("default construction is disabled for type %s", sd->type->toChars()); - goto Lerr; - } - -@@ -4714,7 +5468,9 @@ Lagain: - newargs = new Expressions(); - newargs->shift(e); - -- FuncDeclaration *f = sd->aggNew->overloadResolve(loc, NULL, newargs); -+ FuncDeclaration *f = resolveFuncCall(loc, sc, sd->aggNew, NULL, tb, newargs); -+ if (!f) -+ goto Lerr; - allocator = f->isNewDeclaration(); - assert(allocator); - -@@ -4733,27 +5489,30 @@ Lagain: - } - - FuncDeclaration *f = NULL; -- if (sd->ctor) -- f = resolveFuncCall(sc, loc, sd->ctor, NULL, NULL, arguments, 0); -+ if (sd->ctor && nargs) -+ f = resolveFuncCall(loc, sc, sd->ctor, NULL, tb, arguments, 0); - if (f) - { - checkDeprecated(sc, f); -+#if DMDV2 -+ checkPurity(sc, f); -+ checkSafety(sc, f); -+#endif - member = f->isCtorDeclaration(); - assert(member); - - sd->accessCheck(loc, sc, member); - - TypeFunction *tf = (TypeFunction *)f->type; -- type = tf->next; - - if (!arguments) - arguments = new Expressions(); - unsigned olderrors = global.errors; -- functionParameters(loc, sc, tf, NULL, arguments, f); -+ type = functionParameters(loc, sc, tf, type, arguments, f); - if (olderrors != global.errors) - return new ErrorExp(); - } -- else if (arguments && arguments->dim) -+ else if (nargs) - { - Type *tptr = type->pointerTo(); - -@@ -4782,9 +5541,16 @@ Lagain: - - type = type->pointerTo(); - } -- else if (tb->ty == Tarray && (arguments && arguments->dim)) -+ else if (tb->ty == Tarray && nargs) - { -- for (size_t i = 0; i < arguments->dim; i++) -+ Type *tn = tb->nextOf()->baseElemOf(); -+ Dsymbol *s = tn->toDsymbol(sc); -+ AggregateDeclaration *ad = s ? s->isAggregateDeclaration() : NULL; -+ if (ad && ad->noDefaultCtor) -+ { error("default construction is disabled for type %s", tb->nextOf()->toChars()); -+ goto Lerr; -+ } -+ for (size_t i = 0; i < nargs; i++) - { - if (tb->ty != Tarray) - { error("too many arguments for array"); -@@ -4805,7 +5571,7 @@ Lagain: - } - else if (tb->isscalar()) - { -- if (arguments && arguments->dim) -+ if (nargs) - { error("no constructor for %s", type->toChars()); - goto Lerr; - } -@@ -4881,7 +5647,11 @@ Expression *NewAnonClassExp::semantic(Sc - #endif - - Expression *d = new DeclarationExp(loc, cd); -+ sc = sc->startCTFE(); // just create new scope -+ sc->flags &= ~SCOPEctfe; // temporary stop CTFE - d = d->semantic(sc); -+ sc->flags |= SCOPEctfe; -+ sc = sc->endCTFE(); - - Expression *n = new NewExp(loc, thisexp, newargs, cd->type, arguments); - -@@ -4920,7 +5690,7 @@ void NewAnonClassExp::toCBuffer(OutBuffe - /********************** SymbolExp **************************************/ - - #if DMDV2 --SymbolExp::SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads) -+SymbolExp::SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads) - : Expression(loc, op, size) - { - assert(var); -@@ -4931,7 +5701,7 @@ SymbolExp::SymbolExp(Loc loc, enum TOK o - - /********************** SymOffExp **************************************/ - --SymOffExp::SymOffExp(Loc loc, Declaration *var, unsigned offset, int hasOverloads) -+SymOffExp::SymOffExp(Loc loc, Declaration *var, unsigned offset, bool hasOverloads) - : SymbolExp(loc, TOKsymoff, sizeof(SymOffExp), var, hasOverloads) - { - this->offset = offset; -@@ -4983,13 +5753,15 @@ void SymOffExp::toCBuffer(OutBuffer *buf - { - if (offset) - buf->printf("(& %s+%u)", var->toChars(), offset); -+ else if (var->isTypeInfoDeclaration()) -+ buf->printf("%s", var->toChars()); - else - buf->printf("& %s", var->toChars()); - } - - /******************************** VarExp **************************/ - --VarExp::VarExp(Loc loc, Declaration *var, int hasOverloads) -+VarExp::VarExp(Loc loc, Declaration *var, bool hasOverloads) - : SymbolExp(loc, TOKvar, sizeof(VarExp), var, hasOverloads) - { - //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var->toChars(), loc.toChars()); -@@ -4997,15 +5769,20 @@ VarExp::VarExp(Loc loc, Declaration *var - this->type = var->type; - } - --int VarExp::equals(Object *o) --{ VarExp *ne; -- -- if (this == o || -- (((Expression *)o)->op == TOKvar && -- ((ne = (VarExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && -- var == ne->var)) -- return 1; -- return 0; -+bool VarExp::equals(RootObject *o) -+{ -+ if (this == o) -+ return true; -+ if (((Expression *)o)->op == TOKvar) -+ { -+ VarExp *ne = (VarExp *)o; -+ if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && -+ var == ne->var) -+ { -+ return true; -+ } -+ } -+ return false; - } - - Expression *VarExp::semantic(Scope *sc) -@@ -5035,9 +5812,10 @@ Expression *VarExp::semantic(Scope *sc) - VarDeclaration *v = var->isVarDeclaration(); - if (v) - { -+ hasOverloads = 0; - v->checkNestedReference(sc, loc); - #if DMDV2 -- checkPurity(sc, v, NULL); -+ checkPurity(sc, v); - #endif - } - FuncDeclaration *f = var->isFuncDeclaration(); -@@ -5085,13 +5863,17 @@ void VarExp::checkEscapeRef() - - int VarExp::isLvalue() - { -- if (var->storage_class & (STClazy | STCtemp)) -+ if (var->storage_class & (STClazy | STCtemp | STCmanifest)) - return 0; - return 1; - } - - Expression *VarExp::toLvalue(Scope *sc, Expression *e) - { -+ if (var->storage_class & STCmanifest) -+ { error("manifest constant '%s' is not lvalue", var->toChars()); -+ return new ErrorExp(); -+ } - if (var->storage_class & STClazy) - { error("lazy variables cannot be lvalues"); - return new ErrorExp(); -@@ -5114,19 +5896,11 @@ int VarExp::checkModifiable(Scope *sc, i - Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e) - { - //printf("VarExp::modifiableLvalue('%s')\n", var->toChars()); -- //if (type && type->toBasetype()->ty == Tsarray) -- //error("cannot change reference to static array '%s'", var->toChars()); -- --#if (BUG6652 == 1) -- VarDeclaration *v = var->isVarDeclaration(); -- if (v && (v->storage_class & STCbug6652) && v->type->isMutable()) -- warning("variable modified in foreach body requires ref storage class"); --#elif (BUG6652 == 2) -- VarDeclaration *v = var->isVarDeclaration(); -- if (v && (v->storage_class & STCbug6652) && v->type->isMutable()) -- deprecation("variable modified in foreach body requires ref storage class"); --#endif -- -+ if (var->storage_class & STCmanifest) -+ { -+ error("Cannot modify '%s'", toChars()); -+ return new ErrorExp(); -+ } - // See if this expression is a modifiable lvalue (i.e. not const) - return Expression::modifiableLvalue(sc, e); - } -@@ -5135,7 +5909,7 @@ Expression *VarExp::modifiableLvalue(Sco - /******************************** OverExp **************************/ - - #if DMDV2 --OverExp::OverExp(OverloadSet *s) -+OverExp::OverExp(Loc loc, OverloadSet *s) - : Expression(loc, TOKoverloadset, sizeof(OverExp)) - { - //printf("OverExp(this = %p, '%s')\n", this, var->toChars()); -@@ -5152,47 +5926,60 @@ Expression *OverExp::toLvalue(Scope *sc, - { - return this; - } -+ -+void OverExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -+{ -+ buf->writestring(vars->ident->toChars()); -+} -+ - #endif - - - /******************************** TupleExp **************************/ - --TupleExp::TupleExp(Loc loc, Expressions *exps) -+TupleExp::TupleExp(Loc loc, Expression *e0, Expressions *exps) - : Expression(loc, TOKtuple, sizeof(TupleExp)) - { - //printf("TupleExp(this = %p)\n", this); -+ this->e0 = e0; - this->exps = exps; -- this->type = NULL; - } - -+TupleExp::TupleExp(Loc loc, Expressions *exps) -+ : Expression(loc, TOKtuple, sizeof(TupleExp)) -+{ -+ //printf("TupleExp(this = %p)\n", this); -+ this->e0 = NULL; -+ this->exps = exps; -+} - - TupleExp::TupleExp(Loc loc, TupleDeclaration *tup) - : Expression(loc, TOKtuple, sizeof(TupleExp)) - { -- exps = new Expressions(); -- type = NULL; -+ this->e0 = NULL; -+ this->exps = new Expressions(); - -- exps->reserve(tup->objects->dim); -+ this->exps->reserve(tup->objects->dim); - for (size_t i = 0; i < tup->objects->dim; i++) -- { Object *o = (*tup->objects)[i]; -- if (o->dyncast() == DYNCAST_EXPRESSION) -+ { RootObject *o = (*tup->objects)[i]; -+ if (Dsymbol *s = getDsymbol(o)) - { -- Expression *e = (Expression *)o; -- if (e->op == TOKdsymbol) -- e = e->syntaxCopy(); -- exps->push(e); -+ /* If tuple element represents a symbol, translate to DsymbolExp -+ * to supply implicit 'this' if needed later. -+ */ -+ Expression *e = new DsymbolExp(loc, s); -+ this->exps->push(e); - } -- else if (o->dyncast() == DYNCAST_DSYMBOL) -+ else if (o->dyncast() == DYNCAST_EXPRESSION) - { -- Dsymbol *s = (Dsymbol *)o; -- Expression *e = new DsymbolExp(loc, s); -- exps->push(e); -+ Expression *e = (Expression *)o; -+ this->exps->push(e); - } - else if (o->dyncast() == DYNCAST_TYPE) - { - Type *t = (Type *)o; - Expression *e = new TypeExp(loc, t); -- exps->push(e); -+ this->exps->push(e); - } - else - { -@@ -5201,30 +5988,32 @@ TupleExp::TupleExp(Loc loc, TupleDeclara - } - } - --int TupleExp::equals(Object *o) -+bool TupleExp::equals(RootObject *o) - { - if (this == o) -- return 1; -+ return true; - if (((Expression *)o)->op == TOKtuple) - { - TupleExp *te = (TupleExp *)o; - if (exps->dim != te->exps->dim) -- return 0; -+ return false; -+ if (e0 && !e0->equals(te->e0) || !e0 && te->e0) -+ return false; - for (size_t i = 0; i < exps->dim; i++) -- { Expression *e1 = (*exps)[i]; -+ { -+ Expression *e1 = (*exps)[i]; - Expression *e2 = (*te->exps)[i]; -- - if (!e1->equals(e2)) -- return 0; -+ return false; - } -- return 1; -+ return true; - } -- return 0; -+ return false; - } - - Expression *TupleExp::syntaxCopy() - { -- return new TupleExp(loc, arraySyntaxCopy(exps)); -+ return new TupleExp(loc, e0 ? e0->syntaxCopy() : NULL, arraySyntaxCopy(exps)); - } - - Expression *TupleExp::semantic(Scope *sc) -@@ -5235,6 +6024,9 @@ Expression *TupleExp::semantic(Scope *sc - if (type) - return this; - -+ if (e0) -+ e0 = e0->semantic(sc); -+ - // Run semantic() on each argument - for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (*exps)[i]; -@@ -5256,9 +6048,20 @@ Expression *TupleExp::semantic(Scope *sc - - void TupleExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { -- buf->writestring("tuple("); -- argsToCBuffer(buf, exps, hgs); -- buf->writeByte(')'); -+ if (e0) -+ { -+ buf->writeByte('('); -+ e0->toCBuffer(buf, hgs); -+ buf->writestring(", tuple("); -+ argsToCBuffer(buf, exps, hgs); -+ buf->writestring("))"); -+ } -+ else -+ { -+ buf->writestring("tuple("); -+ argsToCBuffer(buf, exps, hgs); -+ buf->writeByte(')'); -+ } - } - - -@@ -5280,10 +6083,57 @@ FuncExp::FuncExp(Loc loc, FuncLiteralDec - tok = fd->tok; // save original kind of function/delegate/(infer) - } - -+void FuncExp::genIdent(Scope *sc) -+{ -+ if (fd->ident == Id::empty) -+ { -+ const char *s; -+ if (fd->fes) s = "__foreachbody"; -+ else if (fd->tok == TOKreserved) s = "__lambda"; -+ else if (fd->tok == TOKdelegate) s = "__dgliteral"; -+ else s = "__funcliteral"; -+ -+ DsymbolTable *symtab; -+ if (FuncDeclaration *func = sc->parent->isFuncDeclaration()) -+ { -+ symtab = func->localsymtab; -+ if (symtab) -+ { -+ // Inside template constraint, symtab is not set yet. -+ goto L1; -+ } -+ } -+ else -+ { -+ symtab = sc->parent->isScopeDsymbol()->symtab; -+ L1: -+ assert(symtab); -+ int num = _aaLen(symtab->tab) + 1; -+ Identifier *id = Lexer::uniqueId(s, num); -+ fd->ident = id; -+ if (td) td->ident = id; -+ symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd); -+ } -+ } -+} -+ - Expression *FuncExp::syntaxCopy() - { -- TemplateDeclaration *td2 = td ? (TemplateDeclaration *)td->syntaxCopy(NULL) : NULL; -- return new FuncExp(loc, (FuncLiteralDeclaration *)fd->syntaxCopy(NULL), td2); -+ TemplateDeclaration *td2; -+ FuncLiteralDeclaration *fd2; -+ if (td) -+ { -+ td2 = (TemplateDeclaration *)td->syntaxCopy(NULL); -+ assert(td2->members->dim == 1); -+ fd2 = (*td2->members)[0]->isFuncLiteralDeclaration(); -+ assert(fd2); -+ } -+ else -+ { -+ td2 = NULL; -+ fd2 = (FuncLiteralDeclaration *)fd->syntaxCopy(NULL); -+ } -+ return new FuncExp(loc, fd2, td2); - } - - Expression *FuncExp::semantic(Scope *sc) -@@ -5292,6 +6142,11 @@ Expression *FuncExp::semantic(Scope *sc) - printf("FuncExp::semantic(%s)\n", toChars()); - if (fd->treq) printf(" treq = %s\n", fd->treq->toChars()); - #endif -+ Expression *e = this; -+ -+ sc = sc->startCTFE(); // just create new scope -+ sc->flags &= ~SCOPEctfe; // temporary stop CTFE -+ - if (!type || type == Type::tvoid) - { - /* fd->treq might be incomplete type, -@@ -5302,6 +6157,8 @@ Expression *FuncExp::semantic(Scope *sc) - //if (fd->treq) - // fd->treq = fd->treq->semantic(loc, sc); - -+ genIdent(sc); -+ - // Set target of return type inference - if (fd->treq && !fd->type->nextOf()) - { TypeFunction *tfv = NULL; -@@ -5321,10 +6178,9 @@ Expression *FuncExp::semantic(Scope *sc) - td->semantic(sc); - type = Type::tvoid; // temporary type - -- if (!fd->treq) // defer type determination -- return this; -- -- return inferType(fd->treq); -+ if (fd->treq) // defer type determination -+ e = inferType(fd->treq); -+ goto Ldone; - } - - unsigned olderrors = global.errors; -@@ -5345,8 +6201,12 @@ Expression *FuncExp::semantic(Scope *sc) - } - - // need to infer return type -- if ((olderrors != global.errors) && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()) -- ((TypeFunction *)fd->type)->next = Type::terror; -+ if (olderrors != global.errors) -+ { -+ if (fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()) -+ ((TypeFunction *)fd->type)->next = Type::terror; -+ return new ErrorExp(); -+ } - - // Type is a "delegate to" or "pointer to" the function literal - if ((fd->isNested() && fd->tok == TOKdelegate) || -@@ -5379,7 +6239,10 @@ Expression *FuncExp::semantic(Scope *sc) - } - fd->tookAddressOf++; - } -- return this; -+Ldone: -+ sc->flags |= SCOPEctfe; -+ sc = sc->endCTFE(); -+ return e; - } - - // used from CallExp::semantic() -@@ -5393,6 +6256,8 @@ Expression *FuncExp::semantic(Scope *sc, - return checkarg; - } - -+ genIdent(sc); -+ - assert(td->parameters && td->parameters->dim); - td->semantic(sc); - -@@ -5507,7 +6372,7 @@ Expression *DeclarationExp::semantic(Sco - return new ErrorExp(); - } - else if (sc->func) -- { VarDeclaration *v = s->isVarDeclaration(); -+ { - if ( (s->isFuncDeclaration() || s->isTypedefDeclaration() || - s->isAggregateDeclaration() || s->isEnumDeclaration() || - s->isInterfaceDeclaration()) && -@@ -5571,7 +6436,7 @@ void DeclarationExp::toCBuffer(OutBuffer - * typeid(int) - */ - --TypeidExp::TypeidExp(Loc loc, Object *o) -+TypeidExp::TypeidExp(Loc loc, RootObject *o) - : Expression(loc, TOKtypeid, sizeof(TypeidExp)) - { - this->obj = o; -@@ -5598,7 +6463,7 @@ Expression *TypeidExp::semantic(Scope *s - - if (ta) - { -- ta->resolve(loc, sc, &ea, &ta, &sa); -+ ta->resolve(loc, sc, &ea, &ta, &sa, true); - } - - if (ea) -@@ -5676,8 +6541,8 @@ void TraitsExp::toCBuffer(OutBuffer *buf - { - for (size_t i = 0; i < args->dim; i++) - { -- buf->writeByte(','); -- Object *oarg = (*args)[i]; -+ buf->writestring(", ");; -+ RootObject *oarg = (*args)[i]; - ObjectToCBuffer(buf, hgs, oarg); - } - } -@@ -5709,8 +6574,8 @@ void HaltExp::toCBuffer(OutBuffer *buf, - - /************************************************************/ - --IsExp::IsExp(Loc loc, Type *targ, Identifier *id, enum TOK tok, -- Type *tspec, enum TOK tok2, TemplateParameters *parameters) -+IsExp::IsExp(Loc loc, Type *targ, Identifier *id, TOK tok, -+ Type *tspec, TOK tok2, TemplateParameters *parameters) - : Expression(loc, TOKis, sizeof(IsExp)) - { - this->targ = targ; -@@ -5810,8 +6675,6 @@ Expression *IsExp::semantic(Scope *sc) - tded = targ; - break; - -- case TOKinvariant: -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); - case TOKimmutable: - if (!targ->isImmutable()) - goto Lno; -@@ -5839,6 +6702,8 @@ Expression *IsExp::semantic(Scope *sc) - { ClassDeclaration *cd = ((TypeClass *)targ)->sym; - Parameters *args = new Parameters; - args->reserve(cd->baseclasses->dim); -+ if (cd->scope && !cd->symtab) -+ cd->semantic(cd->scope); - for (size_t i = 0; i < cd->baseclasses->dim; i++) - { BaseClass *b = (*cd->baseclasses)[i]; - args->push(new Parameter(STCin, b->type, NULL, NULL)); -@@ -5924,21 +6789,51 @@ Expression *IsExp::semantic(Scope *sc) - } - goto Lyes; - } -- else if (id && tspec) -+ else if (tspec && !id && !(parameters && parameters->dim)) -+ { -+ /* Evaluate to TRUE if targ matches tspec -+ * is(targ == tspec) -+ * is(targ : tspec) -+ */ -+ tspec = tspec->semantic(loc, sc); -+ //printf("targ = %s, %s\n", targ->toChars(), targ->deco); -+ //printf("tspec = %s, %s\n", tspec->toChars(), tspec->deco); -+ if (tok == TOKcolon) -+ { if (targ->implicitConvTo(tspec)) -+ goto Lyes; -+ else -+ goto Lno; -+ } -+ else /* == */ -+ { if (targ->equals(tspec)) -+ goto Lyes; -+ else -+ goto Lno; -+ } -+ } -+ else if (tspec) - { - /* Evaluate to TRUE if targ matches tspec. - * If TRUE, declare id as an alias for the specialized type. -+ * is(targ == tspec, tpl) -+ * is(targ : tspec, tpl) -+ * is(targ id == tspec) -+ * is(targ id : tspec) -+ * is(targ id == tspec, tpl) -+ * is(targ id : tspec, tpl) - */ - -- assert(parameters && parameters->dim); -+ Identifier *tid = id ? id : Lexer::uniqueId("__isexp_id"); -+ TemplateParameter *tp = new TemplateTypeParameter(loc, tid, NULL, NULL); -+ parameters->insert(0, tp); - - Objects dedtypes; - dedtypes.setDim(parameters->dim); - dedtypes.zero(); - - MATCH m = targ->deduceType(sc, tspec, parameters, &dedtypes); --//printf("targ: %s\n", targ->toChars()); --//printf("tspec: %s\n", tspec->toChars()); -+ //printf("targ: %s\n", targ->toChars()); -+ //printf("tspec: %s\n", tspec->toChars()); - if (m == MATCHnomatch || - (m != MATCHexact && tok == TOKequal)) - { -@@ -5960,7 +6855,7 @@ Expression *IsExp::semantic(Scope *sc) - { TemplateParameter *tp = (*parameters)[i]; - Declaration *s = NULL; - -- m = tp->matchArg(sc, &tiargs, i, parameters, &dedtypes, &s); -+ m = tp->matchArg(loc, sc, &tiargs, i, parameters, &dedtypes, &s); - if (m == MATCHnomatch) - goto Lno; - s->semantic(sc); -@@ -5976,32 +6871,11 @@ Expression *IsExp::semantic(Scope *sc) - else if (id) - { - /* Declare id as an alias for type targ. Evaluate to TRUE -+ * is(targ id) - */ - tded = targ; - goto Lyes; - } -- else if (tspec) -- { -- /* Evaluate to TRUE if targ matches tspec -- * is(targ == tspec) -- * is(targ : tspec) -- */ -- tspec = tspec->semantic(loc, sc); -- //printf("targ = %s, %s\n", targ->toChars(), targ->deco); -- //printf("tspec = %s, %s\n", tspec->toChars(), tspec->deco); -- if (tok == TOKcolon) -- { if (targ->implicitConvTo(tspec)) -- goto Lyes; -- else -- goto Lno; -- } -- else /* == */ -- { if (targ->equals(tspec)) -- goto Lyes; -- else -- goto Lno; -- } -- } - - Lyes: - if (id) -@@ -6047,10 +6921,10 @@ void IsExp::toCBuffer(OutBuffer *buf, Hd - } - #if DMDV2 - if (parameters) -- { // First parameter is already output, so start with second -- for (size_t i = 1; i < parameters->dim; i++) -+ { -+ for (size_t i = 0; i < parameters->dim; i++) - { -- buf->writeByte(','); -+ buf->writestring(", "); - TemplateParameter *tp = (*parameters)[i]; - tp->toCBuffer(buf, hgs); - } -@@ -6062,10 +6936,11 @@ void IsExp::toCBuffer(OutBuffer *buf, Hd - - /************************************************************/ - --UnaExp::UnaExp(Loc loc, enum TOK op, int size, Expression *e1) -+UnaExp::UnaExp(Loc loc, TOK op, int size, Expression *e1) - : Expression(loc, op, size) - { - this->e1 = e1; -+ this->att1 = NULL; - } - - Expression *UnaExp::syntaxCopy() -@@ -6101,11 +6976,14 @@ void UnaExp::toCBuffer(OutBuffer *buf, H - - /************************************************************/ - --BinExp::BinExp(Loc loc, enum TOK op, int size, Expression *e1, Expression *e2) -+BinExp::BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2) - : Expression(loc, op, size) - { - this->e1 = e1; - this->e2 = e2; -+ -+ this->att1 = NULL; -+ this->att2 = NULL; - } - - Expression *BinExp::syntaxCopy() -@@ -6262,7 +7140,7 @@ void BinExp::toCBuffer(OutBuffer *buf, H - buf->writeByte(' '); - buf->writestring(Token::toChars(op)); - buf->writeByte(' '); -- expToCBuffer(buf, hgs, e2, (enum PREC)(precedence[op] + 1)); -+ expToCBuffer(buf, hgs, e2, (PREC)(precedence[op] + 1)); - } - - int BinExp::isunsigned() -@@ -6313,8 +7191,7 @@ Expression *BinAssignExp::semantic(Scope - e = e->semantic(sc); - return e; - } -- -- if (e1->op == TOKslice) -+ else if (e1->op == TOKslice) - { - // T[] op= ... - e = typeCombine(sc); -@@ -6324,8 +7201,9 @@ Expression *BinAssignExp::semantic(Scope - return arrayOp(sc); - } - -- e1 = e1->modifiableLvalue(sc, e1); - e1 = e1->semantic(sc); -+ e1 = e1->optimize(WANTvalue); -+ e1 = e1->modifiableLvalue(sc, e1); - type = e1->type; - checkScalar(); - -@@ -6380,7 +7258,8 @@ Expression *BinAssignExp::semantic(Scope - if (e1->op == TOKerror || e2->op == TOKerror) - return new ErrorExp(); - -- return checkComplexOpAssign(sc); -+ checkComplexOpAssign(sc); -+ return reorderSettingAAElem(sc); - } - - #if DMDV2 -@@ -6447,8 +7326,10 @@ Expression *CompileExp::semantic(Scope * - #if LOGSEMANTIC - printf("CompileExp::semantic('%s')\n", toChars()); - #endif -- UnaExp::semantic(sc); -+ sc = sc->startCTFE(); -+ e1 = e1->semantic(sc); - e1 = resolveProperties(sc, e1); -+ sc = sc->endCTFE(); - if (e1->op == TOKerror) - return e1; - if (!e1->type->isString()) -@@ -6463,11 +7344,14 @@ Expression *CompileExp::semantic(Scope * - return new ErrorExp(); - } - se = se->toUTF8(sc); -- Parser p(sc->module, (unsigned char *)se->string, se->len, 0); -- p.loc = loc; -+ Parser p(sc->module, (utf8_t *)se->string, se->len, 0); -+ p.scanloc = loc; - p.nextToken(); - //printf("p.loc.linnum = %d\n", p.loc.linnum); -+ unsigned errors = global.errors; - Expression *e = p.parseExpression(); -+ if (global.errors != errors) -+ return new ErrorExp(); - if (p.token.value != TOKeof) - { error("incomplete mixin expression (%s)", se->toChars()); - return new ErrorExp(); -@@ -6497,8 +7381,10 @@ Expression *FileExp::semantic(Scope *sc) - #if LOGSEMANTIC - printf("FileExp::semantic('%s')\n", toChars()); - #endif -- UnaExp::semantic(sc); -+ sc = sc->startCTFE(); -+ e1 = e1->semantic(sc); - e1 = resolveProperties(sc, e1); -+ sc = sc->endCTFE(); - e1 = e1->ctfeInterpret(); - if (e1->op != TOKstring) - { error("file name argument must be a string, not (%s)", e1->toChars()); -@@ -6525,7 +7411,23 @@ Expression *FileExp::semantic(Scope *sc) - } - - if (global.params.verbose) -- fprintf(stdmsg, "file %s\t(%s)\n", (char *)se->string, name); -+ fprintf(global.stdmsg, "file %s\t(%s)\n", (char *)se->string, name); -+ if (global.params.moduleDeps != NULL && global.params.moduleDepsFile == NULL) -+ { -+ OutBuffer *ob = global.params.moduleDeps; -+ Module* imod = sc->instantiatingModule ? sc->instantiatingModule : sc->module; -+ -+ ob->writestring("depsFile "); -+ ob->writestring(imod->toPrettyChars()); -+ ob->writestring(" ("); -+ escapePath(ob, imod->srcfile->toChars()); -+ ob->writestring(") : "); -+ ob->writestring((char *) se->string); -+ ob->writestring(" ("); -+ escapePath(ob, name); -+ ob->writestring(")"); -+ ob->writenl(); -+ } - - { File f(name); - if (f.read()) -@@ -6606,7 +7508,7 @@ void AssertExp::toCBuffer(OutBuffer *buf - expToCBuffer(buf, hgs, e1, PREC_assign); - if (msg) - { -- buf->writeByte(','); -+ buf->writestring(", "); - expToCBuffer(buf, hgs, msg, PREC_assign); - } - buf->writeByte(')'); -@@ -6622,95 +7524,76 @@ DotIdExp::DotIdExp(Loc loc, Expression * - - Expression *DotIdExp::semantic(Scope *sc) - { -- // Indicate we need to resolve by UFCS. -- return semantic(sc, 0); --} -- --Expression *DotIdExp::semantic(Scope *sc, int flag) --{ Expression *e; -- Expression *eleft; -- Expression *eright; -- - #if LOGSEMANTIC - printf("DotIdExp::semantic(this = %p, '%s')\n", this, toChars()); - //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); - #endif -- --//{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } -- -- /* Special case: rewrite this.id and super.id -- * to be classtype.id and baseclasstype.id -- * if we have no this pointer. -- */ -- if ((e1->op == TOKthis || e1->op == TOKsuper) && !hasThis(sc)) -- { ClassDeclaration *cd; -- StructDeclaration *sd; -- AggregateDeclaration *ad; -- -- ad = sc->getStructClassScope(); -- if (ad) -- { -- cd = ad->isClassDeclaration(); -- if (cd) -- { -- if (e1->op == TOKthis) -- { -- e = typeDotIdExp(loc, cd->type, ident); -- return e->semantic(sc); -- } -- else if (cd->baseClass && e1->op == TOKsuper) -- { -- e = typeDotIdExp(loc, cd->baseClass->type, ident); -- return e->semantic(sc); -- } -- } -- else -- { -- sd = ad->isStructDeclaration(); -- if (sd) -- { -- if (e1->op == TOKthis) -- { -- e = typeDotIdExp(loc, sd->type, ident); -- return e->semantic(sc); -- } -- } -- } -- } -+ Expression *e = semanticY(sc, 1); -+ if (e && isDotOpDispatch(e)) -+ { -+ unsigned errors = global.startGagging(); -+ e = resolvePropertiesX(sc, e); -+ if (global.endGagging(errors)) -+ e = NULL; /* fall down to UFCS */ -+ else -+ return e; - } -+ if (!e) // if failed to find the property -+ { -+ /* If ident is not a valid property, rewrite: -+ * e1.ident -+ * as: -+ * .ident(e1) -+ */ -+ e = resolveUFCSProperties(sc, this); -+ } -+ return e; -+} - --// Type *t1save = e1->type; -+// Run sematnic in e1 -+Expression *DotIdExp::semanticX(Scope *sc) -+{ -+ //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars()); -+ Expression *e; - - UnaExp::semantic(sc); -+ if (e1->op == TOKerror) -+ return e1; - - if (ident == Id::mangleof) - { // symbol.mangleof - Dsymbol *ds; - switch (e1->op) - { -- case TOKimport: ds = ((ScopeExp *)e1)->sds; goto L1; -- case TOKvar: ds = ((VarExp *)e1)->var; goto L1; -- case TOKdotvar: ds = ((DotVarExp *)e1)->var; goto L1; -- default: break; -- L1: -- char* s = ds->mangle(); -- e = new StringExp(loc, s, strlen(s), 'c'); -+ case TOKimport: -+ ds = ((ScopeExp *)e1)->sds; -+ goto L1; -+ case TOKvar: -+ ds = ((VarExp *)e1)->var; -+ goto L1; -+ case TOKdotvar: -+ ds = ((DotVarExp *)e1)->var; -+ goto L1; -+ case TOKoverloadset: -+ ds = ((OverExp *)e1)->vars; -+ L1: -+ { -+ const char* s = ds->mangle(); -+ e = new StringExp(loc, (void*)s, strlen(s), 'c'); - e = e->semantic(sc); - return e; -+ } -+ default: -+ break; - } - } - - if (e1->op == TOKdotexp) - { -- DotExp *de = (DotExp *)e1; -- eleft = de->e1; -- eright = de->e2; - } - else - { -- e1 = resolveProperties(sc, e1); -- eleft = NULL; -- eright = e1; -+ e1 = resolvePropertiesX(sc, e1); - } - #if DMDV2 - if (e1->op == TOKtuple && ident == Id::offsetof) -@@ -6725,7 +7608,8 @@ Expression *DotIdExp::semantic(Scope *sc - e = new DotIdExp(e->loc, e, Id::offsetof); - (*exps)[i] = e; - } -- e = new TupleExp(loc, exps); -+ // Don't evaluate te->e0 in runtime -+ e = new TupleExp(loc, /*te->e0*/NULL, exps); - e = e->semantic(sc); - return e; - } -@@ -6734,6 +7618,7 @@ Expression *DotIdExp::semantic(Scope *sc - if (e1->op == TOKtuple && ident == Id::length) - { - TupleExp *te = (TupleExp *)e1; -+ // Don't evaluate te->e0 in runtime - e = new IntegerExp(loc, te->exps->dim, Type::tsize_t); - return e; - } -@@ -6750,6 +7635,56 @@ Expression *DotIdExp::semantic(Scope *sc - return new ErrorExp(); - } - -+ return this; -+} -+ -+// Resolve e1.ident without seeing UFCS. -+// If flag == 1, stop "not a property" error and return NULL. -+Expression *DotIdExp::semanticY(Scope *sc, int flag) -+{ -+ //printf("DotIdExp::semanticY(this = %p, '%s')\n", this, toChars()); -+ -+//{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } -+ -+ /* Special case: rewrite this.id and super.id -+ * to be classtype.id and baseclasstype.id -+ * if we have no this pointer. -+ */ -+ if ((e1->op == TOKthis || e1->op == TOKsuper) && !hasThis(sc)) -+ { -+ if (AggregateDeclaration *ad = sc->getStructClassScope()) -+ { -+ if (e1->op == TOKthis) -+ { -+ e1 = new TypeExp(e1->loc, ad->type); -+ } -+ else -+ { -+ ClassDeclaration *cd = ad->isClassDeclaration(); -+ if (cd && cd->baseClass) -+ e1 = new TypeExp(e1->loc, cd->baseClass->type); -+ } -+ } -+ } -+ -+ Expression *e = semanticX(sc); -+ if (e != this) -+ return e; -+ -+ Expression *eleft; -+ Expression *eright; -+ if (e1->op == TOKdotexp) -+ { -+ DotExp *de = (DotExp *)e1; -+ eleft = de->e1; -+ eright = de->e2; -+ } -+ else -+ { -+ eleft = NULL; -+ eright = e1; -+ } -+ - Type *t1b = e1->type->toBasetype(); - - if (eright->op == TOKimport) // also used for template alias's -@@ -6768,7 +7703,7 @@ Expression *DotIdExp::semantic(Scope *sc - * aliases to private symbols are public. - */ - if (Declaration *d = s->isDeclaration()) -- accessCheck(loc, sc, 0, d); -+ accessCheck(loc, sc, NULL, d); - - s = s->toAlias(); - checkDeprecated(sc, s); -@@ -6776,9 +7711,7 @@ Expression *DotIdExp::semantic(Scope *sc - EnumMember *em = s->isEnumMember(); - if (em) - { -- e = em->value; -- e = e->semantic(sc); -- return e; -+ return em->getVarExp(loc, sc); - } - - VarDeclaration *v = s->isVarDeclaration(); -@@ -6814,6 +7747,8 @@ Expression *DotIdExp::semantic(Scope *sc - if (f) - { - //printf("it's a function\n"); -+ if (!f->functionSemantic()) -+ return new ErrorExp(); - if (f->needThis()) - { - if (!eleft) -@@ -6835,7 +7770,7 @@ Expression *DotIdExp::semantic(Scope *sc - OverloadSet *o = s->isOverloadSet(); - if (o) - { //printf("'%s' is an overload set\n", o->toChars()); -- return new OverExp(o); -+ return new OverExp(loc, o); - } - #endif - -@@ -6860,7 +7795,7 @@ Expression *DotIdExp::semantic(Scope *sc - ScopeDsymbol *sds = s->isScopeDsymbol(); - if (sds) - { -- //printf("it's a ScopeDsymbol\n"); -+ //printf("it's a ScopeDsymbol %s\n", ident->toChars()); - e = new ScopeExp(loc, sds); - e = e->semantic(sc); - if (eleft) -@@ -6889,6 +7824,14 @@ Expression *DotIdExp::semantic(Scope *sc - e = e->semantic(sc); - return e; - } -+ if (ie->sds->isPackage() || -+ ie->sds->isImport() || -+ ie->sds->isModule()) -+ { -+ flag = 0; -+ } -+ if (flag) -+ return NULL; - s = ie->sds->search_correct(ident); - if (s) - error("undefined identifier '%s', did you mean '%s %s'?", -@@ -6906,68 +7849,19 @@ Expression *DotIdExp::semantic(Scope *sc - * as: - * (*p).ident - */ -+ if (flag && t1b->nextOf()->ty == Tvoid) -+ return NULL; - e = new PtrExp(loc, e1); -- e->type = ((TypePointer *)t1b)->next; -- return e->type->dotExp(sc, e, ident); -- } --#if DMDV2 -- else if (!flag) -- { /* If ident is not a valid property, rewrite: -- * e1.ident -- * as: -- * .ident(e1) -- */ -- if (e1->op == TOKtype || -- t1b->ty == Tvoid || -- (t1b->ty == Tarray || t1b->ty == Tsarray || t1b->ty == Taarray) && -- (ident == Id::sort || ident == Id::reverse || ident == Id::dup || ident == Id::idup)) -- { goto L2; -- } -- -- /* This would be much better if we added a "hasProperty" method to types, -- * i.e. the gagging is a bad way. -- */ -- -- if (t1b->ty == Taarray) -- { -- TypeAArray *taa = (TypeAArray *)t1b; -- if (!taa->impl && -- ident != Id::__sizeof && -- ident != Id::__xalignof && -- ident != Id::init && -- ident != Id::mangleof && -- ident != Id::stringof && -- ident != Id::offsetof) -- { -- // Find out about these errors when not gagged -- taa->getImpl(); -- } -- } -- -- Type *t1 = e1->type; -- unsigned errors = global.startGagging(); -- e = t1->dotExp(sc, e1, ident); -- if (global.endGagging(errors)) // if failed to find the property -- { -- e1->type = t1; // kludge to restore type -- errors = global.startGagging(); -- e = resolveUFCSProperties(sc, this); -- if (global.endGagging(errors)) -- { -- // both lookups failed, lookup property again for better error message -- e1->type = t1; // restore type -- e = t1->dotExp(sc, e1, ident); -- } -- } - e = e->semantic(sc); -- return e; -+ return e->type->dotExp(sc, e, ident, flag); - } --#endif - else - { -- L2: -- e = e1->type->dotExp(sc, e1, ident); -- e = e->semantic(sc); -+ if (e1->op == TOKtype || e1->op == TOKtemplate) -+ flag = 0; -+ e = e1->type->dotExp(sc, e1, ident, flag); -+ if (!flag || e) -+ e = e->semantic(sc); - return e; - } - } -@@ -7001,7 +7895,7 @@ void DotTemplateExp::toCBuffer(OutBuffer - - /************************************************************/ - --DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *v, int hasOverloads) -+DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *v, bool hasOverloads) - : UnaExp(loc, TOKdotvar, sizeof(DotVarExp), e) - { - //printf("DotVarExp()\n"); -@@ -7025,12 +7919,27 @@ Expression *DotVarExp::semantic(Scope *s - * with: - * tuple(e1.a, e1.b, e1.c) - */ -+ e1 = e1->semantic(sc); - Expressions *exps = new Expressions; -+ Expression *e0 = NULL; - Expression *ev = e1; -+ if (sc->func && e1->hasSideEffect()) -+ { -+ Identifier *id = Lexer::uniqueId("__tup"); -+ ExpInitializer *ei = new ExpInitializer(e1->loc, e1); -+ VarDeclaration *v = new VarDeclaration(e1->loc, NULL, id, ei); -+ v->storage_class |= STCctfe; -+ if (e1->isLvalue()) -+ v->storage_class |= STCref | STCforeach; -+ e0 = new DeclarationExp(e1->loc, v); -+ ev = new VarExp(e1->loc, v); -+ e0 = e0->semantic(sc); -+ ev = ev->semantic(sc); -+ } - - exps->reserve(tup->objects->dim); - for (size_t i = 0; i < tup->objects->dim; i++) -- { Object *o = (*tup->objects)[i]; -+ { RootObject *o = (*tup->objects)[i]; - Expression *e; - if (o->dyncast() == DYNCAST_EXPRESSION) - { -@@ -7038,20 +7947,7 @@ Expression *DotVarExp::semantic(Scope *s - if (e->op == TOKdsymbol) - { - Dsymbol *s = ((DsymbolExp *)e)->s; -- if (i == 0 && sc->func && tup->objects->dim > 1 && -- e1->hasSideEffect()) -- { -- Identifier *id = Lexer::uniqueId("__tup"); -- ExpInitializer *ei = new ExpInitializer(e1->loc, e1); -- VarDeclaration *v = new VarDeclaration(e1->loc, NULL, id, ei); -- v->storage_class |= STCctfe | STCref | STCforeach; -- -- ev = new VarExp(e->loc, v); -- e = new CommaExp(e1->loc, new DeclarationExp(e1->loc, v), ev); -- e = new DotVarExp(loc, e, s->isDeclaration()); -- } -- else -- e = new DotVarExp(loc, ev, s->isDeclaration()); -+ e = new DotVarExp(loc, ev, s->isDeclaration()); - } - } - else if (o->dyncast() == DYNCAST_DSYMBOL) -@@ -7069,7 +7965,7 @@ Expression *DotVarExp::semantic(Scope *s - } - exps->push(e); - } -- Expression *e = new TupleExp(loc, exps); -+ Expression *e = new TupleExp(loc, e0, exps); - e = e->semantic(sc); - return e; - } -@@ -7105,13 +8001,25 @@ Expression *DotVarExp::semantic(Scope *s - Dsymbol *vparent = var->toParent(); - AggregateDeclaration *ad = vparent ? vparent->isAggregateDeclaration() : NULL; - e1 = getRightThis(loc, sc, ad, e1, var); -- if (!sc->noaccesscheck) -- accessCheck(loc, sc, e1, var); -+ accessCheck(loc, sc, e1, var); - - VarDeclaration *v = var->isVarDeclaration(); -- Expression *e = expandVar(WANTvalue, v); -- if (e) -+ if (!PULL93 || v && (v->isDataseg() || (v->storage_class & STCmanifest))) -+ { -+ Expression *e = expandVar(WANTvalue, v); -+ if (e) -+ return e; -+ } -+ -+ if (v && v->isDataseg()) // fix bugzilla 8238 -+ { -+ // (e1, v) -+ accessCheck(loc, sc, e1, v); -+ VarExp *ve = new VarExp(loc, v); -+ Expression *e = new CommaExp(loc, e1, ve); -+ e = e->semantic(sc); - return e; -+ } - } - Dsymbol *s; - if (sc->func && !sc->intypeof && t1->hasPointers() && -@@ -7160,15 +8068,49 @@ int modifyFieldVar(Loc loc, Scope *sc, V - if (s) - fd = s->isFuncDeclaration(); - if (fd && -- ((fd->isCtorDeclaration() && var->storage_class & STCfield) || -- (fd->isStaticCtorDeclaration() && !(var->storage_class & STCfield))) && -+ ((fd->isCtorDeclaration() && var->isField()) || -+ (fd->isStaticCtorDeclaration() && !var->isField())) && - fd->toParent2() == var->toParent2() && - (!e1 || e1->op == TOKthis) - ) - { - var->ctorinit = 1; - //printf("setting ctorinit\n"); -- return TRUE; -+ int result = TRUE; -+ if (var->isField() && sc->fieldinit && !sc->intypeof) -+ { -+ assert(e1); -+ bool mustInit = (var->storage_class & STCnodefaultctor || -+ var->type->needsNested()); -+ -+ size_t dim = sc->fieldinit_dim; -+ AggregateDeclaration *ad = fd->isAggregateMember2(); -+ assert(ad); -+ size_t i; -+ for (i = 0; i < dim; i++) // same as findFieldIndexByName in ctfeexp.c ? -+ { -+ if (ad->fields[i] == var) -+ break; -+ } -+ assert(i < dim); -+ unsigned fi = sc->fieldinit[i]; -+ if (fi & CSXthis_ctor) -+ { -+ if (var->type->isMutable() && e1->type->isMutable()) -+ result = FALSE; -+ else -+ ::error(loc, "multiple field %s initialization", var->toChars()); -+ } -+ else if (sc->noctor || fi & CSXlabel) -+ { -+ if (!mustInit && var->type->isMutable() && e1->type->isMutable()) -+ result = FALSE; -+ else -+ ::error(loc, "field %s initializing not allowed in loops or after labels", var->toChars()); -+ } -+ sc->fieldinit[i] |= CSXthis_ctor; -+ } -+ return result; - } - else - { -@@ -7233,89 +8175,127 @@ Expression *DotTemplateInstanceExp::synt - return de; - } - --TemplateDeclaration *DotTemplateInstanceExp::getTempdecl(Scope *sc) -+bool DotTemplateInstanceExp::findTempDecl(Scope *sc) - { - #if LOGSEMANTIC -- printf("DotTemplateInstanceExp::getTempdecl('%s')\n", toChars()); -+ printf("DotTemplateInstanceExp::findTempDecl('%s')\n", toChars()); - #endif -- if (!ti->tempdecl) -+ if (ti->tempdecl) -+ return true; -+ -+ Expression *e = new DotIdExp(loc, e1, ti->name); -+ e = e->semantic(sc); -+ if (e->op == TOKdotexp) -+ e = ((DotExp *)e)->e2; -+ -+ Dsymbol *s = NULL; -+ switch (e->op) - { -- Expression *e = new DotIdExp(loc, e1, ti->name); -- e = e->semantic(sc); -- if (e->op == TOKdottd) -- { -- DotTemplateExp *dte = (DotTemplateExp *)e; -- ti->tempdecl = dte->td; -- } -- else if (e->op == TOKimport) -- { ScopeExp *se = (ScopeExp *)e; -- ti->tempdecl = se->sds->isTemplateDeclaration(); -- } -+ case TOKoverloadset: s = ((OverExp *)e)->vars; break; -+ case TOKdottd: s = ((DotTemplateExp *)e)->td; break; -+ case TOKimport: s = ((ScopeExp *)e)->sds; break; -+ case TOKdotvar: s = ((DotVarExp *)e)->var; break; -+ case TOKvar: s = ((VarExp *)e)->var; break; -+ default: return false; - } -- return ti->tempdecl; -+ return ti->updateTemplateDeclaration(sc, s); - } - - Expression *DotTemplateInstanceExp::semantic(Scope *sc) - { -+#if LOGSEMANTIC -+ printf("DotTemplateInstanceExp::semantic('%s')\n", toChars()); -+#endif -+ - // Indicate we need to resolve by UFCS. -- return semantic(sc, 0); -+ Expression *e = semanticY(sc, 1); -+ if (!e) -+ e = resolveUFCSProperties(sc, this); -+ return e; - } --Expression *DotTemplateInstanceExp::semantic(Scope *sc, int flag) -+ -+// Resolve e1.ident!tiargs without seeing UFCS. -+// If flag == 1, stop "not a property" error and return NULL. -+Expression *DotTemplateInstanceExp::semanticY(Scope *sc, int flag) - { - #if LOGSEMANTIC -- printf("DotTemplateInstanceExp::semantic('%s')\n", toChars()); -+ printf("DotTemplateInstanceExpY::semantic('%s')\n", toChars()); - #endif - -- UnaExp::semantic(sc); -- if (e1->op == TOKerror) -- return e1; -- -- Expression *e; - DotIdExp *die = new DotIdExp(loc, e1, ti->name); - -- if (flag || !e1->type || e1->op == TOKtype || -- (e1->op == TOKimport && ((ScopeExp *)e1)->sds->isModule())) -- { -- e = die->semantic(sc, 1); -- } -- else -+ Expression *e = die->semanticX(sc); -+ if (e == die) - { -+ e1 = die->e1; // take back -+ - Type *t1b = e1->type->toBasetype(); - if (t1b->ty == Tarray || t1b->ty == Tsarray || t1b->ty == Taarray || - t1b->ty == Tnull || (t1b->isTypeBasic() && t1b->ty != Tvoid)) - { -- /* No built-in type has templatized property, so can short cut. -+ /* No built-in type has templatized properties, so do shortcut. -+ * It is necessary in: 1024.max!"a < b" - */ -- return resolveUFCSProperties(sc, this); -+ if (flag) -+ return NULL; - } -- -- unsigned errors = global.startGagging(); -- e = die->semantic(sc, 1); -- Type *t = e1->type; -- if (global.endGagging(errors)) -+ e = die->semanticY(sc, flag); -+ if (flag && e && isDotOpDispatch(e)) - { -- errors = global.startGagging(); -- e = resolveUFCSProperties(sc, this); -- if (!global.endGagging(errors)) -- return e; -- -- // both lookups failed, lookup property again for better error message -- e->type = t; // restore type -- e = die->semantic(sc, 1); -+ /* opDispatch!tiargs would be a function template that needs IFTI, -+ * so it's not a template -+ */ -+ e = NULL; /* fall down to UFCS */ - } -+ if (flag && !e) -+ return NULL; - } -+ assert(e); - - L1: - if (e->op == TOKerror) - return e; -+ if (e->op == TOKdotvar) -+ { -+ DotVarExp *dve = (DotVarExp *)e; -+ FuncDeclaration *f = dve->var->isFuncDeclaration(); -+ if (f) -+ { -+ TemplateDeclaration *td = f->findTemplateDeclRoot(); -+ if (td) -+ { -+ e = new DotTemplateExp(dve->loc, dve->e1, td); -+ e = e->semantic(sc); -+ } -+ } -+ } -+ else if (e->op == TOKvar) -+ { -+ VarExp *ve = (VarExp *)e; -+ FuncDeclaration *f = ve->var->isFuncDeclaration(); -+ if (f) -+ { -+ TemplateDeclaration *td = f->findTemplateDeclRoot(); -+ if (td) -+ { -+ e = new ScopeExp(ve->loc, td); -+ e = e->semantic(sc); -+ } -+ } -+ } - if (e->op == TOKdottd) - { - if (ti->errors) - return new ErrorExp(); - DotTemplateExp *dte = (DotTemplateExp *)e; -- TemplateDeclaration *td = dte->td; - Expression *eleft = dte->e1; -- ti->tempdecl = td; -+ ti->tempdecl = dte->td; -+ if (!ti->semanticTiargs(sc)) -+ { -+ ti->inst = ti; -+ ti->inst->errors = true; -+ return new ErrorExp(); -+ } - if (ti->needsTypeInference(sc)) - { - e1 = eleft; // save result of semantic() -@@ -7327,7 +8307,7 @@ L1: - return new ErrorExp(); - Dsymbol *s = ti->inst->toAlias(); - Declaration *v = s->isDeclaration(); -- if (v) -+ if (v && (v->isFuncDeclaration() || v->isVarDeclaration())) - { - /* Fix for Bugzilla 4003 - * The problem is a class template member function v returning a reference to the same -@@ -7352,6 +8332,12 @@ L1: - e = e->semantic(sc); - return e; - } -+ if (eleft->op == TOKtype) -+ { -+ e = new DsymbolExp(loc, s); -+ e = e->semantic(sc); -+ return e; -+ } - e = new ScopeExp(loc, ti); - e = new DotExp(loc, eleft, e); - e = e->semantic(sc); -@@ -7371,9 +8357,39 @@ L1: - } - else if (e->op == TOKdotexp) - { DotExp *de = (DotExp *)e; -+ Expression *eleft = de->e1; - - if (de->e2->op == TOKoverloadset) - { -+ if (!findTempDecl(sc) || -+ !ti->semanticTiargs(sc)) -+ { -+ ti->inst = ti; -+ ti->inst->errors = true; -+ return new ErrorExp(); -+ } -+ if (ti->needsTypeInference(sc)) -+ { -+ e1 = eleft; -+ return this; -+ } -+ else -+ ti->semantic(sc); -+ if (!ti->inst) // if template failed to expand -+ return new ErrorExp(); -+ Dsymbol *s = ti->inst->toAlias(); -+ Declaration *v = s->isDeclaration(); -+ if (v) -+ { -+ if (v->type && !v->type->deco) -+ v->type = v->type->semantic(v->loc, sc); -+ e = new DotVarExp(loc, eleft, v); -+ e = e->semantic(sc); -+ return e; -+ } -+ e = new ScopeExp(loc, ti); -+ e = new DotExp(loc, eleft, e); -+ e = e->semantic(sc); - return e; - } - -@@ -7396,6 +8412,14 @@ L1: - goto Lerr; - goto L1; - } -+ else if (e->op == TOKoverloadset) -+ { -+ OverExp *oe = (OverExp *)e; -+ ti->tempdecl = oe->vars; -+ e = new ScopeExp(loc, ti); -+ e = e->semantic(sc); -+ return e; -+ } - Lerr: - error("%s isn't a template", e->toChars()); - return new ErrorExp(); -@@ -7410,7 +8434,7 @@ void DotTemplateInstanceExp::toCBuffer(O - - /************************************************************/ - --DelegateExp::DelegateExp(Loc loc, Expression *e, FuncDeclaration *f, int hasOverloads) -+DelegateExp::DelegateExp(Loc loc, Expression *e, FuncDeclaration *f, bool hasOverloads) - : UnaExp(loc, TOKdelegate, sizeof(DelegateExp), e) - { - this->func = f; -@@ -7517,136 +8541,13 @@ Expression *CallExp::syntaxCopy() - return new CallExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments)); - } - -- --Expression *CallExp::resolveUFCS(Scope *sc) --{ -- Expression *e; -- Identifier *ident; -- Objects *tiargs; -- -- if (e1->op == TOKdot) -- { -- DotIdExp *die = (DotIdExp *)e1; -- e = (die->e1 = die->e1->semantic(sc)); -- ident = die->ident; -- tiargs = NULL; -- } -- else if (e1->op == TOKdotti) -- { -- DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)e1; -- e = (dti->e1 = dti->e1->semantic(sc)); -- ident = dti->ti->name; -- tiargs = dti->ti->tiargs; -- } -- else -- return NULL; -- -- if (e->op == TOKerror || !e->type) -- return NULL; -- -- if (e->op == TOKtype || e->op == TOKimport || e->op == TOKdotexp) -- return NULL; -- -- e = resolveProperties(sc, e); -- -- Type *t = e->type->toBasetype(); -- //printf("resolveUCSS %s, e = %s, %s, %s\n", -- // toChars(), Token::toChars(e->op), t->toChars(), e->toChars()); -- if (t->ty == Taarray) -- { -- if (tiargs) -- { -- goto Lshift; -- } -- else if (ident == Id::remove) -- { -- /* Transform: -- * aa.remove(arg) into delete aa[arg] -- */ -- if (!arguments || arguments->dim != 1) -- { error("expected key as argument to aa.remove()"); -- return new ErrorExp(); -- } -- if (!e->type->isMutable()) -- { error("cannot remove key from %s associative array %s", MODtoChars(e->type->mod), e->toChars()); -- return new ErrorExp(); -- } -- Expression *key = (*arguments)[0]; -- key = key->semantic(sc); -- key = resolveProperties(sc, key); -- -- TypeAArray *taa = (TypeAArray *)t; -- key = key->implicitCastTo(sc, taa->index); -- -- if (!key->rvalue()) -- return new ErrorExp(); -- -- return new RemoveExp(loc, e, key); -- } -- else if (ident == Id::apply || ident == Id::applyReverse) -- { -- return NULL; -- } -- else -- { TypeAArray *taa = (TypeAArray *)t; -- assert(taa->ty == Taarray); -- StructDeclaration *sd = taa->getImpl(); -- Dsymbol *s = sd->search(0, ident, 2); -- if (s) -- return NULL; -- goto Lshift; -- } -- } -- else if (t->ty == Tarray || t->ty == Tsarray || -- t->ty == Tnull || (t->isTypeBasic() && t->ty != Tvoid)) -- { -- /* In basic, built-in types don't have normal and templatized -- * member functions. So can short cut. -- */ --Lshift: -- if (!arguments) -- arguments = new Expressions(); -- arguments->shift(e); -- if (!tiargs) -- { -- /* Transform: -- * array.id(args) into .id(array,args) -- */ -- e1 = new DotIdExp(e1->loc, -- new IdentifierExp(e1->loc, Id::empty), -- ident); -- } -- else -- { -- /* Transform: -- * array.foo!(tiargs)(args) into .foo!(tiargs)(array,args) -- */ -- e1 = new DotTemplateInstanceExp(e1->loc, -- new IdentifierExp(e1->loc, Id::empty), -- ident, tiargs); -- } -- } -- else -- { -- DotIdExp *die = new DotIdExp(e->loc, e, ident); -- -- unsigned errors = global.startGagging(); -- Expression *ex = die->semantic(sc, 1); -- if (global.endGagging(errors)) -- { -- goto Lshift; -- } -- } -- return NULL; --} -- - Expression *CallExp::semantic(Scope *sc) - { - Type *t1; - int istemp; -- Objects *targsi = NULL; // initial list of template arguments -- TemplateInstance *tierror = NULL; -+ Objects *tiargs = NULL; // initial list of template arguments - Expression *ethis = NULL; -+ Type *tthis = NULL; - - #if LOGSEMANTIC - printf("CallExp::semantic() %s\n", toChars()); -@@ -7663,10 +8564,10 @@ Expression *CallExp::semantic(Scope *sc) - #endif - - if (e1->op == TOKcomma) -- { /* Rewrite (a,b)(args) as (a,(b(args))) -+ { -+ /* Rewrite (a,b)(args) as (a,(b(args))) - */ - CommaExp *ce = (CommaExp *)e1; -- - e1 = ce->e2; - e1->type = ce->type; - ce->e2 = this; -@@ -7675,15 +8576,15 @@ Expression *CallExp::semantic(Scope *sc) - } - - if (e1->op == TOKdelegate) -- { DelegateExp *de = (DelegateExp *)e1; -- -+ { -+ DelegateExp *de = (DelegateExp *)e1; - e1 = new DotVarExp(de->loc, de->e1, de->func); - return semantic(sc); - } - - if (e1->op == TOKfunction) -- { FuncExp *fe = (FuncExp *)e1; -- -+ { -+ FuncExp *fe = (FuncExp *)e1; - arguments = arrayExpressionSemantic(arguments, sc); - preFunctionParameters(loc, sc, arguments); - e1 = fe->semantic(sc, arguments); -@@ -7691,7 +8592,7 @@ Expression *CallExp::semantic(Scope *sc) - return e1; - } - -- Expression *e = resolveUFCS(sc); -+ Expression *e = resolveUFCS(sc, this); - if (e) - return e; - -@@ -7706,21 +8607,29 @@ Expression *CallExp::semantic(Scope *sc) - /* Attempt to instantiate ti. If that works, go with it. - * If not, go with partial explicit specialization. - */ -- unsigned olderrors = global.errors; -- ti->semanticTiargs(sc); -- if (olderrors != global.errors) -+ if (!ti->findTemplateDeclaration(sc) || -+ !ti->semanticTiargs(sc)) -+ { -+ ti->inst = ti; -+ ti->inst->errors = true; - return new ErrorExp(); -- if (ti->needsTypeInference(sc)) -+ } -+ if (ti->needsTypeInference(sc, 1)) - { - /* Go with partial explicit specialization - */ -- targsi = ti->tiargs; -- tierror = ti; // for error reporting -- e1 = new IdentifierExp(loc, ti->name); -+ tiargs = ti->tiargs; -+ assert(ti->tempdecl); -+ if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration()) -+ e1 = new TemplateExp(loc, td); -+ else -+ e1 = new OverExp(loc, ti->tempdecl->isOverloadSet()); - } - else - { - ti->semantic(sc); -+ if (ti->errors) -+ e1 = new ErrorExp(); - } - } - } -@@ -7737,18 +8646,23 @@ Ldotti: - /* Attempt to instantiate ti. If that works, go with it. - * If not, go with partial explicit specialization. - */ -- ti->semanticTiargs(sc); -- if (!ti->tempdecl) -+ if (!se->findTempDecl(sc) || -+ !ti->semanticTiargs(sc)) - { -- se->getTempdecl(sc); -+ ti->inst = ti; -+ ti->inst->errors = true; -+ return new ErrorExp(); - } -- if (ti->tempdecl && ti->needsTypeInference(sc)) -+ if (ti->needsTypeInference(sc, 1)) - { - /* Go with partial explicit specialization - */ -- targsi = ti->tiargs; -- tierror = ti; // for error reporting -- e1 = new DotIdExp(loc, se->e1, ti->name); -+ tiargs = ti->tiargs; -+ assert(ti->tempdecl); -+ if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration()) -+ e1 = new DotTemplateExp(loc, se->e1, td); -+ else -+ e1 = new DotExp(loc, se->e1, new OverExp(loc, ti->tempdecl->isOverloadSet())); - } - else - { -@@ -7828,6 +8742,7 @@ Lagain: - if (de->e2->op == TOKoverloadset) - { - ethis = de->e1; -+ tthis = de->e1->type; - e1 = de->e2; - } - -@@ -7849,23 +8764,30 @@ Lagain: - if (e1->type) - t1 = e1->type->toBasetype(); - -+ arguments = arrayExpressionSemantic(arguments, sc); -+ preFunctionParameters(loc, sc, arguments); -+ - // Check for call operator overload - if (t1) -- { AggregateDeclaration *ad; -- -+ { -+ AggregateDeclaration *ad; - if (t1->ty == Tstruct) - { - ad = ((TypeStruct *)t1)->sym; - #if DMDV2 - -- if (ad->sizeok == SIZEOKnone && !ad->ctor && -- ad->search(0, Id::ctor, 0)) -+ if (ad->sizeok == SIZEOKnone) - { -- // The constructor hasn't been found yet, see bug 8741 -- // This can happen if we are inferring type from -- // from VarDeclaration::semantic() in declaration.c -- error("cannot create a struct until its size is determined"); -- return new ErrorExp(); -+ if (ad->scope) -+ ad->semantic(ad->scope); -+ else if (!ad->ctor && ad->search(Loc(), Id::ctor, 0)) -+ { -+ // The constructor hasn't been found yet, see bug 8741 -+ // This can happen if we are inferring type from -+ // from VarDeclaration::semantic() in declaration.c -+ error("cannot create a struct until its size is determined"); -+ return new ErrorExp(); -+ } - } - - // First look for constructor -@@ -7877,26 +8799,32 @@ Lagain: - ExpInitializer *ei = NULL; - if (t1->needsNested()) - { -- Expressions *args = new Expressions(); -- StructLiteralExp *se = new StructLiteralExp(loc, (StructDeclaration *)ad, args); -- se->ctorinit = 1; -- ei = new ExpInitializer(loc, se); -+ StructLiteralExp *sle = new StructLiteralExp(loc, (StructDeclaration *)ad, NULL, e1->type); -+ Expression *e = sle->fill(true); -+ if (e->op == TOKerror) -+ return e; -+ sle->type = type; -+ ei = new ExpInitializer(loc, sle); - } -- - VarDeclaration *tmp = new VarDeclaration(loc, t1, idtmp, ei); - tmp->storage_class |= STCctfe; -- Expression *av = new DeclarationExp(loc, tmp); -- av = new CommaExp(loc, av, new VarExp(loc, tmp)); - -- Expression *e; -- CtorDeclaration *cf = ad->ctor->isCtorDeclaration(); -- if (cf) -- e = new DotVarExp(loc, av, cf, 1); -- else -- { TemplateDeclaration *td = ad->ctor->isTemplateDeclaration(); -- assert(td); -- e = new DotTemplateExp(loc, av, td); -+ Expression *e = new DeclarationExp(loc, tmp); -+ e = new CommaExp(loc, e, new VarExp(loc, tmp)); -+ if (CtorDeclaration *cf = ad->ctor->isCtorDeclaration()) -+ { -+ e = new DotVarExp(loc, e, cf, 1); -+ } -+ else if (TemplateDeclaration *td = ad->ctor->isTemplateDeclaration()) -+ { -+ e = new DotTemplateExp(loc, e, td); - } -+ else if (OverloadSet *os = ad->ctor->isOverloadSet()) -+ { -+ e = new DotExp(loc, e, new OverExp(loc, os)); -+ } -+ else -+ assert(0); - e = new CallExp(loc, e, arguments); - e = e->semantic(sc); - return e; -@@ -7908,8 +8836,10 @@ Lagain: - - if (e1->op != TOKtype) - { -- if (ad->aliasthis) -+ if (ad->aliasthis && e1->type != att1) - { -+ if (!att1 && e1->type->checkAliasThisRec()) -+ att1 = e1->type; - e1 = resolveAliasThis(sc, e1); - goto Lagain; - } -@@ -7936,9 +8866,6 @@ Lagain: - } - } - -- arguments = arrayExpressionSemantic(arguments, sc); -- preFunctionParameters(loc, sc, arguments); -- - // If there was an error processing any argument, or the call, - // return an error without trying to resolve the function call. - if (arguments && arguments->dim) -@@ -7954,10 +8881,10 @@ Lagain: - - // If there was an error processing any template argument, - // return an error without trying to resolve the template. -- if (targsi && targsi->dim) -+ if (tiargs && tiargs->dim) - { -- for (size_t k = 0; k < targsi->dim; k++) -- { Object *o = (*targsi)[k]; -+ for (size_t k = 0; k < tiargs->dim; k++) -+ { RootObject *o = (*tiargs)[k]; - if (isError(o)) - return new ErrorExp(); - } -@@ -7972,6 +8899,7 @@ Lagain: - UnaExp *ue = (UnaExp *)(e1); - - Expression *ue1 = ue->e1; -+ Expression *ue1old = ue1; // need for 'right this' check - VarDeclaration *v; - if (ue1->op == TOKvar && - (v = ((VarExp *)ue1)->var->isVarDeclaration()) != NULL && -@@ -7981,34 +8909,31 @@ Lagain: - ue1 = NULL; - } - -+ Dsymbol *s; - if (e1->op == TOKdotvar) -- { // Do overload resolution -+ { - dve = (DotVarExp *)(e1); -- -- f = dve->var->isFuncDeclaration(); -- assert(f); -- f = f->overloadResolve(loc, ue1, arguments); -- -- ad = f->toParent()->isAggregateDeclaration(); -+ s = dve->var; -+ tiargs = NULL; - } - else - { dte = (DotTemplateExp *)(e1); -- TemplateDeclaration *td = dte->td; -- assert(td); -- if (!arguments) -- // Should fix deduceFunctionTemplate() so it works on NULL argument -- arguments = new Expressions(); -- f = td->deduceFunctionTemplate(sc, loc, targsi, ue1, arguments); -- if (!f) -- return new ErrorExp(); -- ad = td->toParent()->isAggregateDeclaration(); -+ s = dte->td; - } -+ -+ // Do overload resolution -+ f = resolveFuncCall(loc, sc, s, tiargs, ue1 ? ue1->type : NULL, arguments); -+ if (!f) -+ return new ErrorExp(); -+ ad = f->toParent2()->isAggregateDeclaration(); -+ - if (f->needThis()) - { - ue->e1 = getRightThis(loc, sc, ad, ue->e1, f); - if (ue->e1->op == TOKerror) - return ue->e1; - ethis = ue->e1; -+ tthis = ue->e1->type; - } - - /* Cannot call public functions from inside invariant -@@ -8040,6 +8965,7 @@ Lagain: - } - else - { -+ checkRightThis(sc, ue1old); - if (e1->op == TOKdotvar) - { - dve->var = f; -@@ -8049,6 +8975,8 @@ Lagain: - { - e1 = new DotVarExp(loc, dte->e1, f); - e1 = e1->semantic(sc); -+ if (e1->op == TOKerror) -+ return new ErrorExp(); - ue = (UnaExp *)e1; - } - #if 0 -@@ -8102,7 +9030,8 @@ Lagain: - sc->callSuper |= CSXany_ctor | CSXsuper_ctor; - } - -- f = resolveFuncCall(sc, loc, cd->baseClass->ctor, NULL, NULL, arguments, 0); -+ tthis = cd->type->addMod(sc->func->type->mod); -+ f = resolveFuncCall(loc, sc, cd->baseClass->ctor, NULL, tthis, arguments, 0); - if (!f) - return new ErrorExp(); - accessCheck(loc, sc, NULL, f); -@@ -8142,7 +9071,8 @@ Lagain: - sc->callSuper |= CSXany_ctor | CSXthis_ctor; - } - -- f = resolveFuncCall(sc, loc, cd->ctor, NULL, NULL, arguments, 0); -+ tthis = cd->type->addMod(sc->func->type->mod); -+ f = resolveFuncCall(loc, sc, cd->ctor, NULL, tthis, arguments, 0); - if (!f) - return new ErrorExp(); - checkDeprecated(sc, f); -@@ -8169,16 +9099,9 @@ Lagain: - Dsymbol *s = NULL; - for (size_t i = 0; i < eo->vars->a.dim; i++) - { s = eo->vars->a[i]; -- FuncDeclaration *f2 = s->isFuncDeclaration(); -- if (f2) -- { -- f2 = f2->overloadResolve(loc, ethis, arguments, 1); -- } -- else -- { TemplateDeclaration *td = s->isTemplateDeclaration(); -- assert(td); -- f2 = td->deduceFunctionTemplate(sc, loc, targsi, ethis, arguments, 1); -- } -+ if (tiargs && s->isFuncDeclaration()) -+ continue; -+ FuncDeclaration *f2 = resolveFuncCall(loc, sc, s, tiargs, tthis, arguments, 1); - if (f2) - { if (f) - /* Error if match in more than one overload set, -@@ -8210,6 +9133,7 @@ Lagain: - { - TypeFunction *tf; - const char *p; -+ f = NULL; - if (e1->op == TOKfunction) - { - // function literal that direct called is always inferred. -@@ -8217,11 +9141,10 @@ Lagain: - f = ((FuncExp *)e1)->fd; - tf = (TypeFunction *)f->type; - p = "function literal"; -- -- f->checkNestedReference(sc, loc); - } - else if (t1->ty == Tdelegate) -- { TypeDelegate *td = (TypeDelegate *)t1; -+ { -+ TypeDelegate *td = (TypeDelegate *)t1; - assert(td->next->ty == Tfunction); - tf = (TypeFunction *)(td->next); - p = "delegate"; -@@ -8234,12 +9157,9 @@ Lagain: - else if (e1->op == TOKtemplate) - { - TemplateExp *te = (TemplateExp *)e1; -- f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); -+ f = resolveFuncCall(loc, sc, te->td, tiargs, NULL, arguments); - if (!f) -- { if (tierror) -- tierror->error("errors instantiating template"); // give better error message - return new ErrorExp(); -- } - if (f->needThis()) - { - if (hasThis(sc)) -@@ -8250,9 +9170,9 @@ Lagain: - e1 = new DotTemplateExp(loc, (new ThisExp(loc))->semantic(sc), te->td); - goto Lagain; - } -- else if (!sc->intypeof && !sc->getStructClassScope()) -+ else if (isNeedThisScope(sc, f)) - { -- error("need 'this' for %s type %s", f->toChars(), f->type->toChars()); -+ error("need 'this' for '%s' of type '%s'", f->toChars(), f->type->toChars()); - return new ErrorExp(); - } - } -@@ -8261,19 +9181,9 @@ Lagain: - goto Lagain; - } - else -- { error("function expected before (), not %s of type %s", e1->toChars(), e1->type->toChars()); -- return new ErrorExp(); -- } -- -- if (sc->func && !tf->purity && !(sc->flags & SCOPEdebug)) -- { -- if (sc->func->setImpure()) -- error("pure function '%s' cannot call impure %s '%s'", sc->func->toPrettyChars(), p, e1->toChars()); -- } -- if (sc->func && tf->trust <= TRUSTsystem) - { -- if (sc->func->setUnsafe()) -- error("safe function '%s' cannot call system %s '%s'", sc->func->toPrettyChars(), p, e1->toChars()); -+ error("function expected before (), not %s of type %s", e1->toChars(), e1->type->toChars()); -+ return new ErrorExp(); - } - - if (!tf->callMatch(NULL, arguments)) -@@ -8287,8 +9197,8 @@ Lagain: - - argExpTypesToCBuffer(&buf, arguments, &hgs); - buf.writeByte(')'); -- if (ethis) -- ethis->type->modToBuffer(&buf); -+ if (tthis) -+ tthis->modToBuffer(&buf); - } - else - buf.writeByte(')'); -@@ -8301,6 +9211,29 @@ Lagain: - return new ErrorExp(); - } - -+ // Purity and safety check should run after testing arguments matching -+ if (f) -+ { -+#if DMDV2 -+ checkPurity(sc, f); -+ checkSafety(sc, f); -+#endif -+ f->checkNestedReference(sc, loc); -+ } -+ else if (sc->func && !(sc->flags & SCOPEctfe)) -+ { -+ if (!tf->purity && !(sc->flags & SCOPEdebug) && sc->func->setImpure()) -+ { -+ error("pure function '%s' cannot call impure %s '%s'", sc->func->toPrettyChars(), p, e1->toChars()); -+ return new ErrorExp(); -+ } -+ if (tf->trust <= TRUSTsystem && sc->func->setUnsafe()) -+ { -+ error("safe function '%s' cannot call system %s '%s'", sc->func->toPrettyChars(), p, e1->toChars()); -+ return new ErrorExp(); -+ } -+ } -+ - if (t1->ty == Tpointer) - { - Expression *e = new PtrExp(loc, e1); -@@ -8316,11 +9249,13 @@ Lagain: - - f = ve->var->isFuncDeclaration(); - assert(f); -+ tiargs = NULL; - - if (ve->hasOverloads) -- f = f->overloadResolve(loc, NULL, arguments, 2); -+ f = resolveFuncCall(loc, sc, f, tiargs, NULL, arguments, 2); - else - { -+ f = f->toAliasFunc(); - TypeFunction *tf = (TypeFunction *)f->type; - if (!tf->callMatch(NULL, arguments)) - { -@@ -8343,6 +9278,8 @@ Lagain: - return new ErrorExp(); - } - } -+ if (!f) -+ return new ErrorExp(); - - if (f->needThis()) - { -@@ -8354,9 +9291,9 @@ Lagain: - e1 = new DotVarExp(loc, (new ThisExp(loc))->semantic(sc), ve->var); - goto Lagain; - } -- else if (!sc->intypeof && !sc->getStructClassScope()) -+ else if (isNeedThisScope(sc, f)) - { -- error("need 'this' for %s type %s", f->toChars(), f->type->toChars()); -+ error("need 'this' for '%s' of type '%s'", f->toChars(), f->type->toChars()); - return new ErrorExp(); - } - } -@@ -8370,10 +9307,13 @@ Lagain: - accessCheck(loc, sc, NULL, f); - - ethis = NULL; -+ tthis = NULL; - -- ve->var = f; --// ve->hasOverloads = 0; -- ve->type = f->type; -+ if (ve->hasOverloads) -+ { -+ e1 = new VarExp(ve->loc, f, 0); -+ e1->type = f->type; -+ } - t1 = f->type; - } - assert(t1->ty == Tfunction); -@@ -8382,7 +9322,7 @@ Lagain: - if (!arguments) - arguments = new Expressions(); - int olderrors = global.errors; -- type = functionParameters(loc, sc, tf, ethis, arguments, f); -+ type = functionParameters(loc, sc, tf, tthis, arguments, f); - if (olderrors != global.errors) - return new ErrorExp(); - -@@ -8405,6 +9345,13 @@ Lagain: - } - } - -+ // Handle the case of a direct lambda call -+ if (f && f->isFuncLiteralDeclaration() && -+ sc->func && !sc->intypeof) -+ { -+ f->tookAddressOf = 0; -+ } -+ - return this; - } - -@@ -8445,16 +9392,14 @@ Expression *CallExp::addDtorHook(Scope * - return this; - } - -- Type *tv = type->toBasetype(); -- while (tv->ty == Tsarray) -- { TypeSArray *ta = (TypeSArray *)tv; -- tv = tv->nextOf()->toBasetype(); -- } -+ Type *tv = type->baseElemOf(); - if (tv->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)tv; -+ { -+ TypeStruct *ts = (TypeStruct *)tv; - StructDeclaration *sd = ts->sym; - if (sd->dtor) -- { /* Type needs destruction, so declare a tmp -+ { -+ /* Type needs destruction, so declare a tmp - * which the back end will recognize and call dtor on - */ - Identifier *idtmp = Lexer::uniqueId("__tmpfordtor"); -@@ -8466,7 +9411,6 @@ Expression *CallExp::addDtorHook(Scope * - return e; - } - } --Lnone: - return this; - } - -@@ -8502,10 +9446,42 @@ Expression *AddrExp::semantic(Scope *sc) - if (!type) - { - UnaExp::semantic(sc); -- Expression *olde1 = e1; - if (e1->type == Type::terror) - return new ErrorExp(); - int wasCond = e1->op == TOKquestion; -+ if (e1->op == TOKdotti) -+ { -+ DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1; -+ TemplateInstance *ti = dti->ti; -+ if (!ti->semanticRun) -+ { -+ //assert(ti->needsTypeInference(sc)); -+ ti->semantic(sc); -+ if (!ti->inst) // if template failed to expand -+ return new ErrorExp; -+ Dsymbol *s = ti->inst->toAlias(); -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ assert(f); -+ e1 = new DotVarExp(e1->loc, dti->e1, f); -+ e1 = e1->semantic(sc); -+ } -+ } -+ else if (e1->op == TOKimport) -+ { -+ TemplateInstance *ti = ((ScopeExp *)e1)->sds->isTemplateInstance(); -+ if (ti && !ti->semanticRun) -+ { -+ //assert(ti->needsTypeInference(sc)); -+ ti->semantic(sc); -+ if (!ti->inst) // if template failed to expand -+ return new ErrorExp; -+ Dsymbol *s = ti->inst->toAlias(); -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ assert(f); -+ e1 = new VarExp(e1->loc, f); -+ e1 = e1->semantic(sc); -+ } -+ } - e1 = e1->toLvalue(sc, NULL); - if (e1->op == TOKerror) - return e1; -@@ -8541,9 +9517,9 @@ Expression *AddrExp::semantic(Scope *sc) - { - DotVarExp *dve = (DotVarExp *)e1; - FuncDeclaration *f = dve->var->isFuncDeclaration(); -- - if (f) - { -+ f = f->toAliasFunc(); // FIXME, should see overlods - Bugzilla 1983 - if (!dve->hasOverloads) - f->tookAddressOf++; - -@@ -8581,7 +9557,6 @@ Expression *AddrExp::semantic(Scope *sc) - } - - FuncDeclaration *f = ve->var->isFuncDeclaration(); -- - if (f) - { - if (!ve->hasOverloads || -@@ -8637,6 +9612,7 @@ Expression *AddrExp::semantic(Scope *sc) - ce->e2->type = NULL; - ce->e2 = ce->e2->semantic(sc); - } -+ - return optimize(WANTvalue); - } - return this; -@@ -8827,6 +9803,8 @@ Expression *NotExp::semantic(Scope *sc) - UnaExp::semantic(sc); - e1 = resolveProperties(sc, e1); - e1 = e1->checkToBoolean(sc); -+ if (e1->type == Type::terror) -+ return e1; - type = Type::tboolean; - } - return this; -@@ -8854,6 +9832,8 @@ Expression *BoolExp::semantic(Scope *sc) - UnaExp::semantic(sc); - e1 = resolveProperties(sc, e1); - e1 = e1->checkToBoolean(sc); -+ if (e1->type == Type::terror) -+ return e1; - type = Type::tboolean; - } - return this; -@@ -8928,7 +9908,7 @@ Expression *DeleteExp::semantic(Scope *s - - if (fd) - { Expression *e = ea ? new VarExp(loc, v) : e1; -- e = new DotVarExp(0, e, fd, 0); -+ e = new DotVarExp(Loc(), e, fd, 0); - eb = new CallExp(loc, e); - eb = eb->semantic(sc); - } -@@ -9026,10 +10006,10 @@ Expression *CastExp::semantic(Scope *sc) - if (type) - return this; - UnaExp::semantic(sc); -+ e1 = resolveProperties(sc, e1); -+ - if (e1->type) // if not a tuple - { -- e1 = resolveProperties(sc, e1); -- - if (!to) - { - /* Handle cast(const) and cast(immutable), etc. -@@ -9048,6 +10028,10 @@ Expression *CastExp::semantic(Scope *sc) - if (e1->type->ty == Terror) - return new ErrorExp(); - -+ // cast(void) is used to mark e1 as unused, so it is safe -+ if (to->ty == Tvoid) -+ goto Lsafe; -+ - if (!to->equals(e1->type)) - { - Expression *e = op_overload(sc); -@@ -9089,15 +10073,19 @@ Expression *CastExp::semantic(Scope *sc) - if (tob->ty == Tstruct || t1b->ty == Tstruct || - (tob->ty == Tsarray && t1b->ty == Tsarray)) - { -- size_t fromsize = t1b->size(loc); -- size_t tosize = tob->size(loc); -- if (fromsize != tosize) -+ if (t1b->ty == Tnull || tob->ty == Tnull || t1b->size(loc) != tob->size(loc)) - { - error("cannot cast from %s to %s", e1->type->toChars(), to->toChars()); - return new ErrorExp(); - } - } - -+ if ((t1b->ty == Tarray || t1b->ty == Tsarray) && tob->ty == Tclass) -+ { -+ error("cannot cast from %s to %s", e1->type->toChars(), to->toChars()); -+ return new ErrorExp(); -+ } -+ - // Look for casting to a vector type - if (tob->ty == Tvector && t1b->ty != Tvector) - { -@@ -9105,7 +10093,19 @@ Expression *CastExp::semantic(Scope *sc) - } - - if (tob->isintegral() && t1b->ty == Tarray) -- deprecation("casting %s to %s is deprecated", e1->type->toChars(), to->toChars()); -+ { -+ error("cannot cast %s to integral type %s", e1->toChars(), to->toChars()); -+ return new ErrorExp(); -+ } -+ -+ if (tob->ty == Tpointer && t1b->ty == Tdelegate) -+ deprecation("casting from %s to %s is deprecated", e1->type->toChars(), to->toChars()); -+ -+ if (t1b->ty == Tvoid && tob->ty != Tvoid && e1->op != TOKfunction) -+ { -+ error("cannot cast %s of type %s to %s", e1->toChars(), e1->type->toChars(), to->toChars()); -+ return new ErrorExp(); -+ } - } - else if (!to) - { error("cannot cast tuple"); -@@ -9164,7 +10164,10 @@ Expression *CastExp::semantic(Scope *sc) - { - Type* tobn = tob->nextOf()->toBasetype(); - Type* t1bn = t1b->nextOf()->toBasetype(); -- if (!tobn->hasPointers() && -+ // If the struct is opaque we don't know about the struct members and the cast becomes unsafe -+ bool sfwrd = tobn->ty == Tstruct && !((StructDeclaration *)((TypeStruct *)tobn)->sym)->members || -+ t1bn->ty == Tstruct && !((StructDeclaration *)((TypeStruct *)t1bn)->sym)->members; -+ if (!sfwrd && !tobn->hasPointers() && - tobn->ty != Tfunction && t1bn->ty != Tfunction && - tobn->size() <= t1bn->size() && - MODimplicitConv(t1bn->mod, tobn->mod)) -@@ -9179,6 +10182,16 @@ Expression *CastExp::semantic(Scope *sc) - } - - Lsafe: -+#if DMDV2 -+ /* Instantiate AA implementations during semantic analysis. -+ */ -+ Type *tfrom = e1->type->toBasetype(); -+ Type *t = to->toBasetype(); -+ if (tfrom->ty == Taarray) -+ ((TypeAArray *)tfrom)->getImpl(); -+ if (t->ty == Taarray) -+ ((TypeAArray *)t)->getImpl(); -+#endif - Expression *e = e1->castTo(sc, to); - return e; - } -@@ -9309,6 +10322,26 @@ Lagain: - e = new TypeExp(loc, e1->type->arrayOf()); - return e->semantic(sc); - } -+ if (!lwr && !upr) -+ { -+ if (e1->op == TOKarrayliteral) -+ { // Convert [a,b,c][] to [a,b,c] -+ Type *t1b = e1->type->toBasetype(); -+ Expression *e = e1; -+ if (t1b->ty == Tsarray) -+ { -+ e = e->copy(); -+ e->type = t1b->nextOf()->arrayOf(); -+ } -+ return e; -+ } -+ if (e1->op == TOKslice) -+ { // Convert e[][] to e[] -+ SliceExp *se = (SliceExp *)e1; -+ if (!se->lwr && !se->upr) -+ return se; -+ } -+ } - - e = this; - -@@ -9319,6 +10352,8 @@ Lagain: - { error("need upper and lower bound to slice pointer"); - return new ErrorExp(); - } -+ if (sc->func && !sc->intypeof && sc->func->setUnsafe()) -+ error("pointer slicing not allowed in safe functions"); - } - else if (t->ty == Tarray) - { -@@ -9339,20 +10374,24 @@ Lagain: - if (search_function(ad, Id::slice)) - { - // Rewrite as e1.slice(lwr, upr) -- SliceExp *se = resolveOpDollar(sc, this); -+ Expression *e0 = resolveOpDollar(sc, this); - Expressions *a = new Expressions(); -- assert(!se->lwr || se->upr); -- if (se->lwr) -- { a->push(se->lwr); -- a->push(se->upr); -+ assert(!lwr || upr); -+ if (lwr) -+ { -+ a->push(lwr); -+ a->push(upr); - } -- e = new DotIdExp(loc, se->e1, Id::slice); -+ e = new DotIdExp(loc, e1, Id::slice); - e = new CallExp(loc, e, a); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } -- if (ad->aliasthis) -+ if (ad->aliasthis && e1->type != att1) - { -+ if (!att1 && e1->type->checkAliasThisRec()) -+ att1 = e1->type; - e1 = resolveAliasThis(sc, e1); - goto Lagain; - } -@@ -9383,15 +10422,21 @@ Lagain: - } - - if (lwr) -- { lwr = lwr->semantic(sc2); -+ { -+ if (t->ty == Ttuple) sc2 = sc2->startCTFE(); -+ lwr = lwr->semantic(sc2); - lwr = resolveProperties(sc2, lwr); -+ if (t->ty == Ttuple) sc2 = sc2->endCTFE(); - lwr = lwr->implicitCastTo(sc2, Type::tsize_t); - if (lwr->type == Type::terror) - goto Lerr; - } - if (upr) -- { upr = upr->semantic(sc2); -+ { -+ if (t->ty == Ttuple) sc2 = sc2->startCTFE(); -+ upr = upr->semantic(sc2); - upr = resolveProperties(sc2, upr); -+ if (t->ty == Ttuple) sc2 = sc2->endCTFE(); - upr = upr->implicitCastTo(sc2, Type::tsize_t); - if (upr->type == Type::terror) - goto Lerr; -@@ -9434,13 +10479,7 @@ Lagain: - { Expression *e = (*te->exps)[j1 + i]; - (*exps)[i] = e; - } -- if (j1 > 0 && j1 != j2 && sc->func && (*te->exps)[0]->op == TOKdotvar) -- { -- Expression *einit = ((DotVarExp *)(*te->exps)[0])->e1->isTemp(); -- if (einit) -- ((DotVarExp *)(*exps)[0])->e1 = einit; -- } -- e = new TupleExp(loc, exps); -+ e = new TupleExp(loc, te->e0, exps); - } - else - { Parameters *args = new Parameters; -@@ -9492,16 +10531,6 @@ void SliceExp::checkEscapeRef() - e1->checkEscapeRef(); - } - --int SliceExp::isLvalue() --{ -- return 1; --} -- --Expression *SliceExp::toLvalue(Scope *sc, Expression *e) --{ -- return this; --} -- - int SliceExp::checkModifiable(Scope *sc, int flag) - { - //printf("SliceExp::checkModifiable %s\n", toChars()); -@@ -9514,6 +10543,21 @@ int SliceExp::checkModifiable(Scope *sc, - return 1; - } - -+int SliceExp::isLvalue() -+{ -+ /* slice expression is rvalue in default, but -+ * conversion to reference of static array is only allowed. -+ */ -+ return (type && type->toBasetype()->ty == Tsarray); -+} -+ -+Expression *SliceExp::toLvalue(Scope *sc, Expression *e) -+{ -+ //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL); -+ return (type && type->toBasetype()->ty == Tsarray) -+ ? this : Expression::toLvalue(sc, e); -+} -+ - Expression *SliceExp::modifiableLvalue(Scope *sc, Expression *e) - { - error("slice expression %s is not a modifiable lvalue", toChars()); -@@ -9532,14 +10576,14 @@ void SliceExp::toCBuffer(OutBuffer *buf, - if (upr || lwr) - { - if (lwr) -- expToCBuffer(buf, hgs, lwr, PREC_assign); -+ sizeToCBuffer(buf, hgs, lwr); - else - buf->writeByte('0'); - buf->writestring(".."); - if (upr) -- expToCBuffer(buf, hgs, upr, PREC_assign); -+ sizeToCBuffer(buf, hgs, upr); - else -- buf->writestring("length"); // BUG: should be array.length -+ buf->writestring("$"); - } - buf->writeByte(']'); - } -@@ -9566,7 +10610,7 @@ Expression *ArrayLengthExp::semantic(Sco - return this; - } - --Expression *opAssignToOp(Loc loc, enum TOK op, Expression *e1, Expression *e2) -+Expression *opAssignToOp(Loc loc, TOK op, Expression *e1, Expression *e2) - { Expression *e; - - switch (op) -@@ -9815,6 +10859,7 @@ IndexExp::IndexExp(Loc loc, Expression * - //printf("IndexExp::IndexExp('%s')\n", toChars()); - lengthVar = NULL; - modifiable = 0; // assume it is an rvalue -+ skipboundscheck = 0; - } - - Expression *IndexExp::syntaxCopy() -@@ -9865,8 +10910,10 @@ Expression *IndexExp::semantic(Scope *sc - sc = sc->push(sym); - } - -+ if (t1->ty == Ttuple) sc = sc->startCTFE(); - e2 = e2->semantic(sc); - e2 = resolveProperties(sc, e2); -+ if (t1->ty == Ttuple) sc = sc->endCTFE(); - if (e2->type == Type::terror) - goto Lerr; - if (e2->type->ty == Ttuple && ((TupleExp *)e2)->exps->dim == 1) // bug 4444 fix -@@ -9879,10 +10926,12 @@ Expression *IndexExp::semantic(Scope *sc - { - case Tpointer: - e2 = e2->implicitCastTo(sc, Type::tsize_t); -+ if (e2->type == Type::terror) -+ goto Lerr; - e2 = e2->optimize(WANTvalue); - if (e2->op == TOKint64 && e2->toInteger() == 0) - ; -- else if (sc->func->setUnsafe()) -+ else if (sc->func && sc->func->setUnsafe()) - { - error("safe function '%s' cannot index pointer '%s'", - sc->func->toPrettyChars(), e1->toChars()); -@@ -9893,12 +10942,16 @@ Expression *IndexExp::semantic(Scope *sc - - case Tarray: - e2 = e2->implicitCastTo(sc, Type::tsize_t); -+ if (e2->type == Type::terror) -+ goto Lerr; - e->type = ((TypeNext *)t1)->next; - break; - - case Tsarray: - { - e2 = e2->implicitCastTo(sc, Type::tsize_t); -+ if (e2->type == Type::terror) -+ goto Lerr; - TypeSArray *tsa = (TypeSArray *)t1; - e->type = t1->nextOf(); - break; -@@ -9920,6 +10973,8 @@ Expression *IndexExp::semantic(Scope *sc - case Ttuple: - { - e2 = e2->implicitCastTo(sc, Type::tsize_t); -+ if (e2->type == Type::terror) -+ goto Lerr; - e2 = e2->ctfeInterpret(); - uinteger_t index = e2->toUInteger(); - size_t length; -@@ -9944,12 +10999,7 @@ Expression *IndexExp::semantic(Scope *sc - if (e1->op == TOKtuple) - { - e = (*te->exps)[(size_t)index]; -- if (sc->func && (*te->exps)[0]->op == TOKdotvar) -- { -- Expression *einit = ((DotVarExp *)(*te->exps)[0])->e1->isTemp(); -- if (einit) -- ((DotVarExp *)e)->e1 = einit; -- } -+ e = combine(te->e0, e); - } - else - e = new TypeExp(e1->loc, Parameter::getNth(tup->arguments, (size_t)index)->type); -@@ -9971,6 +11021,21 @@ Expression *IndexExp::semantic(Scope *sc - case Terror: - goto Lerr; - } -+ -+ if (t1->ty == Tsarray || t1->ty == Tarray) -+ { -+ Expression *el = new ArrayLengthExp(loc, e1); -+ el = el->semantic(sc); -+ el = el->optimize(WANTvalue); -+ if (el->op == TOKint64) -+ { -+ e2 = e2->optimize(WANTvalue); -+ dinteger_t length = el->toInteger(); -+ if (length) -+ skipboundscheck = IntRange(SignExtendedNumber(0), SignExtendedNumber(length)).contains(e2->getIntRange()); -+ } -+ } -+ - return e; - - Lerr: -@@ -10021,14 +11086,14 @@ void IndexExp::toCBuffer(OutBuffer *buf, - { - expToCBuffer(buf, hgs, e1, PREC_primary); - buf->writeByte('['); -- expToCBuffer(buf, hgs, e2, PREC_assign); -+ sizeToCBuffer(buf, hgs, e2); - buf->writeByte(']'); - } - - - /************************* PostExp ***********************************/ - --PostExp::PostExp(enum TOK op, Loc loc, Expression *e) -+PostExp::PostExp(TOK op, Loc loc, Expression *e) - : BinExp(loc, op, sizeof(PostExp), e, - new IntegerExp(loc, 1, Type::tint32)) - { -@@ -10037,6 +11102,9 @@ PostExp::PostExp(enum TOK op, Loc loc, E - Expression *PostExp::semantic(Scope *sc) - { Expression *e = this; - -+#if LOGSEMANTIC -+ printf("PostExp::semantic('%s')\n", toChars()); -+#endif - if (!type) - { - BinExp::semantic(sc); -@@ -10053,6 +11121,7 @@ Expression *PostExp::semantic(Scope *sc) - return new ErrorExp(); - } - -+ e1 = e1->optimize(WANTvalue); - if (e1->op != TOKarraylength) - e1 = e1->modifiableLvalue(sc, e1); - -@@ -10118,7 +11187,7 @@ void PostExp::toCBuffer(OutBuffer *buf, - - /************************* PreExp ***********************************/ - --PreExp::PreExp(enum TOK op, Loc loc, Expression *e) -+PreExp::PreExp(TOK op, Loc loc, Expression *e) - : UnaExp(loc, op, sizeof(PreExp), e) - { - } -@@ -10185,10 +11254,11 @@ Expression *AssignExp::semantic(Scope *s - { - ArrayExp *ae = (ArrayExp *)e1; - AggregateDeclaration *ad = NULL; -- Identifier *id = Id::index; - - ae->e1 = ae->e1->semantic(sc); - ae->e1 = resolveProperties(sc, ae->e1); -+ Expression *ae1old = ae->e1; -+ - Type *t1 = ae->e1->type->toBasetype(); - if (t1->ty == Tstruct) - { -@@ -10203,47 +11273,53 @@ Expression *AssignExp::semantic(Scope *s - if (search_function(ad, Id::indexass)) - { - // Deal with $ -- ae = resolveOpDollar(sc, ae); -+ Expression *e0 = resolveOpDollar(sc, ae); - Expressions *a = (Expressions *)ae->arguments->copy(); - a->insert(0, e2); - - Expression *e = new DotIdExp(loc, ae->e1, Id::indexass); - e = new CallExp(loc, e, a); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } - } - - // No opIndexAssign found yet, but there might be an alias this to try. -- if (ad && ad->aliasthis) -- { Expression *e = resolveAliasThis(sc, ae->e1); -- Type *t = e->type->toBasetype(); -- -- if (t->ty == Tstruct) -+ if (ad && ad->aliasthis && t1 != att1) -+ { -+ if (!att1 && t1->checkAliasThisRec()) -+ att1 = t1; -+ ae->e1 = resolveAliasThis(sc, ae->e1); -+ t1 = ae->e1->type->toBasetype(); -+ if (t1->ty == Tstruct) - { -- ad = ((TypeStruct *)t)->sym; -+ ad = ((TypeStruct *)t1)->sym; - goto L1; - } -- else if (t->ty == Tclass) -+ else if (t1->ty == Tclass) - { -- ad = ((TypeClass *)t)->sym; -+ ad = ((TypeClass *)t1)->sym; - goto L1; - } - } -+ -+ ae->e1 = ae1old; // restore - } - /* Look for operator overloading of a[i..j]=value. - * Do it before semantic() otherwise the a[i..j] will have been - * converted to a.opSlice() already. - */ - if (e1->op == TOKslice) -- { Type *t1; -+ { - SliceExp *ae = (SliceExp *)e1; - AggregateDeclaration *ad = NULL; -- Identifier *id = Id::index; - - ae->e1 = ae->e1->semantic(sc); - ae->e1 = resolveProperties(sc, ae->e1); -- t1 = ae->e1->type->toBasetype(); -+ Expression *ae1old = ae->e1; -+ -+ Type *t1 = ae->e1->type->toBasetype(); - if (t1->ty == Tstruct) - { - ad = ((TypeStruct *)t1)->sym; -@@ -10256,37 +11332,43 @@ Expression *AssignExp::semantic(Scope *s - // Rewrite (a[i..j] = value) to (a.opSliceAssign(value, i, j)) - if (search_function(ad, Id::sliceass)) - { -- ae = resolveOpDollar(sc, ae); -+ Expression *e0 = resolveOpDollar(sc, ae); - Expressions *a = new Expressions(); - a->push(e2); - assert(!ae->lwr || ae->upr); - if (ae->lwr) -- { a->push(ae->lwr); -+ { -+ a->push(ae->lwr); - a->push(ae->upr); - } - Expression *e = new DotIdExp(loc, ae->e1, Id::sliceass); - e = new CallExp(loc, e, a); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } - } - - // No opSliceAssign found yet, but there might be an alias this to try. -- if (ad && ad->aliasthis) -- { Expression *e = resolveAliasThis(sc, ae->e1); -- Type *t = e->type->toBasetype(); -- -- if (t->ty == Tstruct) -+ if (ad && ad->aliasthis && t1 != att1) -+ { -+ if (!att1 && t1->checkAliasThisRec()) -+ att1 = t1; -+ ae->e1 = resolveAliasThis(sc, ae->e1); -+ t1 = ae->e1->type->toBasetype(); -+ if (t1->ty == Tstruct) - { -- ad = ((TypeStruct *)t)->sym; -+ ad = ((TypeStruct *)t1)->sym; - goto L2; - } -- else if (t->ty == Tclass) -+ else if (t1->ty == Tclass) - { -- ad = ((TypeClass *)t)->sym; -+ ad = ((TypeClass *)t1)->sym; - goto L2; - } - } -+ -+ ae->e1 = ae1old; // restore - } - - /* With UFCS, e.f = value -@@ -10297,25 +11379,31 @@ Expression *AssignExp::semantic(Scope *s - */ - if (e1->op == TOKdotti) - { -- Expression *e = resolveProperty(sc, &e1, e2); -- if (e) return e; -+ DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)e1; -+ Expression *e = dti->semanticY(sc, 1); -+ if (!e) -+ return resolveUFCSProperties(sc, e1, e2); -+ e1 = e; - } - else if (e1->op == TOKdot) - { -- Expression *e = resolveProperty(sc, &e1, e2); -- if (e) return e; -- -- VarDeclaration * vd = NULL; -- if (e1->op == TOKvar) -- vd = ((VarExp *)e1)->var->isVarDeclaration(); -- -- if (vd && vd->needThis()) -+ DotIdExp *die = (DotIdExp *)e1; -+ Expression *e = die->semanticY(sc, 1); -+ if (e && isDotOpDispatch(e)) - { -- error("need 'this' to access member %s", e1->toChars()); -- return new ErrorExp(); -+ unsigned errors = global.startGagging(); -+ e = resolvePropertiesX(sc, e, e2); -+ if (global.endGagging(errors)) -+ e = NULL; /* fall down to UFCS */ -+ else -+ return e; - } -+ if (!e) -+ return resolveUFCSProperties(sc, e1, e2); -+ e1 = e; - } -- e1 = e1->semantic(sc); -+ else -+ e1 = e1->semantic(sc); - if (e1->op == TOKerror) - return new ErrorExp(); - -@@ -10325,113 +11413,10 @@ Expression *AssignExp::semantic(Scope *s - * or: - * f() = value - */ -- TemplateDeclaration *td; -- Objects *targsi; -- FuncDeclaration *fd; -- Expression *ethis; -- if (e1->op == TOKdotti) -- { -- DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1; -- td = dti->getTempdecl(sc); -- dti->ti->semanticTiargs(sc); -- targsi = dti->ti->tiargs; -- ethis = dti->e1; -- goto L3; -- } -- else if (e1->op == TOKdottd) -- { -- DotTemplateExp *dte = (DotTemplateExp *)e1; -- td = dte->td; -- targsi = NULL; -- ethis = dte->e1; -- goto L3; -- } -- else if (e1->op == TOKtemplate) -- { -- td = ((TemplateExp *)e1)->td; -- targsi = NULL; -- ethis = NULL; -- L3: -- { -- e2 = e2->semantic(sc); -- if (e2->op == TOKerror) -- return new ErrorExp(); -- e2 = resolveProperties(sc, e2); -- -- assert(td); -- Expressions a; -- a.push(e2); -- -- fd = td->deduceFunctionTemplate(sc, loc, targsi, ethis, &a, 1); -- if (fd && fd->type) -- goto Lsetter; -- -- fd = td->deduceFunctionTemplate(sc, loc, targsi, ethis, NULL, 1); -- if (fd && fd->type) -- goto Lgetter; -- } -- goto Leprop; -- } -- else if (e1->op == TOKdotvar && e1->type->toBasetype()->ty == Tfunction) -- { -- DotVarExp *dve = (DotVarExp *)e1; -- fd = dve->var->isFuncDeclaration(); -- ethis = dve->e1; -- goto L4; -- } -- else if (e1->op == TOKvar && e1->type->toBasetype()->ty == Tfunction) -- { -- fd = ((VarExp *)e1)->var->isFuncDeclaration(); -- ethis = NULL; -- L4: -- { -- e2 = e2->semantic(sc); -- if (e2->op == TOKerror) -- return new ErrorExp(); -- e2 = resolveProperties(sc, e2); -- -- assert(fd); -- FuncDeclaration *f = fd; -- Expressions a; -- a.push(e2); -- -- fd = f->overloadResolve(loc, ethis, &a, 1); -- if (fd && fd->type) -- goto Lsetter; -- -- fd = f->overloadResolve(loc, ethis, NULL, 1); -- if (fd && fd->type) -- goto Lgetter; -- -- goto Leprop; -- } -- -- Expression *e; -- TypeFunction *tf; -- -- Lsetter: -- assert(fd->type->ty == Tfunction); -- tf = (TypeFunction *)fd->type; -- if (!tf->isproperty && global.params.enforcePropertySyntax) -- goto Leprop; -- e = new CallExp(loc, e1, e2); -- return e->semantic(sc); -- -- Lgetter: -- assert(fd->type->ty == Tfunction); -- tf = (TypeFunction *)fd->type; -- if (!tf->isref) -- goto Leprop; -- if (!tf->isproperty && global.params.enforcePropertySyntax) -- goto Leprop; -- e = new CallExp(loc, e1); -- e = new AssignExp(loc, e, e2); -- return e->semantic(sc); -+ if (Expression *e = resolvePropertiesX(sc, e1, e2)) -+ return e; - -- Leprop: -- ::error(e1->loc, "not a property %s", e1->toChars()); -- return new ErrorExp(); -- } -+ e1 = checkRightThis(sc, e1); - - assert(e1->type); - Type *t1 = e1->type->toBasetype(); -@@ -10449,27 +11434,36 @@ Expression *AssignExp::semantic(Scope *s - */ - Ltupleassign: - if (e1->op == TOKtuple && e2->op == TOKtuple) -- { TupleExp *tup1 = (TupleExp *)e1; -+ { -+ TupleExp *tup1 = (TupleExp *)e1; - TupleExp *tup2 = (TupleExp *)e2; - size_t dim = tup1->exps->dim; -+ Expression *e = NULL; - if (dim != tup2->exps->dim) - { - error("mismatched tuple lengths, %d and %d", (int)dim, (int)tup2->exps->dim); - return new ErrorExp(); - } -+ if (dim == 0) -+ { -+ e = new IntegerExp(loc, 0, Type::tint32); -+ e = new CastExp(loc, e, Type::tvoid); // avoid "has no effect" error -+ e = combine(combine(tup1->e0, tup2->e0), e); -+ } - else -- { Expressions *exps = new Expressions; -+ { -+ Expressions *exps = new Expressions; - exps->setDim(dim); -- - for (size_t i = 0; i < dim; i++) -- { Expression *ex1 = (*tup1->exps)[i]; -+ { -+ Expression *ex1 = (*tup1->exps)[i]; - Expression *ex2 = (*tup2->exps)[i]; -- (*exps)[i] = new AssignExp(loc, ex1, ex2); -+ (*exps)[i] = new AssignExp(loc, ex1, ex2); - } -- Expression *e = new TupleExp(loc, exps); -- e = e->semantic(sc); -- return e; -+ e = new TupleExp(loc, combine(tup1->e0, tup2->e0), exps); - } -+ assert(e); -+ return e->semantic(sc); - } - - if (e1->op == TOKtuple) -@@ -10482,12 +11476,15 @@ Ltupleassign: - Identifier *id = Lexer::uniqueId("__tup"); - ExpInitializer *ei = new ExpInitializer(e2->loc, e2); - VarDeclaration *v = new VarDeclaration(e2->loc, NULL, id, ei); -- v->storage_class = STCctfe | STCref | STCforeach; -- Expression *ve = new VarExp(e2->loc, v); -- ve->type = e2->type; -+ v->storage_class = STCctfe; -+ if (e2->isLvalue()) -+ v->storage_class = STCref | STCforeach; -+ Expression *e0 = new DeclarationExp(e2->loc, v); -+ Expression *ev = new VarExp(e2->loc, v); -+ ev->type = e2->type; - - Expressions *iexps = new Expressions(); -- iexps->push(ve); -+ iexps->push(ev); - - for (size_t u = 0; u < iexps->dim ; u++) - { -@@ -10508,8 +11505,7 @@ Ltupleassign: - goto Lnomatch; - } - } -- (*iexps)[0] = new CommaExp(loc, new DeclarationExp(e2->loc, v), (*iexps)[0]); -- e2 = new TupleExp(e2->loc, iexps); -+ e2 = new TupleExp(e2->loc, e0, iexps); - e2 = e2->semantic(sc); - goto Ltupleassign; - -@@ -10518,10 +11514,17 @@ Ltupleassign: - } - } - -+ if (op == TOKassign && e1->checkModifiable(sc) == 2) -+ { -+ //printf("[%s] change to init - %s\n", loc.toChars(), toChars()); -+ op = TOKconstruct; -+ } -+ - // Determine if this is an initialization of a reference - int refinit = 0; - if (op == TOKconstruct && e1->op == TOKvar) -- { VarExp *ve = (VarExp *)e1; -+ { -+ VarExp *ve = (VarExp *)e1; - VarDeclaration *v = ve->var->isVarDeclaration(); - if (v->storage_class & (STCout | STCref)) - refinit = 1; -@@ -10535,88 +11538,238 @@ Ltupleassign: - StructDeclaration *sd = ((TypeStruct *)t1)->sym; - if (op == TOKassign) - { -- Expression *e = op_overload(sc); -- if (e && e1->op == TOKindex && -+ if (e1->op == TOKindex && - ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray) - { -- // Deal with AAs (Bugzilla 2451) -- // Rewrite as: -- // e1 = (typeof(aa.value) tmp = void, tmp = e2, tmp); -- Type * aaValueType = ((TypeAArray *)((IndexExp*)e1)->e1->type->toBasetype())->next; -- Identifier *id = Lexer::uniqueId("__aatmp"); -- VarDeclaration *v = new VarDeclaration(loc, aaValueType, -- id, new VoidInitializer(0)); -- v->storage_class |= STCctfe; -- v->semantic(sc); -- v->parent = sc->parent; -+ /* -+ * Rewrite: -+ * aa[key] = e2; -+ * as: -+ * ref __aatmp = aa; -+ * ref __aakey = key; -+ * ref __aaval = e2; -+ * (__aakey in __aatmp -+ * ? __aatmp[__aakey].opAssign(__aaval) -+ * : ConstructExp(__aatmp[__aakey], __aaval)); -+ */ -+ IndexExp *ie = (IndexExp *)e1; -+ Type *t2 = e2->type->toBasetype(); -+ Expression *e0 = NULL; -+ -+ Expression *ea = ie->e1; -+ Expression *ek = ie->e2; -+ Expression *ev = e2; -+ if (ea->hasSideEffect()) -+ { -+ VarDeclaration *v = new VarDeclaration(loc, ie->e1->type, -+ Lexer::uniqueId("__aatmp"), new ExpInitializer(loc, ie->e1)); -+ v->storage_class |= STCctfe; -+ if (ea->isLvalue()) -+ v->storage_class |= STCforeach | STCref; -+ v->semantic(sc); -+ e0 = combine(e0, new DeclarationExp(loc, v)); -+ ea = new VarExp(loc, v); -+ } -+ if (ek->hasSideEffect()) -+ { -+ VarDeclaration *v = new VarDeclaration(loc, ie->e2->type, -+ Lexer::uniqueId("__aakey"), new ExpInitializer(loc, ie->e2)); -+ v->storage_class |= STCctfe; -+ if (ek->isLvalue()) -+ v->storage_class |= STCforeach | STCref; -+ v->semantic(sc); -+ e0 = combine(e0, new DeclarationExp(loc, v)); -+ ek = new VarExp(loc, v); -+ } -+ if (ev->hasSideEffect()) -+ { -+ VarDeclaration *v = new VarDeclaration(loc, e2->type, -+ Lexer::uniqueId("__aaval"), new ExpInitializer(loc, e2)); -+ v->storage_class |= STCctfe; -+ if (ev->isLvalue()) -+ v->storage_class |= STCforeach | STCref; -+ v->semantic(sc); -+ e0 = combine(e0, new DeclarationExp(loc, v)); -+ ev = new VarExp(loc, v); -+ } -+ if (e0) -+ e0 = e0->semantic(sc); - -- Expression *de = new DeclarationExp(loc, v); -- VarExp *ve = new VarExp(loc, v); -+ AssignExp *ae = (AssignExp *)copy(); -+ ae->e1 = new IndexExp(loc, ea, ek); -+ ae->e1 = ae->e1->semantic(sc); -+ ae->e1 = ae->e1->optimize(WANTvalue); -+ ae->e2 = ev; -+ //Expression *e = new CallExp(loc, new DotIdExp(loc, ex, Id::assign), ev); -+ Expression *e = ae->op_overload(sc); -+ if (!e) -+ goto Lx; - -- AssignExp *ae = new AssignExp(loc, ve, e2); -- e = ae->op_overload(sc); -- e2 = new CommaExp(loc, new CommaExp(loc, de, e), ve); -- e2 = e2->semantic(sc); -+ Expression *ey = NULL; -+ if (t2->ty == Tstruct && sd == t2->toDsymbol(sc)) -+ { -+ ey = ev; -+ goto Lctor; -+ } -+ else if (!ev->implicitConvTo(ie->type) && sd->ctor) -+ { -+ // Look for implicit constructor call -+ // Rewrite as S().ctor(e2) -+ ey = new StructLiteralExp(loc, sd, NULL); -+ ey = new DotIdExp(loc, ey, Id::ctor); -+ ey = new CallExp(loc, ey, ev); -+ ey = ey->trySemantic(sc); -+ if (ey) -+ { -+ Lctor: -+ Expression *ex; -+ ex = new IndexExp(loc, ea, ek); -+ ex = ex->semantic(sc); -+ ex = ex->optimize(WANTvalue); -+ ex = ex->modifiableLvalue(sc, ex); // allocate new slot -+ ey = new ConstructExp(loc, ex, ey); - -- e1 = e1->optimize(WANTvalue); -- e1 = e1->modifiableLvalue(sc, e1); -- e2 = e2->implicitCastTo(sc, e1->type); -- type = e1->type; -- assert(type); -- e = this; -+ e = new CastExp(e->loc, e, Type::tvoid); -+ ey = new CastExp(ey->loc, ey, Type::tvoid); -+ } -+ } -+ if (ey) -+ e = new CondExp(loc, new InExp(loc, ek, ea), e, ey); -+ -+ e = combine(e0, e); -+ e = e->semantic(sc); -+ return e; - } -+ -+ Expression *e = op_overload(sc); - if (e) - { - /* See if we need to set ctorinit, i.e. track - * assignments to fields. An assignment to a field counts even - * if done through an opAssign overload. - */ -- e1->checkModifiable(sc); - return e; - } - } - else if (op == TOKconstruct && !refinit) -- { Type *t2 = e2->type->toBasetype(); -- if (t2->ty == Tstruct && -- sd == ((TypeStruct *)t2)->sym && -- sd->cpctor) -- { /* We have a copy constructor for this -- */ -- if (e2->op == TOKquestion) -- { /* Write as: -- * a ? e1 = b : e1 = c; -+ { -+ Type *t2 = e2->type->toBasetype(); -+ if (t2->ty == Tstruct && sd == ((TypeStruct *)t2)->sym) -+ { -+ if (sd->ctor && // there are constructors -+ e2->op == TOKcall && -+ e2->type->implicitConvTo(t1)) -+ { -+ /* Look for form of constructor call which is: -+ * *__ctmp.ctor(arguments...) - */ -- CondExp *econd = (CondExp *)e2; -- AssignExp *ea1 = new AssignExp(econd->e1->loc, e1, econd->e1); -- ea1->op = op; -- AssignExp *ea2 = new AssignExp(econd->e1->loc, e1, econd->e2); -- ea2->op = op; -- Expression *e = new CondExp(loc, econd->econd, ea1, ea2); -- return e->semantic(sc); -+ CallExp *ce = (CallExp *)e2; -+ if (ce->e1->op == TOKdotvar) -+ { -+ DotVarExp *dve = (DotVarExp *)ce->e1; -+ if (dve->var->isCtorDeclaration()) -+ { -+ /* It's a constructor call, currently constructing -+ * a temporary __ctmp. -+ */ -+ /* Before calling the constructor, initialize -+ * variable with a bit copy of the default -+ * initializer -+ */ -+ -+ if (sd->zeroInit == 1) -+ { -+ e2 = new IntegerExp(loc, 0, Type::tint32); -+ } -+ else if (sd->isNested()) -+ { -+ e2 = t1->defaultInitLiteral(loc); -+ this->op = TOKblit; -+ } -+ else -+ { -+ e2 = t1->defaultInit(loc); -+ this->op = TOKblit; -+ } -+ type = e1->type; -+ -+ /* Replace __ctmp being constructed with e1. -+ * We need to copy constructor call expression, -+ * because it may be used in other place. -+ */ -+ DotVarExp *dvx = (DotVarExp *)dve->copy(); -+ dvx->e1 = e1; -+ CallExp *cx = (CallExp *)ce->copy(); -+ cx->e1 = dvx; -+ -+ Expression *e = new CommaExp(loc, this, cx); -+ e = e->semantic(sc); -+ return e; -+ } -+ } - } -- else if (e2->isLvalue()) -- { /* Write as: -- * e1.cpctor(e2); -+ if (sd->cpctor) -+ { -+ /* We have a copy constructor for this - */ -- if (!e2->type->implicitConvTo(e1->type)) -- error("conversion error from %s to %s", e2->type->toChars(), e1->type->toChars()); -+ if (e2->op == TOKquestion) -+ { -+ /* Write as: -+ * a ? e1 = b : e1 = c; -+ */ -+ CondExp *econd = (CondExp *)e2; -+ AssignExp *ea1 = new AssignExp(econd->e1->loc, e1, econd->e1); -+ ea1->op = op; -+ AssignExp *ea2 = new AssignExp(econd->e1->loc, e1, econd->e2); -+ ea2->op = op; -+ Expression *e = new CondExp(loc, econd->econd, ea1, ea2); -+ return e->semantic(sc); -+ } - -- Expression *e = new DotVarExp(loc, e1, sd->cpctor, 0); -- e = new CallExp(loc, e, e2); -- return e->semantic(sc); -+ if (e2->isLvalue()) -+ { -+ /* Write as: -+ * e1.cpctor(e2); -+ */ -+ if (!e2->type->implicitConvTo(e1->type)) -+ error("conversion error from %s to %s", e2->type->toChars(), e1->type->toChars()); -+ -+ Expression *e = new DotVarExp(loc, e1, sd->cpctor, 0); -+ e = new CallExp(loc, e, e2); -+ return e->semantic(sc); -+ } -+ else -+ { -+ /* The struct value returned from the function is transferred -+ * so should not call the destructor on it. -+ */ -+ e2 = valueNoDtor(e2); -+ } - } -- else if (e2->op == TOKcall) -+ } -+ else -+ { -+ if (!e2->implicitConvTo(t1)) - { -- /* The struct value returned from the function is transferred -- * so should not call the destructor on it. -- */ -- valueNoDtor(e2); -+ // Look for implicit constructor call -+ if (sd->ctor) -+ { -+ // Look for constructor first -+ // Rewrite as e1.ctor(arguments) -+ Expression *e; -+ e = new DotIdExp(loc, e1, Id::ctor); -+ e = new CallExp(loc, e, e2); -+ e = e->semantic(sc); -+ return e; -+ } - } - } - } -+ Lx: ; - } - else if (t1->ty == Tclass) -- { // Disallow assignment operator overloads for same type -+ { -+ // Disallow assignment operator overloads for same type - if (op == TOKassign && !e2->implicitConvTo(e1->type)) - { - Expression *e = op_overload(sc); -@@ -10641,11 +11794,32 @@ Ltupleassign: - else - { - // Convert e2 to e2[], unless e2-> e1[0] -- if (t2->ty == Tsarray && !t2->implicitConvTo(t1->nextOf())) -+ if (e2->op != TOKarrayliteral && t2->ty == Tsarray && !t2->implicitConvTo(t1->nextOf())) - { - e2 = new SliceExp(e2->loc, e2, NULL, NULL); - e2 = e2->semantic(sc); - } -+ else if (0 && global.params.warnings && !global.gag && op == TOKassign && -+ e2->op != TOKarrayliteral && e2->op != TOKstring && -+ !e2->implicitConvTo(t1)) -+ { // Disallow sa = da (Converted to sa[] = da[]) -+ // Disallow sa = e (Converted to sa[] = e) -+ const char* e1str = e1->toChars(); -+ const char* e2str = e2->toChars(); -+ if (e2->op == TOKslice || e2->implicitConvTo(t1->nextOf())) -+ warning("explicit element-wise assignment (%s)[] = %s is better than %s = %s", -+ e1str, e2str, e1str, e2str); -+ else -+ warning("explicit element-wise assignment (%s)[] = (%s)[] is better than %s = %s", -+ e1str, e2str, e1str, e2str); -+ -+ // Convert e2 to e2[] to avoid duplicated error message. -+ if (t2->ty == Tarray) -+ { -+ Expression *e = new SliceExp(e2->loc, e2, NULL, NULL); -+ e2 = e->semantic(sc); -+ } -+ } - - // Convert e1 to e1[] - Expression *e = new SliceExp(e1->loc, e1, NULL, NULL); -@@ -10660,12 +11834,17 @@ Ltupleassign: - ArrayLengthExp *ale = (ArrayLengthExp *)e1; - - ale->e1 = ale->e1->modifiableLvalue(sc, e1); -+ if (ale->e1->op == TOKerror) -+ return ale->e1; -+ -+ checkDefCtor(ale->loc, ale->e1->type->toBasetype()->nextOf()); - } - else if (e1->op == TOKslice) - { - Type *tn = e1->type->nextOf(); -- if (op == TOKassign && e1->checkModifiable(sc) == 1 && !tn->isMutable()) -- { error("slice %s is not mutable", e1->toChars()); -+ if (op == TOKassign && !tn->isMutable()) -+ { -+ error("slice %s is not mutable", e1->toChars()); - return new ErrorExp(); - } - } -@@ -10675,7 +11854,7 @@ Ltupleassign: - if (e1->op != TOKvar) - e1 = e1->optimize(WANTvalue); - -- if (op != TOKconstruct) -+ if (op == TOKassign) - e1 = e1->modifiableLvalue(sc, e1old); - } - -@@ -10696,6 +11875,8 @@ Ltupleassign: - { // memset - ismemset = 1; // make it easy for back end to tell what this is - e2 = e2->implicitCastTo(sc, t1->nextOf()); -+ if (op != TOKblit && e2->isLvalue()) -+ e2->checkPostblit(sc, t1->nextOf()); - } - else if (t1->ty == Tsarray) - { -@@ -10714,19 +11895,26 @@ Ltupleassign: - (t2->ty == Tarray || t2->ty == Tsarray) && - t2->nextOf()->implicitConvTo(t1->nextOf())) - { -- if (((SliceExp *)e1)->lwr == NULL) -+ SliceExp *se1 = (SliceExp *)e1; -+ Type *tx1 = se1->e1->type->toBasetype(); -+ if (se1->lwr == NULL && tx1->ty == Tsarray) - { -- Type *tx1 = ((SliceExp *)e1)->e1->type->toBasetype(); - Type *tx2 = t2; - if (e2->op == TOKslice && ((SliceExp *)e2)->lwr == NULL) - tx2 = ((SliceExp *)e2)->e1->type->toBasetype(); -- if (tx1->ty == Tsarray && tx2->ty == Tsarray) -+ uinteger_t dim1, dim2; -+ if (e2->op == TOKarrayliteral) -+ { -+ dim2 = ((ArrayLiteralExp *)e2)->elements->dim; -+ goto Lsa; -+ } -+ if (tx2->ty == Tsarray) - { // sa1[] = sa2[]; - // sa1[] = sa2; -- TypeSArray *tsa1 = (TypeSArray *)tx1; -- TypeSArray *tsa2 = (TypeSArray *)tx2; -- uinteger_t dim1 = tsa1->dim->toInteger(); -- uinteger_t dim2 = tsa2->dim->toInteger(); -+ // sa1[] = [ ... ]; -+ dim2 = ((TypeSArray *)tx2)->dim->toInteger(); -+ Lsa: -+ dim1 = ((TypeSArray *)tx1)->dim->toInteger(); - if (dim1 != dim2) - { - error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2); -@@ -10739,15 +11927,60 @@ Ltupleassign: - e2->op == TOKcast && ((UnaExp *)e2)->e1->isLvalue() || - e2->op != TOKslice && e2->isLvalue())) - { -- checkPostblit(e2->loc, t2->nextOf()); -+ e2->checkPostblit(sc, t2->nextOf()); - } -- if (op == TOKconstruct) -+ if (0 && global.params.warnings && !global.gag && op == TOKassign && -+ e2->op != TOKslice && e2->op != TOKassign && -+ e2->op != TOKarrayliteral && e2->op != TOKstring && -+ !(e2->op == TOKadd || e2->op == TOKmin || -+ e2->op == TOKmul || e2->op == TOKdiv || -+ e2->op == TOKmod || e2->op == TOKxor || -+ e2->op == TOKand || e2->op == TOKor || -+ #if DMDV2 -+ e2->op == TOKpow || -+ #endif -+ e2->op == TOKtilde || e2->op == TOKneg)) -+ { -+ const char* e1str = e1->toChars(); -+ const char* e2str = e2->toChars(); -+ warning("explicit element-wise assignment %s = (%s)[] is better than %s = %s", -+ e1str, e2str, e1str, e2str); -+ } -+ -+ Type *t2n = t2->nextOf(); -+ Type *t1n = t1->nextOf(); -+ int offset; -+ if (t2n->immutableOf()->equals(t1n->immutableOf()) || -+ t1n->isBaseOf(t2n, &offset) && offset == 0) -+ { -+ /* Allow copy of distinct qualifier elements. -+ * eg. -+ * char[] dst; const(char)[] src; -+ * dst[] = src; -+ * -+ * class C {} class D : C {} -+ * C[2] ca; D[] da; -+ * ca[] = da; -+ */ - e2 = e2->castTo(sc, e1->type->constOf()); -+ } - else -- e2 = e2->implicitCastTo(sc, e1->type->constOf()); -+ e2 = e2->implicitCastTo(sc, e1->type); - } - else - { -+ if (0 && global.params.warnings && !global.gag && op == TOKassign && -+ t1->ty == Tarray && t2->ty == Tsarray && -+ e2->op != TOKslice && //e2->op != TOKarrayliteral && -+ t2->implicitConvTo(t1)) -+ { // Disallow ar[] = sa (Converted to ar[] = sa[]) -+ // Disallow da = sa (Converted to da = sa[]) -+ const char* e1str = e1->toChars(); -+ const char* e2str = e2->toChars(); -+ const char* atypestr = e1->op == TOKslice ? "element-wise" : "slice"; -+ warning("explicit %s assignment %s = (%s)[] is better than %s = %s", -+ atypestr, e1str, e2str, e1str, e2str); -+ } - e2 = e2->implicitCastTo(sc, e1->type); - } - if (e2->op == TOKerror) -@@ -10782,7 +12015,7 @@ Ltupleassign: - - type = e1->type; - assert(type); -- return this; -+ return op == TOKassign ? reorderSettingAAElem(sc) : this; - } - - Expression *AssignExp::checkToBoolean(Scope *sc) -@@ -10858,25 +12091,24 @@ Expression *CatAssignExp::semantic(Scope - (e2->implicitConvTo(e1->type) - #if DMDV2 - || (tb2->nextOf()->implicitConvTo(tb1next) && -- (tb2->nextOf()->size(0) == tb1next->size(0) || -+ (tb2->nextOf()->size(Loc()) == tb1next->size(Loc()) || - tb1next->ty == Tchar || tb1next->ty == Twchar || tb1next->ty == Tdchar)) - #endif - ) - ) - { // Append array -- checkPostblit(e1->loc, tb1next); -+ e1->checkPostblit(sc, tb1next); - e2 = e2->castTo(sc, e1->type); - type = e1->type; -- e = this; - } - else if ((tb1->ty == Tarray) && - e2->implicitConvTo(tb1next) - ) - { // Append element -- checkPostblit(e2->loc, tb2); -+ e2->checkPostblit(sc, tb2); - e2 = e2->castTo(sc, tb1next); -+ e2 = e2->isLvalue() ? callCpCtor(sc, e2) : valueNoDtor(e2); - type = e1->type; -- e = this; - } - else if (tb1->ty == Tarray && - (tb1next->ty == Tchar || tb1next->ty == Twchar) && -@@ -10886,7 +12118,6 @@ Expression *CatAssignExp::semantic(Scope - { // Append dchar to char[] or wchar[] - e2 = e2->castTo(sc, Type::tdchar); - type = e1->type; -- e = this; - - /* Do not allow appending wchar to char[] because if wchar happens - * to be a surrogate pair, nothing good can result. -@@ -10896,9 +12127,9 @@ Expression *CatAssignExp::semantic(Scope - { - if (tb1 != Type::terror && tb2 != Type::terror) - error("cannot append type %s to type %s", tb2->toChars(), tb1->toChars()); -- e = new ErrorExp(); -+ return new ErrorExp(); - } -- return e; -+ return reorderSettingAAElem(sc); - } - - /************************************************************/ -@@ -11005,6 +12236,9 @@ Expression *PowAssignExp::semantic(Scope - else - { - e1 = e1->modifiableLvalue(sc, e1); -+ -+ e = reorderSettingAAElem(sc); -+ if (e != this) return e; - } - - if ( (e1->type->isintegral() || e1->type->isfloating()) && -@@ -11059,6 +12293,19 @@ Expression *AddExp::semantic(Scope *sc) - Type *tb1 = e1->type->toBasetype(); - Type *tb2 = e2->type->toBasetype(); - -+ if (tb1->ty == Tdelegate || -+ tb1->ty == Tpointer && tb1->nextOf()->ty == Tfunction) -+ { -+ e = e1->checkArithmetic(); -+ } -+ if (tb2->ty == Tdelegate || -+ tb2->ty == Tpointer && tb2->nextOf()->ty == Tfunction) -+ { -+ e = e2->checkArithmetic(); -+ } -+ if (e) -+ return e; -+ - if ((tb1->ty == Tarray || tb1->ty == Tsarray) && - (tb2->ty == Tarray || tb2->ty == Tsarray) && - tb1->nextOf()->equals(tb2->nextOf()) -@@ -11068,8 +12315,10 @@ Expression *AddExp::semantic(Scope *sc) - e = this; - } - else if (tb1->ty == Tpointer && e2->type->isintegral() || -- tb2->ty == Tpointer && e1->type->isintegral()) -+ tb2->ty == Tpointer && e1->type->isintegral()) -+ { - e = scaleFactor(sc); -+ } - else if (tb1->ty == Tpointer && tb2->ty == Tpointer) - { - return incompatibleTypes(); -@@ -11135,9 +12384,23 @@ Expression *MinExp::semantic(Scope *sc) - if (e) - return e; - -- e = this; - Type *t1 = e1->type->toBasetype(); - Type *t2 = e2->type->toBasetype(); -+ -+ if (t1->ty == Tdelegate || -+ t1->ty == Tpointer && t1->nextOf()->ty == Tfunction) -+ { -+ e = e1->checkArithmetic(); -+ } -+ if (t2->ty == Tdelegate || -+ t2->ty == Tpointer && t2->nextOf()->ty == Tfunction) -+ { -+ e = e2->checkArithmetic(); -+ } -+ if (e) -+ return e; -+ -+ e = this; - if (t1->ty == Tpointer) - { - if (t2->ty == Tpointer) -@@ -11155,7 +12418,7 @@ Expression *MinExp::semantic(Scope *sc) - } - else - { -- e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t)); -+ e = new DivExp(loc, this, new IntegerExp(Loc(), stride, Type::tptrdiff_t)); - e->type = Type::tptrdiff_t; - } - return e; -@@ -11262,10 +12525,10 @@ Expression *CatExp::semantic(Scope *sc) - e2->implicitConvTo(tb1next) >= MATCHconvert && - tb2->ty != Tvoid) - { -- checkPostblit(e2->loc, tb2); -+ e2->checkPostblit(sc, tb2); - e2 = e2->implicitCastTo(sc, tb1next); - type = tb1next->arrayOf(); -- if (tb2->ty == Tarray) -+ if (tb2->ty == Tarray || tb2->ty == Tsarray) - { // Make e2 into [e2] - e2 = new ArrayLiteralExp(e2->loc, e2); - e2->type = type; -@@ -11276,10 +12539,10 @@ Expression *CatExp::semantic(Scope *sc) - e1->implicitConvTo(tb2next) >= MATCHconvert && - tb1->ty != Tvoid) - { -- checkPostblit(e1->loc, tb1); -+ e1->checkPostblit(sc, tb1); - e1 = e1->implicitCastTo(sc, tb2next); - type = tb2next->arrayOf(); -- if (tb1->ty == Tarray) -+ if (tb1->ty == Tarray || tb1->ty == Tsarray) - { // Make e1 into [e1] - e1 = new ArrayLiteralExp(e1->loc, e1); - e1->type = type; -@@ -11316,9 +12579,9 @@ Expression *CatExp::semantic(Scope *sc) - { - type = type->nextOf()->toHeadMutable()->arrayOf(); - } -- if (tb->nextOf()) -+ if (Type *tbn = tb->nextOf()) - { -- checkPostblit(loc, tb->nextOf()); -+ checkPostblit(sc, tbn); - } - #if 0 - e1->type->print(); -@@ -11569,104 +12832,91 @@ Expression *PowExp::semantic(Scope *sc) - } - } - -- if ( (e1->type->isintegral() || e1->type->isfloating()) && -- (e2->type->isintegral() || e2->type->isfloating())) -+ if ( !(e1->type->isintegral() || e1->type->isfloating()) || -+ !(e2->type->isintegral() || e2->type->isfloating())) - { -- // For built-in numeric types, there are several cases. -- // TODO: backend support, especially for e1 ^^ 2. -+ return incompatibleTypes(); -+ } - -- bool wantSqrt = false; -+ // For built-in numeric types, there are several cases. -+ // TODO: backend support, especially for e1 ^^ 2. - -- // First, attempt to fold the expression. -- e = optimize(WANTvalue); -- if (e->op != TOKpow) -- { -- e = e->semantic(sc); -- return e; -- } -+ bool wantSqrt = false; - -- // Determine if we're raising to an integer power. -- sinteger_t intpow = 0; -- if (e2->op == TOKint64 && ((sinteger_t)e2->toInteger() == 2 || (sinteger_t)e2->toInteger() == 3)) -- intpow = e2->toInteger(); -- else if (e2->op == TOKfloat64 && e2->toReal() == (real_t)(e2->toInteger())) -- intpow = e2->toInteger(); -- -- // Deal with x^^2, x^^3 immediately, since they are of practical importance. -- if (intpow == 2 || intpow == 3) -- { -- // Replace x^^2 with (tmp = x, tmp*tmp) -- // Replace x^^3 with (tmp = x, tmp*tmp*tmp) -- Identifier *idtmp = Lexer::uniqueId("__powtmp"); -- VarDeclaration *tmp = new VarDeclaration(loc, e1->type->toBasetype(), idtmp, new ExpInitializer(0, e1)); -- tmp->storage_class = STCctfe; -- Expression *ve = new VarExp(loc, tmp); -- Expression *ae = new DeclarationExp(loc, tmp); -- /* Note that we're reusing ve. This should be ok. -- */ -- Expression *me = new MulExp(loc, ve, ve); -- if (intpow == 3) -- me = new MulExp(loc, me, ve); -- e = new CommaExp(loc, ae, me); -- e = e->semantic(sc); -- return e; -- } -+ // First, attempt to fold the expression. -+ e = optimize(WANTvalue); -+ if (e->op != TOKpow) -+ { -+ e = e->semantic(sc); -+ return e; -+ } - -- static int importMathChecked = 0; -- static bool importMath = false; -- if (!importMathChecked) -- { -- importMathChecked = 1; -- for (size_t i = 0; i < Module::amodules.dim; i++) -- { Module *mi = Module::amodules[i]; -- //printf("\t[%d] %s\n", i, mi->toChars()); -- if (mi->ident == Id::math && -- mi->parent->ident == Id::std && -- !mi->parent->parent) -- { -- importMath = true; -- goto L1; -- } -- } --#ifndef IN_GCC -- error("must import std.math to use ^^ operator"); -- return new ErrorExp(); --#endif -+ // Determine if we're raising to an integer power. -+ sinteger_t intpow = 0; -+ if (e2->op == TOKint64 && ((sinteger_t)e2->toInteger() == 2 || (sinteger_t)e2->toInteger() == 3)) -+ intpow = e2->toInteger(); -+ else if (e2->op == TOKfloat64 && (e2->toReal() == (sinteger_t)(e2->toReal()))) -+ intpow = (sinteger_t)(e2->toReal()); -+ -+ // Deal with x^^2, x^^3 immediately, since they are of practical importance. -+ if (intpow == 2 || intpow == 3) -+ { -+ // Replace x^^2 with (tmp = x, tmp*tmp) -+ // Replace x^^3 with (tmp = x, tmp*tmp*tmp) -+ Identifier *idtmp = Lexer::uniqueId("__powtmp"); -+ VarDeclaration *tmp = new VarDeclaration(loc, e1->type->toBasetype(), idtmp, new ExpInitializer(Loc(), e1)); -+ tmp->storage_class = STCctfe; -+ Expression *ve = new VarExp(loc, tmp); -+ Expression *ae = new DeclarationExp(loc, tmp); -+ /* Note that we're reusing ve. This should be ok. -+ */ -+ Expression *me = new MulExp(loc, ve, ve); -+ if (intpow == 3) -+ me = new MulExp(loc, me, ve); -+ e = new CommaExp(loc, ae, me); -+ e = e->semantic(sc); -+ return e; -+ } - -- L1: ; -- } -- else -- { -- if (!importMath) -+ static int importMathChecked = 0; -+ static bool importMath = false; -+ if (!importMathChecked) -+ { -+ importMathChecked = 1; -+ for (size_t i = 0; i < Module::amodules.dim; i++) -+ { Module *mi = Module::amodules[i]; -+ //printf("\t[%d] %s\n", i, mi->toChars()); -+ if (mi->ident == Id::math && -+ mi->parent->ident == Id::std && -+ !mi->parent->parent) - { --#ifdef IN_GCC -- // GDC handles PowExp in backend. -- typeCombine(sc); -- e = this; -- return e; --#else -- error("must import std.math to use ^^ operator"); -- return new ErrorExp(); --#endif -+ importMath = true; -+ break; - } - } -- -- e = new IdentifierExp(loc, Id::empty); -- e = new DotIdExp(loc, e, Id::std); -- e = new DotIdExp(loc, e, Id::math); -- if (e2->op == TOKfloat64 && e2->toReal() == 0.5) -- { // Replace e1 ^^ 0.5 with .std.math.sqrt(x) -- e = new CallExp(loc, new DotIdExp(loc, e, Id::_sqrt), e1); -- } -- else -- { -- // Replace e1 ^^ e2 with .std.math.pow(e1, e2) -- e = new CallExp(loc, new DotIdExp(loc, e, Id::_pow), e1, e2); -- } -- e = e->semantic(sc); -+ } -+ if (!importMath) -+ { // Leave handling of PowExp to the backend, or throw -+ // an error gracefully if no backend support exists. -+ typeCombine(sc); -+ e = this; - return e; - } -- return incompatibleTypes(); -+ -+ e = new IdentifierExp(loc, Id::empty); -+ e = new DotIdExp(loc, e, Id::std); -+ e = new DotIdExp(loc, e, Id::math); -+ if (e2->op == TOKfloat64 && e2->toReal() == 0.5) -+ { // Replace e1 ^^ 0.5 with .std.math.sqrt(x) -+ e = new CallExp(loc, new DotIdExp(loc, e, Id::_sqrt), e1); -+ } -+ else -+ { -+ // Replace e1 ^^ e2 with .std.math.pow(e1, e2) -+ e = new CallExp(loc, new DotIdExp(loc, e, Id::_pow), e1, e2); -+ } -+ e = e->semantic(sc); -+ return e; - } - - /************************************************************/ -@@ -12054,7 +13304,7 @@ void RemoveExp::toCBuffer(OutBuffer *buf - - /************************************************************/ - --CmpExp::CmpExp(enum TOK op, Loc loc, Expression *e1, Expression *e2) -+CmpExp::CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2) - : BinExp(loc, op, sizeof(CmpExp), e1, e2) - { - } -@@ -12103,9 +13353,6 @@ Expression *CmpExp::semantic(Scope *sc) - return new ErrorExp(); - } - -- Expression *eb1 = e1; -- Expression *eb2 = e2; -- - e = typeCombine(sc); - if (e->op == TOKerror) - return e; -@@ -12140,6 +13387,11 @@ Expression *CmpExp::semantic(Scope *sc) - error("compare not defined for complex operands"); - e = new ErrorExp(); - } -+ else if (t1->ty == Taarray || t2->ty == Taarray) -+ { -+ error("%s is not defined for associative arrays", Token::toChars(op)); -+ e = new ErrorExp(); -+ } - else if (t1->ty == Tvector) - return incompatibleTypes(); - else -@@ -12159,7 +13411,7 @@ int CmpExp::isBit() - - /************************************************************/ - --EqualExp::EqualExp(enum TOK op, Loc loc, Expression *e1, Expression *e2) -+EqualExp::EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2) - : BinExp(loc, op, sizeof(EqualExp), e1, e2) - { - assert(op == TOKequal || op == TOKnotequal); -@@ -12189,7 +13441,7 @@ int needDirectEq(Type *t1, Type *t2) - if (t->ty != Tstruct) - return FALSE; - -- return ((TypeStruct *)t)->sym->xeq == StructDeclaration::xerreq; -+ return ((TypeStruct *)t)->sym->hasIdentityEquals; - } - - Expression *EqualExp::semantic(Scope *sc) -@@ -12201,16 +13453,20 @@ Expression *EqualExp::semantic(Scope *sc - - BinExp::semanticp(sc); - -+ if (e1->op == TOKtype || e2->op == TOKtype) -+ return incompatibleTypes(); -+ - /* Before checking for operator overloading, check to see if we're - * comparing the addresses of two statics. If so, we can just see - * if they are the same symbol. - */ - if (e1->op == TOKaddress && e2->op == TOKaddress) -- { AddrExp *ae1 = (AddrExp *)e1; -+ { -+ AddrExp *ae1 = (AddrExp *)e1; - AddrExp *ae2 = (AddrExp *)e2; -- - if (ae1->e1->op == TOKvar && ae2->e1->op == TOKvar) -- { VarExp *ve1 = (VarExp *)ae1->e1; -+ { -+ VarExp *ve1 = (VarExp *)ae1->e1; - VarExp *ve2 = (VarExp *)ae2->e1; - - if (ve1->var == ve2->var /*|| ve1->var->toSymbol() == ve2->var->toSymbol()*/) -@@ -12279,6 +13535,63 @@ Expression *EqualExp::semantic(Scope *sc - return new ErrorExp(); - } - -+ if (t1->ty == Tstruct && t2->ty == Tstruct) -+ { -+ StructDeclaration *sd = ((TypeStruct *)t1)->sym; -+ if (sd == ((TypeStruct *)t2)->sym) -+ { -+ if (sd->needOpEquals()) -+ { -+ this->e1 = new DotIdExp(loc, e1, Id::tupleof); -+ this->e2 = new DotIdExp(loc, e2, Id::tupleof); -+ e = this; -+ } -+ else -+ { -+ e = new IdentityExp(op == TOKequal ? TOKidentity : TOKnotidentity, loc, e1, e2); -+ } -+ e = e->semantic(sc); -+ return e; -+ } -+ } -+ -+ // check tuple equality before typeCombine -+ if (e1->op == TOKtuple && e2->op == TOKtuple) -+ { -+ TupleExp *tup1 = (TupleExp *)e1; -+ TupleExp *tup2 = (TupleExp *)e2; -+ size_t dim = tup1->exps->dim; -+ Expression *e = NULL; -+ if (dim != tup2->exps->dim) -+ { -+ error("mismatched tuple lengths, %d and %d", (int)dim, (int)tup2->exps->dim); -+ return new ErrorExp(); -+ } -+ if (dim == 0) -+ { -+ // zero-length tuple comparison should always return true or false. -+ e = new IntegerExp(loc, (op == TOKequal), Type::tboolean); -+ } -+ else -+ { -+ for (size_t i = 0; i < dim; i++) -+ { -+ Expression *ex1 = (*tup1->exps)[i]; -+ Expression *ex2 = (*tup2->exps)[i]; -+ Expression *eeq = new EqualExp(op, loc, ex1, ex2); -+ if (!e) -+ e = eeq; -+ else if (op == TOKequal) -+ e = new AndAndExp(loc, e, eeq); -+ else -+ e = new OrOrExp(loc, e, eeq); -+ } -+ } -+ assert(e); -+ e = combine(combine(tup1->e0, tup2->e0), e); -+ return e->semantic(sc); -+ } -+ - e = typeCombine(sc); - if (e->op == TOKerror) - return e; -@@ -12311,7 +13624,7 @@ int EqualExp::isBit() - - /************************************************************/ - --IdentityExp::IdentityExp(enum TOK op, Loc loc, Expression *e1, Expression *e2) -+IdentityExp::IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2) - : BinExp(loc, op, sizeof(IdentityExp), e1, e2) - { - } -@@ -12362,11 +13675,7 @@ Expression *CondExp::syntaxCopy() - - - Expression *CondExp::semantic(Scope *sc) --{ Type *t1; -- Type *t2; -- unsigned cs0; -- unsigned cs1; -- -+{ - #if LOGSEMANTIC - printf("CondExp::semantic('%s')\n", toChars()); - #endif -@@ -12378,19 +13687,32 @@ Expression *CondExp::semantic(Scope *sc) - econd = econd->checkToPointer(); - econd = econd->checkToBoolean(sc); - -- cs0 = sc->callSuper; -+ unsigned cs0 = sc->callSuper; -+ unsigned *fi0 = fi0 = sc->saveFieldInit(); - e1 = e1->semantic(sc); - e1 = resolveProperties(sc, e1); -- cs1 = sc->callSuper; -+ -+ unsigned cs1 = sc->callSuper; -+ unsigned *fi1 = sc->fieldinit; - sc->callSuper = cs0; -+ sc->fieldinit = fi0; - e2 = e2->semantic(sc); - e2 = resolveProperties(sc, e2); -+ - sc->mergeCallSuper(loc, cs1); -+ sc->mergeFieldInit(loc, fi1); -+ -+ if (econd->type == Type::terror) -+ return econd; -+ if (e1->type == Type::terror) -+ return e1; -+ if (e2->type == Type::terror) -+ return e2; - - - // If either operand is void, the result is void -- t1 = e1->type; -- t2 = e2->type; -+ Type *t1 = e1->type; -+ Type *t2 = e2->type; - if (t1->ty == Tvoid || t2->ty == Tvoid) - type = Type::tvoid; - else if (t1 == t2) -@@ -12420,6 +13742,7 @@ Expression *CondExp::semantic(Scope *sc) - e2 = e2->castTo(sc, type); - } - } -+ type = type->merge2(); - #if 0 - printf("res: %s\n", type->toChars()); - printf("e1 : %s\n", e1->type->toChars()); -@@ -12496,7 +13819,7 @@ void CondExp::toCBuffer(OutBuffer *buf, - - /****************************************************************/ - --DefaultInitExp::DefaultInitExp(Loc loc, enum TOK subop, int size) -+DefaultInitExp::DefaultInitExp(Loc loc, TOK subop, int size) - : Expression(loc, TOKdefault, size) - { - this->subop = subop; -@@ -12517,7 +13840,7 @@ FileInitExp::FileInitExp(Loc loc) - Expression *FileInitExp::semantic(Scope *sc) - { - //printf("FileInitExp::semantic()\n"); -- type = Type::tchar->invariantOf()->arrayOf(); -+ type = Type::tstring; - return this; - } - -@@ -12551,15 +13874,144 @@ Expression *LineInitExp::resolveLoc(Loc - return e; - } - -+/****************************************************************/ -+ -+ModuleInitExp::ModuleInitExp(Loc loc) -+ : DefaultInitExp(loc, TOKmodulestring, sizeof(ModuleInitExp)) -+{ -+} -+ -+Expression *ModuleInitExp::semantic(Scope *sc) -+{ -+ //printf("ModuleInitExp::semantic()\n"); -+ type = Type::tstring; -+ return this; -+} -+ -+Expression *ModuleInitExp::resolveLoc(Loc loc, Scope *sc) -+{ -+ const char *s; -+ if (sc->callsc) -+ s = sc->callsc->module->toPrettyChars(); -+ else -+ s = sc->module->toPrettyChars(); -+ Expression *e = new StringExp(loc, (char *)s); -+ e = e->semantic(sc); -+ e = e->castTo(sc, type); -+ return e; -+} -+ -+/****************************************************************/ -+ -+FuncInitExp::FuncInitExp(Loc loc) -+ : DefaultInitExp(loc, TOKfuncstring, sizeof(FuncInitExp)) -+{ -+} -+ -+Expression *FuncInitExp::semantic(Scope *sc) -+{ -+ //printf("FuncInitExp::semantic()\n"); -+ type = Type::tstring; -+ if (sc->func) return this->resolveLoc(Loc(), sc); -+ return this; -+} -+ -+Expression *FuncInitExp::resolveLoc(Loc loc, Scope *sc) -+{ -+ const char *s; -+ if (sc->callsc && sc->callsc->func) -+ s = sc->callsc->func->Dsymbol::toPrettyChars(); -+ else if (sc->func) -+ s = sc->func->Dsymbol::toPrettyChars(); -+ else -+ s = ""; -+ Expression *e = new StringExp(loc, (char *)s); -+ e = e->semantic(sc); -+ e = e->castTo(sc, type); -+ return e; -+} -+ -+/****************************************************************/ -+ -+PrettyFuncInitExp::PrettyFuncInitExp(Loc loc) -+ : DefaultInitExp(loc, TOKprettyfunc, sizeof(PrettyFuncInitExp)) -+{ -+} -+ -+Expression *PrettyFuncInitExp::semantic(Scope *sc) -+{ -+ //printf("PrettyFuncInitExp::semantic()\n"); -+ type = Type::tstring; -+ if (sc->func) return this->resolveLoc(Loc(), sc); -+ return this; -+} -+ -+Expression *PrettyFuncInitExp::resolveLoc(Loc loc, Scope *sc) -+{ -+ FuncDeclaration *fd; -+ if (sc->callsc && sc->callsc->func) -+ fd = sc->callsc->func; -+ else -+ fd = sc->func; -+ -+ const char *s; -+ if (fd) -+ { -+ const char *funcStr = fd->Dsymbol::toPrettyChars(); -+ HdrGenState hgs; -+ OutBuffer buf; -+ functionToCBuffer2((TypeFunction *)fd->type, &buf, &hgs, 0, funcStr); -+ buf.writebyte(0); -+ s = (const char *)buf.extractData(); -+ } -+ else -+ { -+ s = ""; -+ } -+ -+ Expression *e = new StringExp(loc, (char *)s); -+ e = e->semantic(sc); -+ e = e->castTo(sc, type); -+ return e; -+} -+ -+Expression *extractOpDollarSideEffect(Scope *sc, UnaExp *ue) -+{ -+ Expression *e0 = NULL; -+ if (ue->e1->hasSideEffect()) -+ { -+ /* Even if opDollar is needed, 'ue->e1' should be evaluate only once. So -+ * Rewrite: -+ * ue->e1.opIndex( ... use of $ ... ) -+ * ue->e1.opSlice( ... use of $ ... ) -+ * as: -+ * (ref __dop = ue->e1, __dop).opIndex( ... __dop.opDollar ...) -+ * (ref __dop = ue->e1, __dop).opSlice( ... __dop.opDollar ...) -+ */ -+ Identifier *id = Lexer::uniqueId("__dop"); -+ ExpInitializer *ei = new ExpInitializer(ue->loc, ue->e1); -+ VarDeclaration *v = new VarDeclaration(ue->loc, ue->e1->type, id, ei); -+ v->storage_class |= STCctfe -+ | (ue->e1->isLvalue() ? (STCforeach | STCref) : 0); -+ e0 = new DeclarationExp(ue->loc, v); -+ e0 = e0->semantic(sc); -+ ue->e1 = new VarExp(ue->loc, v); -+ ue->e1 = ue->e1->semantic(sc); -+ } -+ return e0; -+} -+ - /************************************** - * Runs semantic on ae->arguments. Declares temporary variables - * if '$' was used. - */ - --ArrayExp *resolveOpDollar(Scope *sc, ArrayExp *ae) -+Expression *resolveOpDollar(Scope *sc, ArrayExp *ae) - { - assert(!ae->lengthVar); - -+ Expression *e0 = extractOpDollarSideEffect(sc, ae); -+ - for (size_t i = 0; i < ae->arguments->dim; i++) - { - // Create scope for '$' variable for this dimension -@@ -12575,16 +14027,18 @@ ArrayExp *resolveOpDollar(Scope *sc, Arr - e = resolveProperties(sc, e); - if (!e->type) - ae->error("%s has no value", e->toChars()); -- if (ae->lengthVar) -- { // If $ was used, declare it now -+ if (ae->lengthVar && sc->func) -+ { -+ // If $ was used, declare it now - Expression *de = new DeclarationExp(ae->loc, ae->lengthVar); -- e = new CommaExp(0, de, e); -+ e = new CommaExp(Loc(), de, e); - e = e->semantic(sc); - } - (*ae->arguments)[i] = e; - sc = sc->pop(); - } -- return ae; -+ -+ return e0; - } - - /************************************** -@@ -12592,12 +14046,14 @@ ArrayExp *resolveOpDollar(Scope *sc, Arr - * if '$' was used. - */ - --SliceExp *resolveOpDollar(Scope *sc, SliceExp *se) -+Expression *resolveOpDollar(Scope *sc, SliceExp *se) - { - assert(!se->lengthVar); - assert(!se->lwr || se->upr); - -- if (!se->lwr) return se; -+ if (!se->lwr) return NULL; -+ -+ Expression *e0 = extractOpDollarSideEffect(sc, se); - - // create scope for '$' - ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, se); -@@ -12612,15 +14068,78 @@ SliceExp *resolveOpDollar(Scope *sc, Sli - e = resolveProperties(sc, e); - if (!e->type) - se->error("%s has no value", e->toChars()); -- i == 0 ? se->lwr : se->upr = e; -+ (i == 0 ? se->lwr : se->upr) = e; - } - -- if (se->lengthVar) -- { // If $ was used, declare it now -+ if (se->lengthVar && sc->func) -+ { -+ // If $ was used, declare it now - Expression *de = new DeclarationExp(se->loc, se->lengthVar); -- se->lwr = new CommaExp(0, de, se->lwr); -+ se->lwr = new CommaExp(Loc(), de, se->lwr); - se->lwr = se->lwr->semantic(sc); - } - sc = sc->pop(); -- return se; -+ -+ return e0; -+} -+ -+Expression *BinExp::reorderSettingAAElem(Scope *sc) -+{ -+ if (this->e1->op != TOKindex) -+ return this; -+ IndexExp *ie = (IndexExp *)e1; -+ Type *t1 = ie->e1->type->toBasetype(); -+ if (t1->ty != Taarray) -+ return this; -+ -+ /* Check recursive conversion */ -+ VarDeclaration *var; -+ bool isrefvar = (e2->op == TOKvar && -+ (var = ((VarExp *)e2)->var->isVarDeclaration()) != NULL && -+ (var->storage_class & STCref)); -+ if (isrefvar) -+ return this; -+ -+ /* Fix evaluation order of setting AA element. (Bugzilla 3825) -+ * Rewrite: -+ * aa[key] op= val; -+ * as: -+ * ref __aatmp = aa; -+ * ref __aakey = key; -+ * ref __aaval = val; -+ * __aatmp[__aakey] op= __aaval; // assignment -+ */ -+ Expression *ec = NULL; -+ if (ie->e1->hasSideEffect()) -+ { -+ Identifier *id = Lexer::uniqueId("__aatmp"); -+ VarDeclaration *vd = new VarDeclaration(ie->e1->loc, ie->e1->type, id, new ExpInitializer(ie->e1->loc, ie->e1)); -+ Expression *de = new DeclarationExp(ie->e1->loc, vd); -+ if (ie->e1->isLvalue()) -+ vd->storage_class |= STCref | STCforeach; -+ ec = de; -+ ie->e1 = new VarExp(ie->e1->loc, vd); -+ } -+ if (ie->e2->hasSideEffect()) -+ { -+ Identifier *id = Lexer::uniqueId("__aakey"); -+ VarDeclaration *vd = new VarDeclaration(ie->e2->loc, ie->e2->type, id, new ExpInitializer(ie->e2->loc, ie->e2)); -+ if (ie->e2->isLvalue()) -+ vd->storage_class |= STCref | STCforeach; -+ Expression *de = new DeclarationExp(ie->e2->loc, vd); -+ -+ ec = ec ? new CommaExp(loc, ec, de) : de; -+ ie->e2 = new VarExp(ie->e2->loc, vd); -+ } -+ { -+ Identifier *id = Lexer::uniqueId("__aaval"); -+ VarDeclaration *vd = new VarDeclaration(loc, this->e2->type, id, new ExpInitializer(this->e2->loc, this->e2)); -+ vd->storage_class |= STCref | STCforeach | (this->e2->isLvalue() ? 0 : STCtemp); -+ Expression *de = new DeclarationExp(this->e2->loc, vd); -+ -+ ec = ec ? new CommaExp(loc, ec, de) : de; -+ this->e2 = new VarExp(this->e2->loc, vd); -+ } -+ ec = new CommaExp(loc, ec, this); -+ return ec->semantic(sc); - } ---- a/src/gcc/d/dfrontend/expression.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/expression.h 2014-04-01 16:32:51.000000000 +0100 -@@ -17,48 +17,53 @@ - #include "arraytypes.h" - #include "intrange.h" - --struct Type; --struct TypeVector; -+class Type; -+class TypeVector; - struct Scope; --struct TupleDeclaration; --struct VarDeclaration; --struct FuncDeclaration; --struct FuncLiteralDeclaration; --struct Declaration; --struct CtorDeclaration; --struct NewDeclaration; --struct Dsymbol; --struct Import; --struct Module; --struct ScopeDsymbol; -+class TupleDeclaration; -+class VarDeclaration; -+class FuncDeclaration; -+class FuncLiteralDeclaration; -+class Declaration; -+class CtorDeclaration; -+class NewDeclaration; -+class Dsymbol; -+class Import; -+class Module; -+class ScopeDsymbol; - struct InlineCostState; - struct InlineDoState; - struct InlineScanState; --struct Expression; --struct Declaration; --struct AggregateDeclaration; --struct StructDeclaration; --struct TemplateInstance; --struct TemplateDeclaration; --struct ClassDeclaration; -+class Expression; -+class Declaration; -+class AggregateDeclaration; -+class StructDeclaration; -+class TemplateInstance; -+class TemplateDeclaration; -+class ClassDeclaration; - struct HdrGenState; --struct BinExp; -+class BinExp; - struct InterState; - struct Symbol; // back end symbol --struct OverloadSet; --struct Initializer; --struct StringExp; -+class OverloadSet; -+class Initializer; -+class StringExp; -+class ArrayExp; -+class SliceExp; - - enum TOK; - - // Back end - struct IRState; -- - #ifdef IN_GCC --typedef union tree_node elem; - typedef union tree_node dt_t; - #else - struct dt_t; -+#endif -+ -+#ifdef IN_GCC -+typedef union tree_node elem; -+#else - struct elem; - #endif - -@@ -67,6 +72,7 @@ void initPrecedence(); - typedef int (*apply_fp_t)(Expression *, void *); - - Expression *resolveProperties(Scope *sc, Expression *e); -+Expression *resolvePropertiesOnly(Scope *sc, Expression *e1); - void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d); - Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Dsymbol *d); - Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid); -@@ -79,17 +85,21 @@ FuncDeclaration *hasThis(Scope *sc); - Expression *fromConstInitializer(int result, Expression *e); - int arrayExpressionCanThrow(Expressions *exps, bool mustNotThrow); - TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s); --void valueNoDtor(Expression *e); -+Expression *valueNoDtor(Expression *e); - int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1); - #if DMDV2 - Expression *resolveAliasThis(Scope *sc, Expression *e); --Expression *callCpCtor(Loc loc, Scope *sc, Expression *e, int noscope); --int checkPostblit(Loc loc, Type *t); -+Expression *callCpCtor(Scope *sc, Expression *e); - #endif --struct ArrayExp *resolveOpDollar(Scope *sc, struct ArrayExp *ae); --struct SliceExp *resolveOpDollar(Scope *sc, struct SliceExp *se); -+Expression *resolveOpDollar(Scope *sc, ArrayExp *ae); -+Expression *resolveOpDollar(Scope *sc, SliceExp *se); - Expressions *arrayExpressionSemantic(Expressions *exps, Scope *sc); - -+/* Run CTFE on the expression, but allow the expression to be a TypeExp -+ * or a tuple containing a TypeExp. (This is required by pragma(msg)). -+ */ -+Expression *ctfeInterpretForPragmaMsg(Expression *e); -+ - /* Interpreter: what form of return value expression is required? - */ - enum CtfeGoal -@@ -100,15 +110,22 @@ enum CtfeGoal - ctfeNeedNothing // The return value is not required - }; - --struct Expression : Object -+#define WANTflags 1 -+#define WANTvalue 2 -+// Same as WANTvalue, but also expand variables as far as possible -+#define WANTexpand 8 -+ -+class Expression : public RootObject - { -+public: - Loc loc; // file location -- enum TOK op; // handy to minimize use of dynamic_cast -+ TOK op; // handy to minimize use of dynamic_cast - Type *type; // !=NULL means that semantic() has been run - unsigned char size; // # of bytes in Expression so we can copy() it - unsigned char parens; // if this is a parenthesized expression - -- Expression(Loc loc, enum TOK op, int size); -+ Expression(Loc loc, TOK op, int size); -+ static void init(); - Expression *copy(); - virtual Expression *syntaxCopy(); - virtual int apply(apply_fp_t fp, void *param); -@@ -143,7 +160,7 @@ struct Expression : Object - virtual MATCH implicitConvTo(Type *t); - virtual IntRange getIntRange(); - virtual Expression *castTo(Scope *sc, Type *t); -- virtual Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); -+ virtual Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); - virtual void checkEscape(); - virtual void checkEscapeRef(); - virtual Expression *resolveLoc(Loc loc, Scope *sc); -@@ -153,8 +170,9 @@ struct Expression : Object - Expression *checkArithmetic(); - void checkDeprecated(Scope *sc, Dsymbol *s); - void checkPurity(Scope *sc, FuncDeclaration *f); -- void checkPurity(Scope *sc, VarDeclaration *v, Expression *e1); -+ void checkPurity(Scope *sc, VarDeclaration *v); - void checkSafety(Scope *sc, FuncDeclaration *f); -+ bool checkPostblit(Scope *sc, Type *t); - virtual int checkModifiable(Scope *sc, int flag = 0); - virtual Expression *checkToBoolean(Scope *sc); - virtual Expression *addDtorHook(Scope *sc); -@@ -167,12 +185,6 @@ struct Expression : Object - Expression *toDelegate(Scope *sc, Type *t); - - virtual Expression *optimize(int result, bool keepLvalue = false); -- #define WANTflags 1 -- #define WANTvalue 2 -- // A compile-time result is required. Give an error if not possible -- #define WANTinterpret 4 -- // Same as WANTvalue, but also expand variables as far as possible -- #define WANTexpand 8 - - // Entry point for CTFE. - // A compile-time result is required. Give an error if not possible -@@ -210,13 +222,14 @@ struct Expression : Object - virtual dt_t **toDt(dt_t **pdt); - }; - --struct IntegerExp : Expression -+class IntegerExp : public Expression - { -+public: - dinteger_t value; - - IntegerExp(Loc loc, dinteger_t value, Type *type); - IntegerExp(dinteger_t value); -- int equals(Object *o); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - char *toChars(); -@@ -236,22 +249,25 @@ struct IntegerExp : Expression - dt_t **toDt(dt_t **pdt); - }; - --struct ErrorExp : IntegerExp -+class ErrorExp : public IntegerExp - { -+public: - ErrorExp(); - - Expression *implicitCastTo(Scope *sc, Type *t); -+ MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - Expression *toLvalue(Scope *sc, Expression *e); - }; - --struct RealExp : Expression -+class RealExp : public Expression - { -+public: - real_t value; - - RealExp(Loc loc, real_t value, Type *type); -- int equals(Object *o); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - char *toChars(); -@@ -269,12 +285,13 @@ struct RealExp : Expression - dt_t **toDt(dt_t **pdt); - }; - --struct ComplexExp : Expression -+class ComplexExp : public Expression - { -+public: - complex_t value; - - ComplexExp(Loc loc, complex_t value, Type *type); -- int equals(Object *o); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - char *toChars(); -@@ -288,18 +305,17 @@ struct ComplexExp : Expression - int isBool(int result); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void toMangleBuffer(OutBuffer *buf); -- OutBuffer hexp; - elem *toElem(IRState *irs); - dt_t **toDt(dt_t **pdt); - }; - --struct IdentifierExp : Expression -+class IdentifierExp : public Expression - { -+public: - Identifier *ident; - Declaration *var; - - IdentifierExp(Loc loc, Identifier *ident); -- IdentifierExp(Loc loc, Declaration *var); - Expression *semantic(Scope *sc); - char *toChars(); - void dump(int indent); -@@ -308,17 +324,19 @@ struct IdentifierExp : Expression - Expression *toLvalue(Scope *sc, Expression *e); - }; - --struct DollarExp : IdentifierExp -+class DollarExp : public IdentifierExp - { -+public: - DollarExp(Loc loc); - }; - --struct DsymbolExp : Expression -+class DsymbolExp : public Expression - { -+public: - Dsymbol *s; -- int hasOverloads; -+ bool hasOverloads; - -- DsymbolExp(Loc loc, Dsymbol *s, int hasOverloads = 0); -+ DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads = false); - Expression *semantic(Scope *sc); - char *toChars(); - void dump(int indent); -@@ -327,8 +345,9 @@ struct DsymbolExp : Expression - Expression *toLvalue(Scope *sc, Expression *e); - }; - --struct ThisExp : Expression -+class ThisExp : public Expression - { -+public: - Declaration *var; - - ThisExp(Loc loc); -@@ -347,8 +366,9 @@ struct ThisExp : Expression - elem *toElem(IRState *irs); - }; - --struct SuperExp : ThisExp -+class SuperExp : public ThisExp - { -+public: - SuperExp(Loc loc); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -357,12 +377,13 @@ struct SuperExp : ThisExp - //Expression *inlineScan(InlineScanState *iss); - }; - --struct NullExp : Expression -+class NullExp : public Expression - { -+public: - unsigned char committed; // !=0 if type is committed - - NullExp(Loc loc, Type *t = NULL); -- int equals(Object *o); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - int isBool(int result); - int isConst(); -@@ -376,20 +397,21 @@ struct NullExp : Expression - dt_t **toDt(dt_t **pdt); - }; - --struct StringExp : Expression -+class StringExp : public Expression - { -+public: - void *string; // char, wchar, or dchar data - size_t len; // number of chars, wchars, or dchars - unsigned char sz; // 1: char, 2: wchar, 4: dchar - unsigned char committed; // !=0 if type is committed -- unsigned char postfix; // 'c', 'w', 'd' -+ utf8_t postfix; // 'c', 'w', 'd' - bool ownedByCtfe; // true = created in CTFE - - StringExp(Loc loc, char *s); - StringExp(Loc loc, void *s, size_t len); -- StringExp(Loc loc, void *s, size_t len, unsigned char postfix); -+ StringExp(Loc loc, void *s, size_t len, utf8_t postfix); - //Expression *syntaxCopy(); -- int equals(Object *o); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - size_t length(); -@@ -398,7 +420,7 @@ struct StringExp : Expression - Expression *implicitCastTo(Scope *sc, Type *t); - MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); -- int compare(Object *obj); -+ int compare(RootObject *obj); - int isBool(int result); - int isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); -@@ -412,15 +434,25 @@ struct StringExp : Expression - - // Tuple - --struct TupleExp : Expression -+class TupleExp : public Expression - { -+public: -+ Expression *e0; // side-effect part -+ /* Tuple-field access may need to take out its side effect part. -+ * For example: -+ * foo().tupleof -+ * is rewritten as: -+ * (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...)) -+ * The declaration of temporary variable __tup will be stored in TupleExp::e0. -+ */ - Expressions *exps; - -+ TupleExp(Loc loc, Expression *e0, Expressions *exps); - TupleExp(Loc loc, Expressions *exps); - TupleExp(Loc loc, TupleDeclaration *tup); - Expression *syntaxCopy(); - int apply(apply_fp_t fp, void *param); -- int equals(Object *o); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void checkEscape(); -@@ -433,8 +465,9 @@ struct TupleExp : Expression - Expression *inlineScan(InlineScanState *iss); - }; - --struct ArrayLiteralExp : Expression -+class ArrayLiteralExp : public Expression - { -+public: - Expressions *elements; - bool ownedByCtfe; // true = created in CTFE - -@@ -443,6 +476,7 @@ struct ArrayLiteralExp : Expression - - Expression *syntaxCopy(); - int apply(apply_fp_t fp, void *param); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - int isBool(int result); - elem *toElem(IRState *irs); -@@ -453,15 +487,19 @@ struct ArrayLiteralExp : Expression - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); -- Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); -+ Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); - dt_t **toDt(dt_t **pdt); - -+ void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -+ Expression *buildArrayLoop(Parameters *fparams); -+ - Expression *doInline(InlineDoState *ids); - Expression *inlineScan(InlineScanState *iss); - }; - --struct AssocArrayLiteralExp : Expression -+class AssocArrayLiteralExp : public Expression - { -+public: - Expressions *keys; - Expressions *values; - bool ownedByCtfe; // true = created in CTFE -@@ -479,14 +517,28 @@ struct AssocArrayLiteralExp : Expression - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); -- Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); -+ Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); - - Expression *doInline(InlineDoState *ids); - Expression *inlineScan(InlineScanState *iss); - }; - --struct StructLiteralExp : Expression -+// scrubReturnValue is running -+#define stageScrub 0x1 -+// hasNonConstPointers is running -+#define stageSearchPointers 0x2 -+// optimize is running -+#define stageOptimize 0x4 -+// apply is running -+#define stageApply 0x8 -+//inlineScan is running -+#define stageInlineScan 0x10 -+// toCBuffer is running -+#define stageToCBuffer 0x20 -+ -+class StructLiteralExp : public Expression - { -+public: - StructDeclaration *sd; // which aggregate this is for - Expressions *elements; // parallels sd->fields[] with - // NULL entries for fields to skip -@@ -497,13 +549,24 @@ struct StructLiteralExp : Expression - size_t soffset; // offset from start of s - int fillHoles; // fill alignment 'holes' with zero - bool ownedByCtfe; // true = created in CTFE -- int ctorinit; - -- StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype = NULL); -+ StructLiteralExp *origin; // pointer to the origin instance of the expression. -+ // once a new expression is created, origin is set to 'this'. -+ // anytime when an expression copy is created, 'origin' pointer is set to -+ // 'origin' pointer value of the original expression. -+ -+ StructLiteralExp *inlinecopy; // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer. -+ int stageflags; // anytime when recursive function is calling, 'stageflags' marks with bit flag of -+ // current stage and unmarks before return from this function. -+ // 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline' -+ // (with infinite recursion) of this expression. - -+ StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype = NULL); -+ bool equals(RootObject *o); - Expression *syntaxCopy(); - int apply(apply_fp_t fp, void *param); - Expression *semantic(Scope *sc); -+ Expression *fill(bool ctorinit); - Expression *getField(Type *type, unsigned offset); - int getFieldIndex(Type *type, unsigned offset); - elem *toElem(IRState *irs); -@@ -512,17 +575,21 @@ struct StructLiteralExp : Expression - Expression *optimize(int result, bool keepLvalue = false); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - dt_t **toDt(dt_t **pdt); -+ Symbol *toSymbol(); - MATCH implicitConvTo(Type *t); -+ Expression *castTo(Scope *sc, Type *t); - - int inlineCost3(InlineCostState *ics); - Expression *doInline(InlineDoState *ids); - Expression *inlineScan(InlineScanState *iss); - }; - --Expression *typeDotIdExp(Loc loc, Type *type, Identifier *ident); -+class DotIdExp; -+DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident); - --struct TypeExp : Expression -+class TypeExp : public Expression - { -+public: - TypeExp(Loc loc, Type *type); - Expression *syntaxCopy(); - Expression *semantic(Scope *sc); -@@ -532,8 +599,9 @@ struct TypeExp : Expression - elem *toElem(IRState *irs); - }; - --struct ScopeExp : Expression -+class ScopeExp : public Expression - { -+public: - ScopeDsymbol *sds; - - ScopeExp(Loc loc, ScopeDsymbol *sds); -@@ -543,17 +611,22 @@ struct ScopeExp : Expression - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct TemplateExp : Expression -+class TemplateExp : public Expression - { -+public: - TemplateDeclaration *td; -+ FuncDeclaration *fd; - -- TemplateExp(Loc loc, TemplateDeclaration *td); -+ TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd = NULL); - int rvalue(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -+ int isLvalue(); -+ Expression *toLvalue(Scope *sc, Expression *e); - }; - --struct NewExp : Expression -+class NewExp : public Expression - { -+public: - /* thisexp.new(newargs) newtype(arguments) - */ - Expression *thisexp; // if !NULL, 'this' for class being allocated -@@ -581,8 +654,9 @@ struct NewExp : Expression - //Expression *inlineScan(InlineScanState *iss); - }; - --struct NewAnonClassExp : Expression -+class NewAnonClassExp : public Expression - { -+public: - /* thisexp.new(newargs) class baseclasses { } (arguments) - */ - Expression *thisexp; // if !NULL, 'this' for class being allocated -@@ -599,12 +673,13 @@ struct NewAnonClassExp : Expression - }; - - #if DMDV2 --struct SymbolExp : Expression -+class SymbolExp : public Expression - { -+public: - Declaration *var; -- int hasOverloads; -+ bool hasOverloads; - -- SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads); -+ SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads); - - elem *toElem(IRState *irs); - }; -@@ -612,12 +687,14 @@ struct SymbolExp : Expression - - // Offset from symbol - --struct SymOffExp : SymbolExp -+class SymOffExp : public SymbolExp - { -+public: - unsigned offset; - -- SymOffExp(Loc loc, Declaration *var, unsigned offset, int hasOverloads = 0); -+ SymOffExp(Loc loc, Declaration *var, unsigned offset, bool hasOverloads = false); - Expression *semantic(Scope *sc); -+ Expression *optimize(int result, bool keepLvalue = false); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - void checkEscape(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -632,10 +709,11 @@ struct SymOffExp : SymbolExp - - // Variable - --struct VarExp : SymbolExp -+class VarExp : public SymbolExp - { -- VarExp(Loc loc, Declaration *var, int hasOverloads = 0); -- int equals(Object *o); -+public: -+ VarExp(Loc loc, Declaration *var, bool hasOverloads = false); -+ bool equals(RootObject *o); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -@@ -658,25 +736,29 @@ struct VarExp : SymbolExp - #if DMDV2 - // Overload Set - --struct OverExp : Expression -+class OverExp : public Expression - { -+public: - OverloadSet *vars; - -- OverExp(OverloadSet *s); -+ OverExp(Loc loc, OverloadSet *s); - int isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); -+ void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - #endif - - // Function/Delegate literal - --struct FuncExp : Expression -+class FuncExp : public Expression - { -+public: - FuncLiteralDeclaration *fd; - TemplateDeclaration *td; -- enum TOK tok; -+ TOK tok; - - FuncExp(Loc loc, FuncLiteralDeclaration *fd, TemplateDeclaration *td = NULL); -+ void genIdent(Scope *sc); - Expression *syntaxCopy(); - Expression *semantic(Scope *sc); - Expression *semantic(Scope *sc, Expressions *arguments); -@@ -684,7 +766,7 @@ struct FuncExp : Expression - Expression *implicitCastTo(Scope *sc, Type *t); - MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); -- Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); -+ Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); - char *toChars(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - elem *toElem(IRState *irs); -@@ -697,8 +779,9 @@ struct FuncExp : Expression - - // Declaration of a symbol - --struct DeclarationExp : Expression -+class DeclarationExp : public Expression - { -+public: - Dsymbol *declaration; - - DeclarationExp(Loc loc, Dsymbol *declaration); -@@ -713,19 +796,21 @@ struct DeclarationExp : Expression - Expression *inlineScan(InlineScanState *iss); - }; - --struct TypeidExp : Expression -+class TypeidExp : public Expression - { -- Object *obj; -+public: -+ RootObject *obj; - -- TypeidExp(Loc loc, Object *obj); -+ TypeidExp(Loc loc, RootObject *obj); - Expression *syntaxCopy(); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - - #if DMDV2 --struct TraitsExp : Expression -+class TraitsExp : public Expression - { -+public: - Identifier *ident; - Objects *args; - -@@ -736,8 +821,9 @@ struct TraitsExp : Expression - }; - #endif - --struct HaltExp : Expression -+class HaltExp : public Expression - { -+public: - HaltExp(Loc loc); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -745,20 +831,21 @@ struct HaltExp : Expression - elem *toElem(IRState *irs); - }; - --struct IsExp : Expression -+class IsExp : public Expression - { -+public: - /* is(targ id tok tspec) - * is(targ id == tok2) - */ - Type *targ; - Identifier *id; // can be NULL -- enum TOK tok; // ':' or '==' -+ TOK tok; // ':' or '==' - Type *tspec; // can be NULL -- enum TOK tok2; // 'struct', 'union', 'typedef', etc. -+ TOK tok2; // 'struct', 'union', 'typedef', etc. - TemplateParameters *parameters; - -- IsExp(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec, -- enum TOK tok2, TemplateParameters *parameters); -+ IsExp(Loc loc, Type *targ, Identifier *id, TOK tok, Type *tspec, -+ TOK tok2, TemplateParameters *parameters); - Expression *syntaxCopy(); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -766,19 +853,20 @@ struct IsExp : Expression - - /****************************************************************/ - --struct UnaExp : Expression -+class UnaExp : public Expression - { -+public: - Expression *e1; -+ Type *att1; // Save alias this type to detect recursion - -- UnaExp(Loc loc, enum TOK op, int size, Expression *e1); -+ UnaExp(Loc loc, TOK op, int size, Expression *e1); - Expression *syntaxCopy(); - int apply(apply_fp_t fp, void *param); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - Expression *optimize(int result, bool keepLvalue = false); - void dump(int indent); -- Expression *interpretCommon(InterState *istate, CtfeGoal goal, -- Expression *(*fp)(Type *, Expression *)); -+ Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - Expression *resolveLoc(Loc loc, Scope *sc); - - Expression *doInline(InlineDoState *ids); -@@ -787,12 +875,19 @@ struct UnaExp : Expression - virtual Expression *op_overload(Scope *sc); - }; - --struct BinExp : Expression -+typedef Expression *(*fp_t)(Type *, Expression *, Expression *); -+typedef int (*fp2_t)(Loc loc, TOK, Expression *, Expression *); -+ -+class BinExp : public Expression - { -+public: - Expression *e1; - Expression *e2; - -- BinExp(Loc loc, enum TOK op, int size, Expression *e1, Expression *e2); -+ Type *att1; // Save alias this type to detect recursion -+ Type *att2; // Save alias this type to detect recursion -+ -+ BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2); - Expression *syntaxCopy(); - int apply(apply_fp_t fp, void *param); - Expression *semantic(Scope *sc); -@@ -806,12 +901,10 @@ struct BinExp : Expression - Expression *incompatibleTypes(); - void dump(int indent); - -- Expression *interpretCommon(InterState *istate, CtfeGoal goal, -- Expression *(*fp)(Type *, Expression *, Expression *)); -- Expression *interpretCompareCommon(InterState *istate, CtfeGoal goal, -- int (*fp)(Loc, TOK, Expression *, Expression *)); -- Expression *interpretAssignCommon(InterState *istate, CtfeGoal goal, -- Expression *(*fp)(Type *, Expression *, Expression *), int post = 0); -+ Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -+ Expression *interpretCommon(InterState *istate, CtfeGoal goal, fp_t fp); -+ Expression *interpretCompareCommon(InterState *istate, CtfeGoal goal, fp2_t fp); -+ Expression *interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_t fp, int post = 0); - Expression *interpretFourPointerRelation(InterState *istate, CtfeGoal goal); - virtual Expression *arrayOp(Scope *sc); - -@@ -820,13 +913,18 @@ struct BinExp : Expression - - Expression *op_overload(Scope *sc); - Expression *compare_overload(Scope *sc, Identifier *id); -+ Expression *reorderSettingAAElem(Scope *sc); -+ -+ void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -+ Expression *buildArrayLoop(Parameters *fparams); - - elem *toElemBin(IRState *irs, int op); - }; - --struct BinAssignExp : BinExp -+class BinAssignExp : public BinExp - { -- BinAssignExp(Loc loc, enum TOK op, int size, Expression *e1, Expression *e2) -+public: -+ BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2) - : BinExp(loc, op, size, e1, e2) - { - } -@@ -834,8 +932,13 @@ struct BinAssignExp : BinExp - Expression *semantic(Scope *sc); - Expression *arrayOp(Scope *sc); - -+ Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -+ - Expression *op_overload(Scope *sc); - -+ void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -+ Expression *buildArrayLoop(Parameters *fparams); -+ - int isLvalue(); - Expression *toLvalue(Scope *sc, Expression *ex); - Expression *modifiableLvalue(Scope *sc, Expression *e); -@@ -843,22 +946,25 @@ struct BinAssignExp : BinExp - - /****************************************************************/ - --struct CompileExp : UnaExp -+class CompileExp : public UnaExp - { -+public: - CompileExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct FileExp : UnaExp -+class FileExp : public UnaExp - { -+public: - FileExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct AssertExp : UnaExp -+class AssertExp : public UnaExp - { -+public: - Expression *msg; - - AssertExp(Loc loc, Expression *e, Expression *msg = NULL); -@@ -874,31 +980,35 @@ struct AssertExp : UnaExp - elem *toElem(IRState *irs); - }; - --struct DotIdExp : UnaExp -+class DotIdExp : public UnaExp - { -+public: - Identifier *ident; - - DotIdExp(Loc loc, Expression *e, Identifier *ident); - Expression *semantic(Scope *sc); -- Expression *semantic(Scope *sc, int flag); -+ Expression *semanticX(Scope *sc); -+ Expression *semanticY(Scope *sc, int flag); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void dump(int i); - }; - --struct DotTemplateExp : UnaExp -+class DotTemplateExp : public UnaExp - { -+public: - TemplateDeclaration *td; - - DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct DotVarExp : UnaExp -+class DotVarExp : public UnaExp - { -+public: - Declaration *var; -- int hasOverloads; -+ bool hasOverloads; - -- DotVarExp(Loc loc, Expression *e, Declaration *var, int hasOverloads = 0); -+ DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads = false); - Expression *semantic(Scope *sc); - int checkModifiable(Scope *sc, int flag); - int isLvalue(); -@@ -911,25 +1021,27 @@ struct DotVarExp : UnaExp - elem *toElem(IRState *irs); - }; - --struct DotTemplateInstanceExp : UnaExp -+class DotTemplateInstanceExp : public UnaExp - { -+public: - TemplateInstance *ti; - - DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs); - Expression *syntaxCopy(); -- TemplateDeclaration *getTempdecl(Scope *sc); -+ bool findTempDecl(Scope *sc); - Expression *semantic(Scope *sc); -- Expression *semantic(Scope *sc, int flag); -+ Expression *semanticY(Scope *sc, int flag); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void dump(int indent); - }; - --struct DelegateExp : UnaExp -+class DelegateExp : public UnaExp - { -+public: - FuncDeclaration *func; -- int hasOverloads; -+ bool hasOverloads; - -- DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, int hasOverloads = 0); -+ DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, bool hasOverloads = false); - Expression *semantic(Scope *sc); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - MATCH implicitConvTo(Type *t); -@@ -941,8 +1053,9 @@ struct DelegateExp : UnaExp - elem *toElem(IRState *irs); - }; - --struct DotTypeExp : UnaExp -+class DotTypeExp : public UnaExp - { -+public: - Dsymbol *sym; // symbol that represents a type - - DotTypeExp(Loc loc, Expression *e, Dsymbol *sym); -@@ -951,8 +1064,9 @@ struct DotTypeExp : UnaExp - elem *toElem(IRState *irs); - }; - --struct CallExp : UnaExp -+class CallExp : public UnaExp - { -+public: - Expressions *arguments; // function arguments - FuncDeclaration *f; // symbol to call - -@@ -963,7 +1077,6 @@ struct CallExp : UnaExp - - Expression *syntaxCopy(); - int apply(apply_fp_t fp, void *param); -- Expression *resolveUFCS(Scope *sc); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -@@ -980,8 +1093,9 @@ struct CallExp : UnaExp - Expression *inlineScan(InlineScanState *iss); - }; - --struct AddrExp : UnaExp -+class AddrExp : public UnaExp - { -+public: - AddrExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - void checkEscape(); -@@ -990,10 +1104,12 @@ struct AddrExp : UnaExp - Expression *castTo(Scope *sc, Type *t); - Expression *optimize(int result, bool keepLvalue = false); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -+ dt_t **toDt(dt_t **pdt); - }; - --struct PtrExp : UnaExp -+class PtrExp : public UnaExp - { -+public: - PtrExp(Loc loc, Expression *e); - PtrExp(Loc loc, Expression *e, Type *t); - Expression *semantic(Scope *sc); -@@ -1011,12 +1127,12 @@ struct PtrExp : UnaExp - Identifier *opId(); - }; - --struct NegExp : UnaExp -+class NegExp : public UnaExp - { -+public: - NegExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - void buildArrayIdent(OutBuffer *buf, Expressions *arguments); - Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); -@@ -1027,8 +1143,9 @@ struct NegExp : UnaExp - elem *toElem(IRState *irs); - }; - --struct UAddExp : UnaExp -+class UAddExp : public UnaExp - { -+public: - UAddExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - -@@ -1036,12 +1153,12 @@ struct UAddExp : UnaExp - Identifier *opId(); - }; - --struct ComExp : UnaExp -+class ComExp : public UnaExp - { -+public: - ComExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - void buildArrayIdent(OutBuffer *buf, Expressions *arguments); - Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); -@@ -1052,28 +1169,29 @@ struct ComExp : UnaExp - elem *toElem(IRState *irs); - }; - --struct NotExp : UnaExp -+class NotExp : public UnaExp - { -+public: - NotExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - int isBit(); - elem *toElem(IRState *irs); - }; - --struct BoolExp : UnaExp -+class BoolExp : public UnaExp - { -+public: - BoolExp(Loc loc, Expression *e, Type *type); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - int isBit(); - elem *toElem(IRState *irs); - }; - --struct DeleteExp : UnaExp -+class DeleteExp : public UnaExp - { -+public: - DeleteExp(Loc loc, Expression *e); - Expression *semantic(Scope *sc); - Expression *checkToBoolean(Scope *sc); -@@ -1081,8 +1199,9 @@ struct DeleteExp : UnaExp - elem *toElem(IRState *irs); - }; - --struct CastExp : UnaExp -+class CastExp : public UnaExp - { -+public: - // Possible to cast to one type while painting to another type - Type *to; // type to cast to - unsigned mod; // MODxxxxx -@@ -1104,10 +1223,12 @@ struct CastExp : UnaExp - // For operator overloading - Identifier *opId(); - Expression *op_overload(Scope *sc); -+ dt_t **toDt(dt_t **pdt); - }; - --struct VectorExp : UnaExp -+class VectorExp : public UnaExp - { -+public: - TypeVector *to; // the target vector type before semantic() - unsigned dim; // number of elements in the vector - -@@ -1119,8 +1240,9 @@ struct VectorExp : UnaExp - dt_t **toDt(dt_t **pdt); - }; - --struct SliceExp : UnaExp -+class SliceExp : public UnaExp - { -+public: - Expression *upr; // NULL if implicit 0 - Expression *lwr; // NULL if implicit [length - 1] - VarDeclaration *lengthVar; -@@ -1137,6 +1259,9 @@ struct SliceExp : UnaExp - Expression *modifiableLvalue(Scope *sc, Expression *e); - int isBool(int result); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -+ Type *toStaticArrayType(); -+ MATCH implicitConvTo(Type *t); -+ Expression *castTo(Scope *sc, Type *t); - Expression *optimize(int result, bool keepLvalue = false); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - void dump(int indent); -@@ -1148,8 +1273,9 @@ struct SliceExp : UnaExp - Expression *inlineScan(InlineScanState *iss); - }; - --struct ArrayLengthExp : UnaExp -+class ArrayLengthExp : public UnaExp - { -+public: - ArrayLengthExp(Loc loc, Expression *e1); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -@@ -1162,8 +1288,9 @@ struct ArrayLengthExp : UnaExp - - // e1[a0,a1,a2,a3,...] - --struct ArrayExp : UnaExp -+class ArrayExp : public UnaExp - { -+public: - Expressions *arguments; // Array of Expression's - size_t currentDimension; // for opDollar - VarDeclaration *lengthVar; -@@ -1186,15 +1313,17 @@ struct ArrayExp : UnaExp - - /****************************************************************/ - --struct DotExp : BinExp -+class DotExp : public BinExp - { -+public: - DotExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct CommaExp : BinExp -+class CommaExp : public BinExp - { -+public: - CommaExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - void checkEscape(); -@@ -1213,10 +1342,12 @@ struct CommaExp : BinExp - elem *toElem(IRState *irs); - }; - --struct IndexExp : BinExp -+class IndexExp : public BinExp - { -+public: - VarDeclaration *lengthVar; - int modifiable; -+ bool skipboundscheck; - - IndexExp(Loc loc, Expression *e1, Expression *e2); - Expression *syntaxCopy(); -@@ -1235,9 +1366,10 @@ struct IndexExp : BinExp - - /* For both i++ and i-- - */ --struct PostExp : BinExp -+class PostExp : public BinExp - { -- PostExp(enum TOK op, Loc loc, Expression *e); -+public: -+ PostExp(TOK op, Loc loc, Expression *e); - Expression *semantic(Scope *sc); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -1247,15 +1379,18 @@ struct PostExp : BinExp - - /* For both ++i and --i - */ --struct PreExp : UnaExp -+class PreExp : public UnaExp - { -- PreExp(enum TOK op, Loc loc, Expression *e); -+public: -+ PreExp(TOK op, Loc loc, Expression *e); - Expression *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct AssignExp : BinExp --{ int ismemset; // !=0 if setting the contents of an array -+class AssignExp : public BinExp -+{ -+public: -+ int ismemset; // !=0 if setting the contents of an array - - AssignExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); -@@ -1267,19 +1402,18 @@ struct AssignExp : BinExp - elem *toElem(IRState *irs); - }; - --struct ConstructExp : AssignExp -+class ConstructExp : public AssignExp - { -+public: - ConstructExp(Loc loc, Expression *e1, Expression *e2); - }; - - #define ASSIGNEXP(op) \ --struct op##AssignExp : BinAssignExp \ -+class op##AssignExp : public BinAssignExp \ - { \ -+public: \ - op##AssignExp(Loc loc, Expression *e1, Expression *e2); \ - S(Expression *semantic(Scope *sc);) \ -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); \ -- X(void buildArrayIdent(OutBuffer *buf, Expressions *arguments);) \ -- X(Expression *buildArrayLoop(Parameters *fparams);) \ - \ - Identifier *opId(); /* For operator overloading */ \ - \ -@@ -1322,14 +1456,12 @@ ASSIGNEXP(Cat) - #undef X - #undef ASSIGNEXP - --struct AddExp : BinExp -+class AddExp : public BinExp - { -+public: - AddExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); - - // For operator overloading -@@ -1340,14 +1472,12 @@ struct AddExp : BinExp - elem *toElem(IRState *irs); - }; - --struct MinExp : BinExp -+class MinExp : public BinExp - { -+public: - MinExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); - - // For operator overloading -@@ -1357,8 +1487,9 @@ struct MinExp : BinExp - elem *toElem(IRState *irs); - }; - --struct CatExp : BinExp -+class CatExp : public BinExp - { -+public: - CatExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -@@ -1371,14 +1502,12 @@ struct CatExp : BinExp - elem *toElem(IRState *irs); - }; - --struct MulExp : BinExp -+class MulExp : public BinExp - { -+public: - MulExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); - - // For operator overloading -@@ -1389,14 +1518,12 @@ struct MulExp : BinExp - elem *toElem(IRState *irs); - }; - --struct DivExp : BinExp -+class DivExp : public BinExp - { -+public: - DivExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); - - // For operator overloading -@@ -1406,14 +1533,12 @@ struct DivExp : BinExp - elem *toElem(IRState *irs); - }; - --struct ModExp : BinExp -+class ModExp : public BinExp - { -+public: - ModExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); - - // For operator overloading -@@ -1424,14 +1549,12 @@ struct ModExp : BinExp - }; - - #if DMDV2 --struct PowExp : BinExp -+class PowExp : public BinExp - { -+public: - PowExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - - // For operator overloading - Identifier *opId(); -@@ -1441,12 +1564,12 @@ struct PowExp : BinExp - }; - #endif - --struct ShlExp : BinExp -+class ShlExp : public BinExp - { -+public: - ShlExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - IntRange getIntRange(); - - // For operator overloading -@@ -1456,12 +1579,12 @@ struct ShlExp : BinExp - elem *toElem(IRState *irs); - }; - --struct ShrExp : BinExp -+class ShrExp : public BinExp - { -+public: - ShrExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - IntRange getIntRange(); - - // For operator overloading -@@ -1471,12 +1594,12 @@ struct ShrExp : BinExp - elem *toElem(IRState *irs); - }; - --struct UshrExp : BinExp -+class UshrExp : public BinExp - { -+public: - UshrExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - IntRange getIntRange(); - - // For operator overloading -@@ -1486,14 +1609,12 @@ struct UshrExp : BinExp - elem *toElem(IRState *irs); - }; - --struct AndExp : BinExp -+class AndExp : public BinExp - { -+public: - AndExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - IntRange getIntRange(); - - // For operator overloading -@@ -1504,14 +1625,12 @@ struct AndExp : BinExp - elem *toElem(IRState *irs); - }; - --struct OrExp : BinExp -+class OrExp : public BinExp - { -+public: - OrExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - MATCH implicitConvTo(Type *t); - IntRange getIntRange(); - -@@ -1523,14 +1642,12 @@ struct OrExp : BinExp - elem *toElem(IRState *irs); - }; - --struct XorExp : BinExp -+class XorExp : public BinExp - { -+public: - XorExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -- void buildArrayIdent(OutBuffer *buf, Expressions *arguments); -- Expression *buildArrayLoop(Parameters *fparams); - MATCH implicitConvTo(Type *t); - IntRange getIntRange(); - -@@ -1542,8 +1659,9 @@ struct XorExp : BinExp - elem *toElem(IRState *irs); - }; - --struct OrOrExp : BinExp -+class OrOrExp : public BinExp - { -+public: - OrOrExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *checkToBoolean(Scope *sc); -@@ -1553,8 +1671,9 @@ struct OrOrExp : BinExp - elem *toElem(IRState *irs); - }; - --struct AndAndExp : BinExp -+class AndAndExp : public BinExp - { -+public: - AndAndExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *checkToBoolean(Scope *sc); -@@ -1564,12 +1683,12 @@ struct AndAndExp : BinExp - elem *toElem(IRState *irs); - }; - --struct CmpExp : BinExp -+class CmpExp : public BinExp - { -- CmpExp(enum TOK op, Loc loc, Expression *e1, Expression *e2); -+public: -+ CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - int isBit(); - - // For operator overloading -@@ -1580,8 +1699,9 @@ struct CmpExp : BinExp - elem *toElem(IRState *irs); - }; - --struct InExp : BinExp -+class InExp : public BinExp - { -+public: - InExp(Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); -@@ -1594,8 +1714,9 @@ struct InExp : BinExp - elem *toElem(IRState *irs); - }; - --struct RemoveExp : BinExp -+class RemoveExp : public BinExp - { -+public: - RemoveExp(Loc loc, Expression *e1, Expression *e2); - Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -1604,12 +1725,12 @@ struct RemoveExp : BinExp - - // == and != - --struct EqualExp : BinExp -+class EqualExp : public BinExp - { -- EqualExp(enum TOK op, Loc loc, Expression *e1, Expression *e2); -+public: -+ EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - int isBit(); - - // For operator overloading -@@ -1622,20 +1743,21 @@ struct EqualExp : BinExp - - // is and !is - --struct IdentityExp : BinExp -+class IdentityExp : public BinExp - { -- IdentityExp(enum TOK op, Loc loc, Expression *e1, Expression *e2); -+public: -+ IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2); - Expression *semantic(Scope *sc); - int isBit(); - Expression *optimize(int result, bool keepLvalue = false); -- Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); - elem *toElem(IRState *irs); - }; - - /****************************************************************/ - --struct CondExp : BinExp -+class CondExp : public BinExp - { -+public: - Expression *econd; - - CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2); -@@ -1654,7 +1776,7 @@ struct CondExp : BinExp - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); -- Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); -+ Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); - - Expression *doInline(InlineDoState *ids); - Expression *inlineScan(InlineScanState *iss); -@@ -1665,38 +1787,66 @@ struct CondExp : BinExp - #if DMDV2 - /****************************************************************/ - --struct DefaultInitExp : Expression -+class DefaultInitExp : public Expression - { -- enum TOK subop; // which of the derived classes this is -+public: -+ TOK subop; // which of the derived classes this is - -- DefaultInitExp(Loc loc, enum TOK subop, int size); -+ DefaultInitExp(Loc loc, TOK subop, int size); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct FileInitExp : DefaultInitExp -+class FileInitExp : public DefaultInitExp - { -+public: - FileInitExp(Loc loc); - Expression *semantic(Scope *sc); - Expression *resolveLoc(Loc loc, Scope *sc); - }; - --struct LineInitExp : DefaultInitExp -+class LineInitExp : public DefaultInitExp - { -+public: - LineInitExp(Loc loc); - Expression *semantic(Scope *sc); - Expression *resolveLoc(Loc loc, Scope *sc); - }; -+ -+class ModuleInitExp : public DefaultInitExp -+{ -+public: -+ ModuleInitExp(Loc loc); -+ Expression *semantic(Scope *sc); -+ Expression *resolveLoc(Loc loc, Scope *sc); -+}; -+ -+class FuncInitExp : public DefaultInitExp -+{ -+public: -+ FuncInitExp(Loc loc); -+ Expression *semantic(Scope *sc); -+ Expression *resolveLoc(Loc loc, Scope *sc); -+}; -+ -+class PrettyFuncInitExp : public DefaultInitExp -+{ -+public: -+ PrettyFuncInitExp(Loc loc); -+ Expression *semantic(Scope *sc); -+ Expression *resolveLoc(Loc loc, Scope *sc); -+}; -+ - #endif - - /****************************************************************/ - - /* Special values used by the interpreter - */ --#define EXP_CANT_INTERPRET ((Expression *)1) --#define EXP_CONTINUE_INTERPRET ((Expression *)2) --#define EXP_BREAK_INTERPRET ((Expression *)3) --#define EXP_GOTO_INTERPRET ((Expression *)4) --#define EXP_VOID_INTERPRET ((Expression *)5) -+extern Expression *EXP_CANT_INTERPRET; -+extern Expression *EXP_CONTINUE_INTERPRET; -+extern Expression *EXP_BREAK_INTERPRET; -+extern Expression *EXP_GOTO_INTERPRET; -+extern Expression *EXP_VOID_INTERPRET; - - Expression *expType(Type *type, Expression *e); - -@@ -1723,9 +1873,9 @@ Expression *Xor(Type *type, Expression * - Expression *Index(Type *type, Expression *e1, Expression *e2); - Expression *Cat(Type *type, Expression *e1, Expression *e2); - --Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2); --Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2); --Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2); -+Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2); -+Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2); -+Expression *Identity(TOK op, Type *type, Expression *e1, Expression *e2); - - Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr); - ---- a/src/gcc/d/dfrontend/file.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/file.c 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,514 @@ -+ -+// Copyright (c) 1999-2012 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#include "file.h" -+ -+#if defined (__sun) -+#include -+#endif -+ -+#if _MSC_VER ||__MINGW32__ -+#include -+#include -+#endif -+ -+#if _WIN32 -+#include -+#include -+#include -+#endif -+ -+#if POSIX -+#include -+#include -+#include -+#include -+#include -+#include -+#endif -+ -+#include "filename.h" -+#include "array.h" -+#include "port.h" -+#include "rmem.h" -+ -+/****************************** File ********************************/ -+ -+File::File(const FileName *n) -+{ -+ ref = 0; -+ buffer = NULL; -+ len = 0; -+ touchtime = NULL; -+ name = (FileName *)n; -+} -+ -+File::File(const char *n) -+{ -+ ref = 0; -+ buffer = NULL; -+ len = 0; -+ touchtime = NULL; -+ name = new FileName(n); -+} -+ -+File::~File() -+{ -+ if (buffer) -+ { -+ if (ref == 0) -+ mem.free(buffer); -+#if _WIN32 -+ if (ref == 2) -+ UnmapViewOfFile(buffer); -+#endif -+ } -+ if (touchtime) -+ mem.free(touchtime); -+} -+ -+/************************************* -+ */ -+ -+int File::read() -+{ -+ if (len) -+ return 0; // already read the file -+#if POSIX -+ off_t size; -+ ssize_t numread; -+ int fd; -+ struct stat buf; -+ int result = 0; -+ char *name; -+ -+ name = this->name->toChars(); -+ //printf("File::read('%s')\n",name); -+ fd = open(name, O_RDONLY); -+ if (fd == -1) -+ { -+ //printf("\topen error, errno = %d\n",errno); -+ goto err1; -+ } -+ -+ if (!ref) -+ ::free(buffer); -+ ref = 0; // we own the buffer now -+ -+ //printf("\tfile opened\n"); -+ if (fstat(fd, &buf)) -+ { -+ printf("\tfstat error, errno = %d\n",errno); -+ goto err2; -+ } -+ size = buf.st_size; -+ buffer = (utf8_t *) ::malloc(size + 2); -+ if (!buffer) -+ { -+ printf("\tmalloc error, errno = %d\n",errno); -+ goto err2; -+ } -+ -+ numread = ::read(fd, buffer, size); -+ if (numread != size) -+ { -+ printf("\tread error, errno = %d\n",errno); -+ goto err2; -+ } -+ -+ if (touchtime) -+ memcpy(touchtime, &buf, sizeof(buf)); -+ -+ if (close(fd) == -1) -+ { -+ printf("\tclose error, errno = %d\n",errno); -+ goto err; -+ } -+ -+ len = size; -+ -+ // Always store a wchar ^Z past end of buffer so scanner has a sentinel -+ buffer[size] = 0; // ^Z is obsolete, use 0 -+ buffer[size + 1] = 0; -+ return 0; -+ -+err2: -+ close(fd); -+err: -+ ::free(buffer); -+ buffer = NULL; -+ len = 0; -+ -+err1: -+ result = 1; -+ return result; -+#elif _WIN32 -+ DWORD size; -+ DWORD numread; -+ HANDLE h; -+ int result = 0; -+ char *name; -+ -+ name = this->name->toChars(); -+ h = CreateFileA(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, -+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); -+ if (h == INVALID_HANDLE_VALUE) -+ goto err1; -+ -+ if (!ref) -+ ::free(buffer); -+ ref = 0; -+ -+ size = GetFileSize(h,NULL); -+ buffer = (utf8_t *) ::malloc(size + 2); -+ if (!buffer) -+ goto err2; -+ -+ if (ReadFile(h,buffer,size,&numread,NULL) != TRUE) -+ goto err2; -+ -+ if (numread != size) -+ goto err2; -+ -+ if (touchtime) -+ { -+ if (!GetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime)) -+ goto err2; -+ } -+ -+ if (!CloseHandle(h)) -+ goto err; -+ -+ len = size; -+ -+ // Always store a wchar ^Z past end of buffer so scanner has a sentinel -+ buffer[size] = 0; // ^Z is obsolete, use 0 -+ buffer[size + 1] = 0; -+ return 0; -+ -+err2: -+ CloseHandle(h); -+err: -+ ::free(buffer); -+ buffer = NULL; -+ len = 0; -+ -+err1: -+ result = 1; -+ return result; -+#else -+ assert(0); -+#endif -+} -+ -+/***************************** -+ * Read a file with memory mapped file I/O. -+ */ -+ -+int File::mmread() -+{ -+#if POSIX -+ return read(); -+#elif _WIN32 -+ HANDLE hFile; -+ HANDLE hFileMap; -+ DWORD size; -+ char *name; -+ -+ name = this->name->toChars(); -+ hFile = CreateFile(name, GENERIC_READ, -+ FILE_SHARE_READ, NULL, -+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -+ if (hFile == INVALID_HANDLE_VALUE) -+ goto Lerr; -+ size = GetFileSize(hFile, NULL); -+ //printf(" file created, size %d\n", size); -+ -+ hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,size,NULL); -+ if (CloseHandle(hFile) != TRUE) -+ goto Lerr; -+ -+ if (hFileMap == NULL) -+ goto Lerr; -+ -+ //printf(" mapping created\n"); -+ -+ if (!ref) -+ mem.free(buffer); -+ ref = 2; -+ buffer = (utf8_t *)MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL); -+ if (CloseHandle(hFileMap) != TRUE) -+ goto Lerr; -+ if (buffer == NULL) // mapping view failed -+ goto Lerr; -+ -+ len = size; -+ //printf(" buffer = %p\n", buffer); -+ -+ return 0; -+ -+Lerr: -+ return GetLastError(); // failure -+#else -+ assert(0); -+#endif -+} -+ -+/********************************************* -+ * Write a file. -+ * Returns: -+ * 0 success -+ */ -+ -+int File::write() -+{ -+#if POSIX -+ int fd; -+ ssize_t numwritten; -+ char *name; -+ -+ name = this->name->toChars(); -+ fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644); -+ if (fd == -1) -+ goto err; -+ -+ numwritten = ::write(fd, buffer, len); -+ if (len != numwritten) -+ goto err2; -+ -+ if (close(fd) == -1) -+ goto err; -+ -+ if (touchtime) -+ { struct utimbuf ubuf; -+ -+ ubuf.actime = ((struct stat *)touchtime)->st_atime; -+ ubuf.modtime = ((struct stat *)touchtime)->st_mtime; -+ if (utime(name, &ubuf)) -+ goto err; -+ } -+ return 0; -+ -+err2: -+ close(fd); -+ ::remove(name); -+err: -+ return 1; -+#elif _WIN32 -+ HANDLE h; -+ DWORD numwritten; -+ char *name; -+ -+ name = this->name->toChars(); -+ h = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, -+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); -+ if (h == INVALID_HANDLE_VALUE) -+ goto err; -+ -+ if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE) -+ goto err2; -+ -+ if (len != numwritten) -+ goto err2; -+ -+ if (touchtime) { -+ SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime); -+ } -+ if (!CloseHandle(h)) -+ goto err; -+ return 0; -+ -+err2: -+ CloseHandle(h); -+ DeleteFileA(name); -+err: -+ return 1; -+#else -+ assert(0); -+#endif -+} -+ -+/********************************************* -+ * Append to a file. -+ * Returns: -+ * 0 success -+ */ -+ -+int File::append() -+{ -+#if POSIX -+ return 1; -+#elif _WIN32 -+ HANDLE h; -+ DWORD numwritten; -+ char *name; -+ -+ name = this->name->toChars(); -+ h = CreateFileA(name,GENERIC_WRITE,0,NULL,OPEN_ALWAYS, -+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); -+ if (h == INVALID_HANDLE_VALUE) -+ goto err; -+ -+#if 1 -+ SetFilePointer(h, 0, NULL, FILE_END); -+#else // INVALID_SET_FILE_POINTER doesn't seem to have a definition -+ if (SetFilePointer(h, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) -+ goto err; -+#endif -+ -+ if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE) -+ goto err2; -+ -+ if (len != numwritten) -+ goto err2; -+ -+ if (touchtime) { -+ SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime); -+ } -+ if (!CloseHandle(h)) -+ goto err; -+ return 0; -+ -+err2: -+ CloseHandle(h); -+err: -+ return 1; -+#else -+ assert(0); -+#endif -+} -+ -+/******************************************* -+ * Return !=0 if file exists. -+ * 0: file doesn't exist -+ * 1: normal file -+ * 2: directory -+ */ -+ -+int File::exists() -+{ -+#if POSIX -+ return 0; -+#elif _WIN32 -+ DWORD dw; -+ int result; -+ char *name; -+ -+ name = this->name->toChars(); -+ if (touchtime) -+ dw = ((WIN32_FIND_DATAA *)touchtime)->dwFileAttributes; -+ else -+ dw = GetFileAttributesA(name); -+ if (dw == -1L) -+ result = 0; -+ else if (dw & FILE_ATTRIBUTE_DIRECTORY) -+ result = 2; -+ else -+ result = 1; -+ return result; -+#else -+ assert(0); -+#endif -+} -+ -+void File::remove() -+{ -+#if POSIX -+ int dummy = ::remove(this->name->toChars()); -+#elif _WIN32 -+ DeleteFileA(this->name->toChars()); -+#else -+ assert(0); -+#endif -+} -+ -+Files *File::match(char *n) -+{ -+ return match(new FileName(n)); -+} -+ -+Files *File::match(FileName *n) -+{ -+#if POSIX -+ return NULL; -+#elif _WIN32 -+ HANDLE h; -+ WIN32_FIND_DATAA fileinfo; -+ -+ Files *a = new Files(); -+ const char *c = n->toChars(); -+ const char *name = n->name(); -+ h = FindFirstFileA(c,&fileinfo); -+ if (h != INVALID_HANDLE_VALUE) -+ { -+ do -+ { -+ // Glue path together with name -+ char *fn; -+ File *f; -+ -+ fn = (char *)mem.malloc(name - c + strlen(&fileinfo.cFileName[0]) + 1); -+ memcpy(fn, c, name - c); -+ strcpy(fn + (name - c), &fileinfo.cFileName[0]); -+ f = new File(fn); -+ f->touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); -+ memcpy(f->touchtime, &fileinfo, sizeof(fileinfo)); -+ a->push(f); -+ } while (FindNextFileA(h,&fileinfo) != FALSE); -+ FindClose(h); -+ } -+ return a; -+#else -+ assert(0); -+#endif -+} -+ -+int File::compareTime(File *f) -+{ -+#if POSIX -+ return 0; -+#elif _WIN32 -+ if (!touchtime) -+ stat(); -+ if (!f->touchtime) -+ f->stat(); -+ return CompareFileTime(&((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime, &((WIN32_FIND_DATAA *)f->touchtime)->ftLastWriteTime); -+#else -+ assert(0); -+#endif -+} -+ -+void File::stat() -+{ -+#if POSIX -+ if (!touchtime) -+ { -+ touchtime = mem.calloc(1, sizeof(struct stat)); -+ } -+#elif _WIN32 -+ HANDLE h; -+ -+ if (!touchtime) -+ { -+ touchtime = mem.calloc(1, sizeof(WIN32_FIND_DATAA)); -+ } -+ h = FindFirstFileA(name->toChars(),(WIN32_FIND_DATAA *)touchtime); -+ if (h != INVALID_HANDLE_VALUE) -+ { -+ FindClose(h); -+ } -+#else -+ assert(0); -+#endif -+} -+ -+char *File::toChars() -+{ -+ return name->toChars(); -+} ---- a/src/gcc/d/dfrontend/file.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/file.h 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,103 @@ -+ -+// Copyright (c) 1999-2011 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#ifndef FILE_H -+#define FILE_H -+ -+#if __DMC__ -+#pragma once -+#endif -+ -+#include -+ -+#include "array.h" -+ -+template struct Array; -+typedef Array Files; -+ -+struct FileName; -+ -+struct File -+{ -+ int ref; // != 0 if this is a reference to someone else's buffer -+ unsigned char *buffer; // data for our file -+ size_t len; // amount of data in buffer[] -+ void *touchtime; // system time to use for file -+ -+ FileName *name; // name of our file -+ -+ File(const char *); -+ File(const FileName *); -+ ~File(); -+ -+ char *toChars(); -+ -+ /* Read file, return !=0 if error -+ */ -+ -+ int read(); -+ -+ /* Read file, return !=0 if error -+ */ -+ -+ int mmread(); -+ -+ /* Write file, return !=0 if error -+ */ -+ -+ int write(); -+ -+ /* Return !=0 if file exists. -+ * 0: file doesn't exist -+ * 1: normal file -+ * 2: directory -+ */ -+ -+ /* Append to file, return !=0 if error -+ */ -+ -+ int append(); -+ -+ /* Return !=0 if file exists. -+ * 0: file doesn't exist -+ * 1: normal file -+ * 2: directory -+ */ -+ -+ int exists(); -+ -+ /* Given wildcard filespec, return an array of -+ * matching File's. -+ */ -+ -+ static Files *match(char *); -+ static Files *match(FileName *); -+ -+ // Compare file times. -+ // Return <0 this < f -+ // =0 this == f -+ // >0 this > f -+ int compareTime(File *f); -+ -+ // Read system file statistics -+ void stat(); -+ -+ /* Set buffer -+ */ -+ -+ void setbuffer(void *buffer, size_t len) -+ { -+ this->buffer = (unsigned char *)buffer; -+ this->len = len; -+ } -+ -+ void remove(); // delete file -+}; -+ -+#endif ---- a/src/gcc/d/dfrontend/filename.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/filename.c 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,690 @@ -+ -+// Copyright (c) 1999-2012 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#include "filename.h" -+ -+#include -+#include -+ -+#include "outbuffer.h" -+#include "array.h" -+#include "file.h" -+#include "rmem.h" -+ -+#if defined (__sun) -+#include -+#endif -+ -+#if _MSC_VER ||__MINGW32__ -+#include -+#include -+#endif -+ -+#if _WIN32 -+#include -+#include -+#include -+#endif -+ -+#if POSIX -+#include -+#include -+#include -+#include -+#include -+#include -+#endif -+ -+/****************************** FileName ********************************/ -+ -+FileName::FileName(const char *str) -+ : str(mem.strdup(str)) -+{ -+} -+ -+const char *FileName::combine(const char *path, const char *name) -+{ char *f; -+ size_t pathlen; -+ size_t namelen; -+ -+ if (!path || !*path) -+ return (char *)name; -+ pathlen = strlen(path); -+ namelen = strlen(name); -+ f = (char *)mem.malloc(pathlen + 1 + namelen + 1); -+ memcpy(f, path, pathlen); -+#if POSIX -+ if (path[pathlen - 1] != '/') -+ { f[pathlen] = '/'; -+ pathlen++; -+ } -+#elif _WIN32 -+ if (path[pathlen - 1] != '\\' && -+ path[pathlen - 1] != '/' && -+ path[pathlen - 1] != ':') -+ { f[pathlen] = '\\'; -+ pathlen++; -+ } -+#else -+ assert(0); -+#endif -+ memcpy(f + pathlen, name, namelen + 1); -+ return f; -+} -+ -+// Split a path into an Array of paths -+Strings *FileName::splitPath(const char *path) -+{ -+ char c = 0; // unnecessary initializer is for VC /W4 -+ const char *p; -+ OutBuffer buf; -+ Strings *array; -+ -+ array = new Strings(); -+ if (path) -+ { -+ p = path; -+ do -+ { char instring = 0; -+ -+ while (isspace((utf8_t)*p)) // skip leading whitespace -+ p++; -+ buf.reserve(strlen(p) + 1); // guess size of path -+ for (; ; p++) -+ { -+ c = *p; -+ switch (c) -+ { -+ case '"': -+ instring ^= 1; // toggle inside/outside of string -+ continue; -+ -+#if MACINTOSH -+ case ',': -+#endif -+#if _WIN32 -+ case ';': -+#endif -+#if POSIX -+ case ':': -+#endif -+ p++; -+ break; // note that ; cannot appear as part -+ // of a path, quotes won't protect it -+ -+ case 0x1A: // ^Z means end of file -+ case 0: -+ break; -+ -+ case '\r': -+ continue; // ignore carriage returns -+ -+#if POSIX -+ case '~': -+ buf.writestring(getenv("HOME")); -+ continue; -+#endif -+ -+#if 0 -+ case ' ': -+ case '\t': // tabs in filenames? -+ if (!instring) // if not in string -+ break; // treat as end of path -+#endif -+ default: -+ buf.writeByte(c); -+ continue; -+ } -+ break; -+ } -+ if (buf.offset) // if path is not empty -+ { -+ buf.writeByte(0); // to asciiz -+ array->push(buf.extractData()); -+ } -+ } while (c); -+ } -+ return array; -+} -+ -+int FileName::compare(RootObject *obj) -+{ -+ return compare(str, ((FileName *)obj)->str); -+} -+ -+int FileName::compare(const char *name1, const char *name2) -+{ -+#if _WIN32 -+ return stricmp(name1, name2); -+#else -+ return strcmp(name1, name2); -+#endif -+} -+ -+bool FileName::equals(RootObject *obj) -+{ -+ return compare(obj) == 0; -+} -+ -+int FileName::equals(const char *name1, const char *name2) -+{ -+ return compare(name1, name2) == 0; -+} -+ -+/************************************ -+ * Return !=0 if absolute path name. -+ */ -+ -+int FileName::absolute(const char *name) -+{ -+#if _WIN32 -+ return (*name == '\\') || -+ (*name == '/') || -+ (*name && name[1] == ':'); -+#elif POSIX -+ return (*name == '/'); -+#else -+ assert(0); -+#endif -+} -+ -+/******************************** -+ * Return filename extension (read-only). -+ * Points past '.' of extension. -+ * If there isn't one, return NULL. -+ */ -+ -+const char *FileName::ext(const char *str) -+{ -+ size_t len = strlen(str); -+ -+ const char *e = str + len; -+ for (;;) -+ { -+ switch (*e) -+ { case '.': -+ return e + 1; -+#if POSIX -+ case '/': -+ break; -+#endif -+#if _WIN32 -+ case '\\': -+ case ':': -+ case '/': -+ break; -+#endif -+ default: -+ if (e == str) -+ break; -+ e--; -+ continue; -+ } -+ return NULL; -+ } -+} -+ -+const char *FileName::ext() -+{ -+ return ext(str); -+} -+ -+/******************************** -+ * Return mem.malloc'd filename with extension removed. -+ */ -+ -+const char *FileName::removeExt(const char *str) -+{ -+ const char *e = ext(str); -+ if (e) -+ { size_t len = (e - str) - 1; -+ char *n = (char *)mem.malloc(len + 1); -+ memcpy(n, str, len); -+ n[len] = 0; -+ return n; -+ } -+ return mem.strdup(str); -+} -+ -+/******************************** -+ * Return filename name excluding path (read-only). -+ */ -+ -+const char *FileName::name(const char *str) -+{ -+ size_t len = strlen(str); -+ -+ const char *e = str + len; -+ for (;;) -+ { -+ switch (*e) -+ { -+#if POSIX -+ case '/': -+ return e + 1; -+#endif -+#if _WIN32 -+ case '/': -+ case '\\': -+ return e + 1; -+ case ':': -+ /* The ':' is a drive letter only if it is the second -+ * character or the last character, -+ * otherwise it is an ADS (Alternate Data Stream) separator. -+ * Consider ADS separators as part of the file name. -+ */ -+ if (e == str + 1 || e == str + len - 1) -+ return e + 1; -+#endif -+ default: -+ if (e == str) -+ break; -+ e--; -+ continue; -+ } -+ return e; -+ } -+} -+ -+const char *FileName::name() -+{ -+ return name(str); -+} -+ -+/************************************** -+ * Return path portion of str. -+ * Path will does not include trailing path separator. -+ */ -+ -+const char *FileName::path(const char *str) -+{ -+ const char *n = name(str); -+ size_t pathlen; -+ -+ if (n > str) -+ { -+#if POSIX -+ if (n[-1] == '/') -+ n--; -+#elif _WIN32 -+ if (n[-1] == '\\' || n[-1] == '/') -+ n--; -+#else -+ assert(0); -+#endif -+ } -+ pathlen = n - str; -+ char *path = (char *)mem.malloc(pathlen + 1); -+ memcpy(path, str, pathlen); -+ path[pathlen] = 0; -+ return path; -+} -+ -+/************************************** -+ * Replace filename portion of path. -+ */ -+ -+const char *FileName::replaceName(const char *path, const char *name) -+{ -+ size_t pathlen; -+ size_t namelen; -+ -+ if (absolute(name)) -+ return name; -+ -+ const char *n = FileName::name(path); -+ if (n == path) -+ return name; -+ pathlen = n - path; -+ namelen = strlen(name); -+ char *f = (char *)mem.malloc(pathlen + 1 + namelen + 1); -+ memcpy(f, path, pathlen); -+#if POSIX -+ if (path[pathlen - 1] != '/') -+ { f[pathlen] = '/'; -+ pathlen++; -+ } -+#elif _WIN32 -+ if (path[pathlen - 1] != '\\' && -+ path[pathlen - 1] != '/' && -+ path[pathlen - 1] != ':') -+ { f[pathlen] = '\\'; -+ pathlen++; -+ } -+#else -+ assert(0); -+#endif -+ memcpy(f + pathlen, name, namelen + 1); -+ return f; -+} -+ -+/*************************** -+ * Free returned value with FileName::free() -+ */ -+ -+const char *FileName::defaultExt(const char *name, const char *ext) -+{ -+ const char *e = FileName::ext(name); -+ if (e) // if already has an extension -+ return mem.strdup(name); -+ -+ size_t len = strlen(name); -+ size_t extlen = strlen(ext); -+ char *s = (char *)mem.malloc(len + 1 + extlen + 1); -+ memcpy(s,name,len); -+ s[len] = '.'; -+ memcpy(s + len + 1, ext, extlen + 1); -+ return s; -+} -+ -+/*************************** -+ * Free returned value with FileName::free() -+ */ -+ -+const char *FileName::forceExt(const char *name, const char *ext) -+{ -+ const char *e = FileName::ext(name); -+ if (e) // if already has an extension -+ { -+ size_t len = e - name; -+ size_t extlen = strlen(ext); -+ -+ char *s = (char *)mem.malloc(len + extlen + 1); -+ memcpy(s,name,len); -+ memcpy(s + len, ext, extlen + 1); -+ return s; -+ } -+ else -+ return defaultExt(name, ext); // doesn't have one -+} -+ -+/****************************** -+ * Return !=0 if extensions match. -+ */ -+ -+int FileName::equalsExt(const char *ext) -+{ -+ return equalsExt(str, ext); -+} -+ -+int FileName::equalsExt(const char *name, const char *ext) -+{ -+ const char *e = FileName::ext(name); -+ if (!e && !ext) -+ return 1; -+ if (!e || !ext) -+ return 0; -+ return FileName::compare(e, ext) == 0; -+} -+ -+/************************************* -+ * Search Path for file. -+ * Input: -+ * cwd if !=0, search current directory before searching path -+ */ -+ -+const char *FileName::searchPath(Strings *path, const char *name, int cwd) -+{ -+ if (absolute(name)) -+ { -+ return exists(name) ? name : NULL; -+ } -+ if (cwd) -+ { -+ if (exists(name)) -+ return name; -+ } -+ if (path) -+ { -+ -+ for (size_t i = 0; i < path->dim; i++) -+ { -+ const char *p = (*path)[i]; -+ const char *n = combine(p, name); -+ -+ if (exists(n)) -+ return n; -+ } -+ } -+ return NULL; -+} -+ -+ -+/************************************* -+ * Search Path for file in a safe manner. -+ * -+ * Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory -+ * ('Path Traversal') attacks. -+ * http://cwe.mitre.org/data/definitions/22.html -+ * More info: -+ * https://www.securecoding.cert.org/confluence/display/seccode/FIO02-C.+Canonicalize+path+names+originating+from+untrusted+sources -+ * Returns: -+ * NULL file not found -+ * !=NULL mem.malloc'd file name -+ */ -+ -+const char *FileName::safeSearchPath(Strings *path, const char *name) -+{ -+#if _WIN32 -+ /* Disallow % / \ : and .. in name characters -+ */ -+ for (const char *p = name; *p; p++) -+ { -+ char c = *p; -+ if (c == '\\' || c == '/' || c == ':' || c == '%' || -+ (c == '.' && p[1] == '.')) -+ { -+ return NULL; -+ } -+ } -+ -+ return FileName::searchPath(path, name, 0); -+#elif POSIX -+ /* Even with realpath(), we must check for // and disallow it -+ */ -+ for (const char *p = name; *p; p++) -+ { -+ char c = *p; -+ if (c == '/' && p[1] == '/') -+ { -+ return NULL; -+ } -+ } -+ -+ if (path) -+ { -+ /* Each path is converted to a cannonical name and then a check is done to see -+ * that the searched name is really a child one of the the paths searched. -+ */ -+ for (size_t i = 0; i < path->dim; i++) -+ { -+ const char *cname = NULL; -+ const char *cpath = canonicalName((*path)[i]); -+ //printf("FileName::safeSearchPath(): name=%s; path=%s; cpath=%s\n", -+ // name, (char *)path->data[i], cpath); -+ if (cpath == NULL) -+ goto cont; -+ cname = canonicalName(combine(cpath, name)); -+ //printf("FileName::safeSearchPath(): cname=%s\n", cname); -+ if (cname == NULL) -+ goto cont; -+ //printf("FileName::safeSearchPath(): exists=%i " -+ // "strncmp(cpath, cname, %i)=%i\n", exists(cname), -+ // strlen(cpath), strncmp(cpath, cname, strlen(cpath))); -+ // exists and name is *really* a "child" of path -+ if (exists(cname) && strncmp(cpath, cname, strlen(cpath)) == 0) -+ { -+ ::free((void *)cpath); -+ const char *p = mem.strdup(cname); -+ ::free((void *)cname); -+ return p; -+ } -+cont: -+ if (cpath) -+ ::free((void *)cpath); -+ if (cname) -+ ::free((void *)cname); -+ } -+ } -+ return NULL; -+#else -+ assert(0); -+#endif -+} -+ -+ -+int FileName::exists(const char *name) -+{ -+#if POSIX -+ struct stat st; -+ -+ if (stat(name, &st) < 0) -+ return 0; -+ if (S_ISDIR(st.st_mode)) -+ return 2; -+ return 1; -+#elif _WIN32 -+ DWORD dw; -+ int result; -+ -+ dw = GetFileAttributesA(name); -+ if (dw == -1L) -+ result = 0; -+ else if (dw & FILE_ATTRIBUTE_DIRECTORY) -+ result = 2; -+ else -+ result = 1; -+ return result; -+#else -+ assert(0); -+#endif -+} -+ -+int FileName::ensurePathExists(const char *path) -+{ -+ //printf("FileName::ensurePathExists(%s)\n", path ? path : ""); -+ if (path && *path) -+ { -+ if (!exists(path)) -+ { -+ const char *p = FileName::path(path); -+ if (*p) -+ { -+#if _WIN32 -+ size_t len = strlen(path); -+ if ((len > 2 && p[-1] == ':' && strcmp(path + 2, p) == 0) || -+ len == strlen(p)) -+ { mem.free((void *)p); -+ return 0; -+ } -+#endif -+ int r = ensurePathExists(p); -+ mem.free((void *)p); -+ if (r) -+ return r; -+ } -+#if _WIN32 -+ char sep = '\\'; -+#elif POSIX -+ char sep = '/'; -+#endif -+ if (path[strlen(path) - 1] != sep) -+ { -+ //printf("mkdir(%s)\n", path); -+#if _WIN32 -+ int r = _mkdir(path); -+#endif -+#if POSIX -+ int r = mkdir(path, 0777); -+#endif -+ if (r) -+ { -+ /* Don't error out if another instance of dmd just created -+ * this directory -+ */ -+ if (errno != EEXIST) -+ return 1; -+ } -+ } -+ } -+ } -+ return 0; -+} -+ -+/****************************************** -+ * Return canonical version of name in a malloc'd buffer. -+ * This code is high risk. -+ */ -+const char *FileName::canonicalName(const char *name) -+{ -+#if linux -+ // Lovely glibc extension to do it for us -+ return canonicalize_file_name(name); -+#elif POSIX -+ #if _POSIX_VERSION >= 200809L || defined (linux) -+ // NULL destination buffer is allowed and preferred -+ return realpath(name, NULL); -+ #else -+ char *cname = NULL; -+ #if PATH_MAX -+ /* PATH_MAX must be defined as a constant in , -+ * otherwise using it is unsafe due to TOCTOU -+ */ -+ size_t path_max = (size_t)PATH_MAX; -+ if (path_max > 0) -+ { -+ /* Need to add one to PATH_MAX because of realpath() buffer overflow bug: -+ * http://isec.pl/vulnerabilities/isec-0011-wu-ftpd.txt -+ */ -+ cname = (char *)malloc(path_max + 1); -+ if (cname == NULL) -+ return NULL; -+ } -+ #endif -+ return realpath(name, cname); -+ #endif -+#elif _WIN32 -+ /* Apparently, there is no good way to do this on Windows. -+ * GetFullPathName isn't it, but use it anyway. -+ */ -+ DWORD result = GetFullPathName(name, 0, NULL, NULL); -+ if (result) -+ { -+ char *buf = (char *)malloc(result); -+ result = GetFullPathName(name, result, buf, NULL); -+ if (result == 0) -+ { -+ ::free(buf); -+ return NULL; -+ } -+ return buf; -+ } -+ return NULL; -+#else -+ assert(0); -+ return NULL; -+#endif -+} -+ -+/******************************** -+ * Free memory allocated by FileName routines -+ */ -+void FileName::free(const char *str) -+{ -+ if (str) -+ { assert(str[0] != 0xAB); -+ memset((void *)str, 0xAB, strlen(str) + 1); // stomp -+ } -+ mem.free((void *)str); -+} -+ -+char *FileName::toChars() -+{ -+ return (char *)str; // toChars() should really be const -+} ---- a/src/gcc/d/dfrontend/filename.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/filename.h 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,59 @@ -+ -+// Copyright (c) 1999-2011 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#ifndef FILENAME_H -+#define FILENAME_H -+ -+#if __DMC__ -+#pragma once -+#endif -+ -+#include "array.h" -+ -+class RootObject; -+ -+template struct Array; -+typedef Array Strings; -+ -+struct FileName -+{ -+ const char *str; -+ FileName(const char *str); -+ bool equals(RootObject *obj); -+ static int equals(const char *name1, const char *name2); -+ int compare(RootObject *obj); -+ static int compare(const char *name1, const char *name2); -+ static int absolute(const char *name); -+ static const char *ext(const char *); -+ const char *ext(); -+ static const char *removeExt(const char *str); -+ static const char *name(const char *); -+ const char *name(); -+ static const char *path(const char *); -+ static const char *replaceName(const char *path, const char *name); -+ -+ static const char *combine(const char *path, const char *name); -+ static Strings *splitPath(const char *path); -+ static const char *defaultExt(const char *name, const char *ext); -+ static const char *forceExt(const char *name, const char *ext); -+ static int equalsExt(const char *name, const char *ext); -+ -+ int equalsExt(const char *ext); -+ -+ static const char *searchPath(Strings *path, const char *name, int cwd); -+ static const char *safeSearchPath(Strings *path, const char *name); -+ static int exists(const char *name); -+ static int ensurePathExists(const char *path); -+ static const char *canonicalName(const char *name); -+ -+ static void free(const char *str); -+ char *toChars(); -+}; -+ -+#endif ---- a/src/gcc/d/dfrontend/func.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/func.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -25,6 +25,11 @@ - #include "template.h" - #include "hdrgen.h" - #include "target.h" -+#include "parse.h" -+#include "rmem.h" -+ -+void functionToCBuffer2(TypeFunction *t, OutBuffer *buf, HdrGenState *hgs, int mod, const char *kind); -+void genCmain(Scope *sc); - - /********************************* FuncDeclaration ****************************/ - -@@ -60,14 +65,16 @@ FuncDeclaration::FuncDeclaration(Loc loc - parameters = NULL; - labtab = NULL; - overnext = NULL; -+ overnext0 = NULL; - vtblIndex = -1; - hasReturnExp = 0; - naked = 0; - inlineStatusExp = ILSuninitialized; - inlineStatusStmt = ILSuninitialized; - inlineNest = 0; -+ ctfeCode = NULL; - isArrayOp = 0; -- semanticRun = PASSinit; -+ dArrayOp = NULL; - semantic3Errors = 0; - #if DMDV1 - nestedFrameRef = 0; -@@ -118,7 +125,6 @@ void FuncDeclaration::semantic(Scope *sc - StructDeclaration *sd; - ClassDeclaration *cd; - InterfaceDeclaration *id; -- Dsymbol *pd; - bool doesoverride; - - #if 0 -@@ -139,25 +145,17 @@ void FuncDeclaration::semantic(Scope *sc - return; - } - -+ if (semanticRun >= PASSsemanticdone) -+ return; -+ assert(semanticRun <= PASSsemantic); -+ semanticRun = PASSsemantic; -+ - parent = sc->parent; - Dsymbol *parent = toParent(); - -- if (semanticRun >= PASSsemanticdone) -- { -- if (!parent->isClassDeclaration()) -- { -- return; -- } -- // need to re-run semantic() in order to set the class's vtbl[] -- } -- else -- { -- assert(semanticRun <= PASSsemantic); -- semanticRun = PASSsemantic; -- } -- - if (scope) -- { sc = scope; -+ { -+ sc = scope; - scope = NULL; - } - -@@ -174,6 +172,9 @@ void FuncDeclaration::semantic(Scope *sc - if (StructDeclaration *sd = ad->isStructDeclaration()) - sd->makeNested(); - } -+ // Remove prefix storage classes silently. -+ if ((storage_class & STC_TYPECTOR) && !(ad || isNested())) -+ storage_class &= ~STC_TYPECTOR; - - //printf("function storage_class = x%llx, sc->stc = x%llx, %x\n", storage_class, sc->stc, Declaration::isFinal()); - -@@ -186,12 +187,34 @@ void FuncDeclaration::semantic(Scope *sc - userAttributes = sc->userAttributes; - - if (!originalType) -- originalType = type; -+ originalType = type->syntaxCopy(); - if (!type->deco) - { - sc = sc->push(); - sc->stc |= storage_class & STCdisable; // forward to function type - TypeFunction *tf = (TypeFunction *)type; -+#if 1 -+ /* If the parent is @safe, then this function defaults to safe -+ * too. -+ * If the parent's @safe-ty is inferred, then this function's @safe-ty needs -+ * to be inferred first. -+ */ -+ if (tf->trust == TRUSTdefault && -+ !(//isFuncLiteralDeclaration() || -+ parent->isTemplateInstance() || -+ ad && ad->parent && ad->parent->isTemplateInstance())) -+ { -+ for (Dsymbol *p = sc->func; p; p = p->toParent2()) -+ { FuncDeclaration *fd = p->isFuncDeclaration(); -+ if (fd) -+ { -+ if (fd->isSafeBypassingInference()) -+ tf->trust = TRUSTsafe; // default to @safe -+ break; -+ } -+ } -+ } -+#endif - if (tf->isref) sc->stc |= STCref; - if (tf->isnothrow) sc->stc |= STCnothrow; - if (tf->isproperty) sc->stc |= STCproperty; -@@ -201,10 +224,37 @@ void FuncDeclaration::semantic(Scope *sc - if (tf->trust == TRUSTtrusted) sc->stc |= STCtrusted; - - if (isCtorDeclaration()) -+ { - sc->flags |= SCOPEctor; - -+ Type *tret; -+ if (!ad || parent->isUnionDeclaration()) -+ { -+ error("constructors are only for class or struct definitions"); -+ tret = Type::tvoid; -+ } -+ else -+ { tret = ad->handle; -+ assert(tret); -+ tret = tret->addStorageClass(storage_class | sc->stc); -+ tret = tret->addMod(type->mod); -+ } -+ tf->next = tret; -+ -+ if (ad && ad->isStructDeclaration()) -+ sc->stc |= STCref; -+ } -+ - sc->linkage = linkage; - -+ if (!tf->isNaked() && !(isThis() || isNested())) -+ { -+ OutBuffer buf; -+ MODtoBuffer(&buf, tf->mod); -+ error("without 'this' cannot be %s", buf.toChars()); -+ tf->mod = 0; // remove qualifiers -+ } -+ - /* Apply const, immutable, wild and shared storage class - * to the function type. Do this before type semantic. - */ -@@ -270,38 +320,33 @@ void FuncDeclaration::semantic(Scope *sc - error("%s must be a function instead of %s", toChars(), type->toChars()); - return; - } -- f = (TypeFunction *)(type); -+ f = (TypeFunction *)type; - size_t nparams = Parameter::dim(f->parameters); - -- /* Purity and safety can be inferred for some functions by examining -- * the function body. -- */ -- if (fbody && -- (isFuncLiteralDeclaration() || parent->isTemplateInstance())) -- { -- if (f->purity == PUREimpure) // purity not specified -- flags |= FUNCFLAGpurityInprocess; -- -- if (f->trust == TRUSTdefault) -- flags |= FUNCFLAGsafetyInprocess; -- -- if (!f->isnothrow) -- flags |= FUNCFLAGnothrowInprocess; -- } -- - if (storage_class & STCscope) - error("functions cannot be scope"); - - if (isAbstract() && !isVirtual()) -- error("non-virtual functions cannot be abstract"); -+ { -+ const char *sfunc; -+ if (isStatic()) -+ sfunc = "static"; -+ else if (protection == PROTprivate || protection == PROTpackage) -+ sfunc = Pprotectionnames[protection]; -+ else -+ sfunc = "non-virtual"; -+ error("%s functions cannot be abstract", sfunc); -+ } - - if (isOverride() && !isVirtual()) -- error("cannot override a non-virtual function"); -- -- if ((f->isConst() || f->isImmutable()) && !isThis()) -- error("without 'this' cannot be const/immutable"); -+ { -+ if ((prot() == PROTprivate || prot() == PROTpackage) && isMember()) -+ error("%s method is not virtual and cannot override", Pprotectionnames[prot()]); -+ else -+ error("cannot override a non-virtual function"); -+ } - -- if (isAbstract() && isFinal()) -+ if (isAbstract() && isFinalFunc()) - error("cannot be both final and abstract"); - #if 0 - if (isAbstract() && fbody) -@@ -337,8 +382,8 @@ void FuncDeclaration::semantic(Scope *sc - error("special member functions not allowed for %ss", sd->kind()); - } - -- if (!sd->inv) -- sd->inv = isInvariantDeclaration(); -+ if (isInvariantDeclaration()) -+ sd->invs.push(this); - - if (!sd->aggNew) - sd->aggNew = isNewDeclaration(); -@@ -376,11 +421,8 @@ void FuncDeclaration::semantic(Scope *sc - - cd = parent->isClassDeclaration(); - if (cd) -- { size_t vi; -- CtorDeclaration *ctor; -- DtorDeclaration *dtor; -- InvariantDeclaration *inv; -- -+ { -+ size_t vi; - if (isCtorDeclaration()) - { - // ctor = (CtorDeclaration *)this; -@@ -389,35 +431,6 @@ void FuncDeclaration::semantic(Scope *sc - goto Ldone; - } - --#if 0 -- dtor = isDtorDeclaration(); -- if (dtor) -- { -- if (cd->dtor) -- error("multiple destructors for class %s", cd->toChars()); -- cd->dtor = dtor; -- } -- -- inv = isInvariantDeclaration(); -- if (inv) -- { -- cd->inv = inv; -- } -- -- if (isNewDeclaration()) -- { -- if (!cd->aggNew) -- cd->aggNew = (NewDeclaration *)(this); -- } -- -- if (isDelete()) -- { -- if (cd->aggDelete) -- error("multiple delete's for class %s", cd->toChars()); -- cd->aggDelete = (DeleteDeclaration *)(this); -- } --#endif -- - if (storage_class & STCabstract) - cd->isabstract = 1; - -@@ -431,6 +444,34 @@ void FuncDeclaration::semantic(Scope *sc - if (type->nextOf() == Type::terror) - goto Ldone; - -+ bool may_override = false; -+ for (size_t i = 0; i < cd->baseclasses->dim; i++) -+ { -+ BaseClass *b = (*cd->baseclasses)[i]; -+ ClassDeclaration *cbd = b->type->toBasetype()->isClassHandle(); -+ if (!cbd) -+ continue; -+ for (size_t j = 0; j < cbd->vtbl.dim; j++) -+ { -+ FuncDeclaration *f = cbd->vtbl[j]->isFuncDeclaration(); -+ if (!f || f->ident != ident) -+ continue; -+ if (cbd->parent && cbd->parent->isTemplateInstance()) -+ { -+ if (!f->functionSemantic()) -+ goto Ldone; -+ } -+ may_override = true; -+ } -+ } -+ if (may_override && type->nextOf() == NULL) -+ { -+ /* If same name function exists in base class but 'this' is auto return, -+ * cannot find index of base class's vtbl[] to override. -+ */ -+ error("return type inference is not supported if may override base class function"); -+ } -+ - /* Find index of existing function in base class's vtbl[] to override - * (the index will be the same as in cd's current vtbl[]) - */ -@@ -440,7 +481,7 @@ void FuncDeclaration::semantic(Scope *sc - doesoverride = FALSE; - switch (vi) - { -- case -1: -+ case (size_t)-1: - Lintro: - /* Didn't find one, so - * This is an 'introducing' function which gets a new -@@ -453,13 +494,16 @@ void FuncDeclaration::semantic(Scope *sc - if (s) - { - FuncDeclaration *f = s->isFuncDeclaration(); -- f = f->overloadExactMatch(type); -- if (f && f->isFinal() && f->prot() != PROTprivate) -- error("cannot override final function %s", f->toPrettyChars()); -+ if (f) -+ { -+ f = f->overloadExactMatch(type); -+ if (f && f->isFinalFunc() && f->prot() != PROTprivate) -+ error("cannot override final function %s", f->toPrettyChars()); -+ } - } - } - -- if (isFinal()) -+ if (isFinalFunc()) - { - // Don't check here, as it may override an interface function - //if (isOverride()) -@@ -477,7 +521,7 @@ void FuncDeclaration::semantic(Scope *sc - } - break; - -- case -2: // can't determine because of fwd refs -+ case (size_t)-2: // can't determine because of fwd refs - cd->sizeok = SIZEOKfwd; // can't finish due to forward reference - Module::dprogress = dprogress_save; - return; -@@ -487,6 +531,12 @@ void FuncDeclaration::semantic(Scope *sc - FuncDeclaration *fdc = cd->vtbl[vi]->isFuncDeclaration(); - // This function is covariant with fdv - -+ if (fdc == this) -+ { -+ doesoverride = TRUE; -+ break; -+ } -+ - if (fdc->toParent() == parent) - { - //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc = %p %s %s @ [%s]\n\tfdv = %p %s %s @ [%s]\n", -@@ -500,7 +550,7 @@ void FuncDeclaration::semantic(Scope *sc - } - - // This function overrides fdv -- if (fdv->isFinal()) -+ if (fdv->isFinalFunc()) - error("cannot override final function %s", fdv->toPrettyChars()); - - doesoverride = TRUE; -@@ -566,10 +616,10 @@ void FuncDeclaration::semantic(Scope *sc - vi = findVtblIndex((Dsymbols *)&b->base->vtbl, b->base->vtbl.dim); - switch (vi) - { -- case -1: -+ case (size_t)-1: - break; - -- case -2: -+ case (size_t)-2: - cd->sizeok = SIZEOKfwd; // can't finish due to forward reference - Module::dprogress = dprogress_save; - return; -@@ -633,7 +683,7 @@ void FuncDeclaration::semantic(Scope *sc - } - } - -- if (!doesoverride && isOverride()) -+ if (!doesoverride && isOverride() && type->nextOf()) - { - Dsymbol *s = NULL; - for (size_t i = 0; i < cd->baseclasses->dim; i++) -@@ -665,7 +715,7 @@ void FuncDeclaration::semantic(Scope *sc - if (f) - { - f = f->overloadExactMatch(type); -- if (f && f->isFinal() && f->prot() != PROTprivate) -+ if (f && f->isFinalFunc() && f->prot() != PROTprivate) - error("cannot override final function %s.%s", b->base->toChars(), f->toPrettyChars()); - } - } -@@ -675,6 +725,10 @@ void FuncDeclaration::semantic(Scope *sc - else if (isOverride() && !parent->isTemplateInstance()) - error("override only applies to class member functions"); - -+ // Reflect this->type to f because it could be changed by findVtblIndex -+ assert(type->ty == Tfunction); -+ f = (TypeFunction *)type; -+ - /* Do not allow template instances to add virtual functions - * to a class. - */ -@@ -742,13 +796,17 @@ void FuncDeclaration::semantic(Scope *sc - * can call them. - */ - if (frequire) -- { /* in { ... } -+ { -+ /* in { ... } - * becomes: - * void __require() { ... } - * __require(); - */ - Loc loc = frequire->loc; - TypeFunction *tf = new TypeFunction(NULL, Type::tvoid, 0, LINKd); -+ tf->isnothrow = f->isnothrow; -+ tf->purity = f->purity; -+ tf->trust = f->trust; - FuncDeclaration *fd = new FuncDeclaration(loc, loc, - Id::require, STCundefined, tf); - fd->fbody = frequire; -@@ -763,9 +821,10 @@ void FuncDeclaration::semantic(Scope *sc - outId = Id::result; // provide a default - - if (fensure) -- { /* out (result) { ... } -+ { -+ /* out (result) { ... } - * becomes: -- * tret __ensure(ref tret result) { ... } -+ * void __ensure(ref tret result) { ... } - * __ensure(result); - */ - Loc loc = fensure->loc; -@@ -776,6 +835,9 @@ void FuncDeclaration::semantic(Scope *sc - arguments->push(a); - } - TypeFunction *tf = new TypeFunction(arguments, Type::tvoid, 0, LINKd); -+ tf->isnothrow = f->isnothrow; -+ tf->purity = f->purity; -+ tf->trust = f->trust; - FuncDeclaration *fd = new FuncDeclaration(loc, loc, - Id::ensure, STCundefined, tf); - fd->fbody = fensure; -@@ -791,6 +853,26 @@ void FuncDeclaration::semantic(Scope *sc - } - - Ldone: -+ /* Purity and safety can be inferred for some functions by examining -+ * the function body. -+ */ -+ if (fbody && -+ (isFuncLiteralDeclaration() || -+ parent->isTemplateInstance() || -+ ad && ad->parent && ad->parent->isTemplateInstance() && !isVirtualMethod())) -+ { -+ /* isVirtualMethod() needs setting correct foverrides -+ */ -+ if (f->purity == PUREimpure) // purity not specified -+ flags |= FUNCFLAGpurityInprocess; -+ -+ if (f->trust == TRUSTdefault) -+ flags |= FUNCFLAGsafetyInprocess; -+ -+ if (!f->isnothrow) -+ flags |= FUNCFLAGnothrowInprocess; -+ } -+ - Module::dprogress++; - semanticRun = PASSsemanticdone; - -@@ -799,6 +881,24 @@ Ldone: - */ - scope = new Scope(*sc); - scope->setNoFree(); -+ -+ static bool printedMain = false; // semantic might run more than once -+ if (global.params.verbose && !printedMain) -+ { -+ const char *type = isMain() ? "main" : isWinMain() ? "winmain" : isDllMain() ? "dllmain" : (const char *)NULL; -+ Module *mod = sc->module; -+ -+ if (type && mod) -+ { -+ printedMain = true; -+ const char *name = FileName::searchPath(global.path, mod->srcfile->toChars(), 1); -+ fprintf(global.stdmsg, "entry %-10s\t%s\n", type, name); -+ } -+ } -+ -+ if (fbody && isMain() && sc->module->isRoot()) -+ genCmain(sc); -+ - return; - } - -@@ -835,7 +935,7 @@ void FuncDeclaration::semantic3(Scope *s - - if (!type || type->ty != Tfunction) - return; -- f = (TypeFunction *)(type); -+ f = (TypeFunction *)type; - if (!inferRetType && f->next->ty == Terror) - return; - -@@ -875,7 +975,7 @@ void FuncDeclaration::semantic3(Scope *s - } - - frequire = mergeFrequire(frequire); -- fensure = mergeFensure(fensure); -+ fensure = mergeFensure(fensure, outId); - - if (fbody || frequire || fensure) - { -@@ -903,11 +1003,15 @@ void FuncDeclaration::semantic3(Scope *s - sc2->protection = PROTpublic; - sc2->explicitProtection = 0; - sc2->structalign = STRUCTALIGN_DEFAULT; -- sc2->flags = sc->flags & ~SCOPEcontract; -+ if (this->ident != Id::require && this->ident != Id::ensure) -+ sc2->flags = sc->flags & ~SCOPEcontract; - sc2->tf = NULL; - sc2->noctor = 0; - sc2->speculative = sc->speculative || isSpeculative() != NULL; - sc2->userAttributes = NULL; -+ if (sc2->intypeof == 1) sc2->intypeof = 2; -+ sc2->fieldinit = NULL; -+ sc2->fieldinit_dim = 0; - - // Declare 'this' - AggregateDeclaration *ad = isThis(); -@@ -950,15 +1054,15 @@ void FuncDeclaration::semantic3(Scope *s - - if (f->linkage == LINKd) - { // Declare _arguments[] -- v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); -+ v_arguments = new VarDeclaration(Loc(), Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); - v_arguments->storage_class = STCparameter; - v_arguments->semantic(sc2); - sc2->insert(v_arguments); - v_arguments->parent = this; - - //t = Type::typeinfo->type->constOf()->arrayOf(); -- t = Type::typeinfo->type->arrayOf(); -- _arguments = new VarDeclaration(0, t, Id::_arguments, NULL); -+ t = Type::dtypeinfo->type->arrayOf(); -+ _arguments = new VarDeclaration(Loc(), t, Id::_arguments, NULL); - _arguments->semantic(sc2); - sc2->insert(_arguments); - _arguments->parent = this; -@@ -966,7 +1070,7 @@ void FuncDeclaration::semantic3(Scope *s - if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters))) - { // Declare _argptr - t = Type::tvalist; -- argptr = new VarDeclaration(0, t, Id::_argptr, NULL); -+ argptr = new VarDeclaration(Loc(), t, Id::_argptr, NULL); - argptr->semantic(sc2); - sc2->insert(argptr); - argptr->parent = this; -@@ -1015,8 +1119,6 @@ void FuncDeclaration::semantic3(Scope *s - arg->ident = id = Identifier::generateId("_param_", i); - } - Type *vtype = arg->type; -- //if (isPure()) -- //vtype = vtype->addMod(MODconst); - VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL); - //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); - v->storage_class |= STCparameter; -@@ -1050,7 +1152,7 @@ void FuncDeclaration::semantic3(Scope *s - for (size_t j = 0; j < dim; j++) - { Parameter *narg = Parameter::getNth(t->arguments, j); - assert(narg->ident); -- VarDeclaration *v = sc2->search(0, narg->ident, NULL)->isVarDeclaration(); -+ VarDeclaration *v = sc2->search(Loc(), narg->ident, NULL)->isVarDeclaration(); - assert(v); - Expression *e = new VarExp(v->loc, v); - (*exps)[j] = e; -@@ -1058,7 +1160,7 @@ void FuncDeclaration::semantic3(Scope *s - assert(arg->ident); - TupleDeclaration *v = new TupleDeclaration(loc, arg->ident, exps); - //printf("declaring tuple %s\n", v->toChars()); -- v->isexp = 1; -+ v->isexp = true; - if (!sc2->insert(v)) - error("parameter %s.%s is already defined", toChars(), v->toChars()); - localsymtab->insert(v); -@@ -1075,7 +1177,7 @@ void FuncDeclaration::semantic3(Scope *s - if (isDtorDeclaration()) - { - // Call invariant directly only if it exists -- InvariantDeclaration *inv = ad->inv; -+ FuncDeclaration *inv = ad->inv; - ClassDeclaration *cd = ad->isClassDeclaration(); - - while (!inv && cd) -@@ -1087,24 +1189,24 @@ void FuncDeclaration::semantic3(Scope *s - } - if (inv) - { -- e = new DsymbolExp(0, inv); -- e = new CallExp(0, e); -+ e = new DsymbolExp(Loc(), inv); -+ e = new CallExp(Loc(), e); - e = e->semantic(sc2); - } - } - else - { // Call invariant virtually -- Expression *v = new ThisExp(0); -+ Expression *v = new ThisExp(Loc()); - v->type = vthis->type; - if (ad->isStructDeclaration()) - v = v->addressOf(sc); -- Expression *se = new StringExp(0, (char *)"null this"); -+ Expression *se = new StringExp(Loc(), (char *)"null this"); - se = se->semantic(sc); - se->type = Type::tchar->arrayOf(); - e = new AssertExp(loc, v, se); - } - if (e) -- fpreinv = new ExpStatement(0, e); -+ fpreinv = new ExpStatement(Loc(), e); - } - - // Postcondition invariant -@@ -1115,7 +1217,7 @@ void FuncDeclaration::semantic3(Scope *s - if (isCtorDeclaration()) - { - // Call invariant directly only if it exists -- InvariantDeclaration *inv = ad->inv; -+ FuncDeclaration *inv = ad->inv; - ClassDeclaration *cd = ad->isClassDeclaration(); - - while (!inv && cd) -@@ -1127,21 +1229,21 @@ void FuncDeclaration::semantic3(Scope *s - } - if (inv) - { -- e = new DsymbolExp(0, inv); -- e = new CallExp(0, e); -+ e = new DsymbolExp(Loc(), inv); -+ e = new CallExp(Loc(), e); - e = e->semantic(sc2); - } - } - else - { // Call invariant virtually -- Expression *v = new ThisExp(0); -+ Expression *v = new ThisExp(Loc()); - v->type = vthis->type; - if (ad->isStructDeclaration()) - v = v->addressOf(sc); -- e = new AssertExp(0, v); -+ e = new AssertExp(Loc(), v); - } - if (e) -- fpostinv = new ExpStatement(0, e); -+ fpostinv = new ExpStatement(Loc(), e); - } - - if (fensure || addPostInvariant()) -@@ -1168,10 +1270,13 @@ void FuncDeclaration::semantic3(Scope *s - */ - if (ad && isCtorDeclaration()) - { -+ sc2->fieldinit = new unsigned[ad->fields.dim]; -+ sc2->fieldinit_dim = ad->fields.dim; - for (size_t i = 0; i < ad->fields.dim; i++) -- { VarDeclaration *v = ad->fields[i]; -- -+ { -+ VarDeclaration *v = ad->fields[i]; - v->ctorinit = 0; -+ sc2->fieldinit[i] = 0; - } - } - -@@ -1180,29 +1285,34 @@ void FuncDeclaration::semantic3(Scope *s - - fbody = fbody->semantic(sc2); - if (!fbody) -- fbody = new CompoundStatement(0, new Statements()); -+ fbody = new CompoundStatement(Loc(), new Statements()); - - if (inferRetType) -- { // If no return type inferred yet, then infer a void -+ { -+ // If no return type inferred yet, then infer a void - if (!type->nextOf()) - { - f->next = Type::tvoid; - //type = type->semantic(loc, sc); // Removed with 6902 - } -- else if (returns && f->next->ty != Tvoid) -+ } -+ if (returns && f->next->ty != Tvoid) -+ { -+ for (size_t i = 0; i < returns->dim; i++) - { -- for (size_t i = 0; i < returns->dim; i++) -- { Expression *exp = (*returns)[i]->exp; -- if (!f->next->invariantOf()->equals(exp->type->invariantOf())) -- { exp = exp->castTo(sc2, f->next); -- exp = exp->optimize(WANTvalue); -- (*returns)[i]->exp = exp; -- } -- //printf("[%d] %s %s\n", i, exp->type->toChars(), exp->toChars()); -+ Expression *exp = (*returns)[i]->exp; -+ if (!nrvo_can && !f->isref && exp->isLvalue()) -+ exp = callCpCtor(sc2, exp); -+ if (!tintro && !f->next->immutableOf()->equals(exp->type->immutableOf())) -+ { -+ exp = exp->castTo(sc2, f->next); -+ exp = exp->optimize(WANTvalue); - } -+ //printf("[%d] %s %s\n", i, exp->type->toChars(), exp->toChars()); -+ (*returns)[i]->exp = exp; - } -- assert(type == f); - } -+ assert(type == f); - - if (isStaticCtorDeclaration()) - { /* It's a static constructor. Ensure that all -@@ -1225,14 +1335,16 @@ void FuncDeclaration::semantic3(Scope *s - } - } - -- if (isCtorDeclaration() && ad) -+ if (fbody->isErrorStatement()) -+ ; -+ else if (isCtorDeclaration() && ad) - { - #if DMDV2 - // Check for errors related to 'nothrow'. - int nothrowErrors = global.errors; - int blockexit = fbody->blockExit(f->isnothrow); - if (f->isnothrow && (global.errors != nothrowErrors) ) -- error("'%s' is nothrow yet may throw", toChars()); -+ ::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars()); - if (flags & FUNCFLAGnothrowInprocess) - f->isnothrow = !(blockexit & BEthrow); - #endif -@@ -1261,8 +1373,20 @@ void FuncDeclaration::semantic3(Scope *s - else if (v->type->needsNested()) - error("field %s must be initialized in constructor, because it is nested struct", v->toChars()); - } -+ else -+ { -+ bool mustInit = (v->storage_class & STCnodefaultctor || -+ v->type->needsNested()); -+ if (mustInit && !(sc2->fieldinit[i] & CSXthis_ctor)) -+ { -+ error("field %s must be initialized but skipped", v->toChars()); -+ } -+ } - } - } -+ delete[] sc2->fieldinit; -+ sc2->fieldinit = NULL; -+ sc2->fieldinit_dim = 0; - - if (cd && - !(sc2->callSuper & CSXany_ctor) && -@@ -1271,19 +1395,18 @@ void FuncDeclaration::semantic3(Scope *s - sc2->callSuper = 0; - - // Insert implicit super() at start of fbody -- Expression *e1 = new SuperExp(0); -- Expression *e = new CallExp(0, e1); -- -- e = e->trySemantic(sc2); -- if (!e) -+ if (!resolveFuncCall(Loc(), sc2, cd->baseClass->ctor, NULL, NULL, NULL, 1)) - { -- const char* impGen = ((CtorDeclaration*)this)->isImplicit ? "implicitly generated " : ""; -- error("no match for implicit super() call in %sconstructor", impGen); -+ error("no match for implicit super() call in constructor"); - } - else - { -- Statement *s = new ExpStatement(0, e); -- fbody = new CompoundStatement(0, s, fbody); -+ Expression *e1 = new SuperExp(Loc()); -+ Expression *e = new CallExp(Loc(), e1); -+ e = e->semantic(sc2); -+ -+ Statement *s = new ExpStatement(Loc(), e); -+ fbody = new CompoundStatement(Loc(), s, fbody); - } - } - -@@ -1304,8 +1427,8 @@ void FuncDeclaration::semantic3(Scope *s - else if (fes) - { // For foreach(){} body, append a return 0; - Expression *e = new IntegerExp(0); -- Statement *s = new ReturnStatement(0, e); -- fbody = new CompoundStatement(0, fbody, s); -+ Statement *s = new ReturnStatement(Loc(), e); -+ fbody = new CompoundStatement(Loc(), fbody, s); - assert(!returnLabel); - } - else if (!hasReturnExp && type->nextOf()->ty != Tvoid) -@@ -1321,10 +1444,10 @@ void FuncDeclaration::semantic3(Scope *s - int nothrowErrors = global.errors; - int blockexit = fbody->blockExit(f->isnothrow); - if (f->isnothrow && (global.errors != nothrowErrors) ) -- error("'%s' is nothrow yet may throw", toChars()); -+ ::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars()); - if (flags & FUNCFLAGnothrowInprocess) - { -- if (type == f) f = f->copy(); -+ if (type == f) f = (TypeFunction *)f->copy(); - f->isnothrow = !(blockexit & BEthrow); - } - -@@ -1352,10 +1475,10 @@ void FuncDeclaration::semantic3(Scope *s - } - else - e = new HaltExp(endloc); -- e = new CommaExp(0, e, type->nextOf()->defaultInit()); -+ e = new CommaExp(Loc(), e, type->nextOf()->defaultInit()); - e = e->semantic(sc2); -- Statement *s = new ExpStatement(0, e); -- fbody = new CompoundStatement(0, fbody, s); -+ Statement *s = new ExpStatement(Loc(), e); -+ fbody = new CompoundStatement(Loc(), fbody, s); - } - } - } -@@ -1405,6 +1528,12 @@ void FuncDeclaration::semantic3(Scope *s - - // BUG: need to treat parameters as const - // BUG: need to disallow returns and throws -+ if (inferRetType && fdensure && ((TypeFunction *)fdensure->type)->parameters) -+ { -+ // Return type was unknown in the first semantic pass -+ Parameter *p = (*((TypeFunction *)fdensure->type)->parameters)[0]; -+ p->type = ((TypeFunction *)type)->nextOf(); -+ } - fens = fens->semantic(sc2); - - sc2 = sc2->pop(); -@@ -1428,7 +1557,7 @@ void FuncDeclaration::semantic3(Scope *s - assert(ie); - if (ie->exp->op == TOKconstruct) - ie->exp->op = TOKassign; // construction occured in parameter processing -- a->push(new ExpStatement(0, ie->exp)); -+ a->push(new ExpStatement(Loc(), ie->exp)); - } - } - } -@@ -1443,12 +1572,12 @@ void FuncDeclaration::semantic3(Scope *s - Type *t = argptr->type; - if (global.params.is64bit && !global.params.isWindows) - { // Initialize _argptr to point to v_argsave -- Expression *e1 = new VarExp(0, argptr); -- Expression *e = new SymOffExp(0, v_argsave, 6*8 + 8*16); -+ Expression *e1 = new VarExp(Loc(), argptr); -+ Expression *e = new SymOffExp(Loc(), v_argsave, 6*8 + 8*16); - e->type = argptr->type; -- e = new AssignExp(0, e1, e); -+ e = new AssignExp(Loc(), e1, e); - e = e->semantic(sc); -- a->push(new ExpStatement(0, e)); -+ a->push(new ExpStatement(Loc(), e)); - } - else - { // Initialize _argptr to point past non-variadic arg -@@ -1456,7 +1585,7 @@ void FuncDeclaration::semantic3(Scope *s - unsigned offset = 0; - Expression *e; - -- Expression *e1 = new VarExp(0, argptr); -+ Expression *e1 = new VarExp(Loc(), argptr); - // Find the last non-ref parameter - if (parameters && parameters->dim) - { -@@ -1481,16 +1610,16 @@ void FuncDeclaration::semantic3(Scope *s - p = v_arguments; // last parameter is _arguments[] - if (global.params.is64bit && global.params.isWindows) - { offset += Target::ptrsize; -- if (p->storage_class & STClazy) -+ if (p->storage_class & STClazy || p->type->size() > Target::ptrsize) - { - /* Necessary to offset the extra level of indirection the Win64 - * ABI demands - */ -- e = new SymOffExp(0,p,0); -+ e = new SymOffExp(Loc(),p,0); - e->type = Type::tvoidptr; -- e = new AddrExp(0, e); -+ e = new AddrExp(Loc(), e); - e->type = Type::tvoidptr; -- e = new AddExp(0, e, new IntegerExp(offset)); -+ e = new AddExp(Loc(), e, new IntegerExp(offset)); - e->type = Type::tvoidptr; - goto L1; - } -@@ -1501,13 +1630,13 @@ void FuncDeclaration::semantic3(Scope *s - else - offset += p->type->size(); - offset = (offset + Target::ptrsize - 1) & ~(Target::ptrsize - 1); // assume stack aligns on pointer size -- e = new SymOffExp(0, p, offset); -+ e = new SymOffExp(Loc(), p, offset); - e->type = Type::tvoidptr; - //e = e->semantic(sc); - L1: -- e = new AssignExp(0, e1, e); -+ e = new AssignExp(Loc(), e1, e); - e->type = t; -- a->push(new ExpStatement(0, e)); -+ a->push(new ExpStatement(Loc(), e)); - p->isargptr = TRUE; - } - #endif -@@ -1522,12 +1651,12 @@ void FuncDeclaration::semantic3(Scope *s - /* Advance to elements[] member of TypeInfo_Tuple with: - * _arguments = v_arguments.elements; - */ -- Expression *e = new VarExp(0, v_arguments); -- e = new DotIdExp(0, e, Id::elements); -- Expression *e1 = new VarExp(0, _arguments); -- e = new ConstructExp(0, e1, e); -+ Expression *e = new VarExp(Loc(), v_arguments); -+ e = new DotIdExp(Loc(), e, Id::elements); -+ Expression *e1 = new VarExp(Loc(), _arguments); -+ e = new ConstructExp(Loc(), e1, e); - e = e->semantic(sc2); -- a->push(new ExpStatement(0, e)); -+ a->push(new ExpStatement(Loc(), e)); - } - - // Merge contracts together with body into one compound statement -@@ -1537,7 +1666,7 @@ void FuncDeclaration::semantic3(Scope *s - if (!freq) - freq = fpreinv; - else if (fpreinv) -- freq = new CompoundStatement(0, freq, fpreinv); -+ freq = new CompoundStatement(Loc(), freq, fpreinv); - - a->push(freq); - } -@@ -1550,31 +1679,31 @@ void FuncDeclaration::semantic3(Scope *s - if (!fens) - fens = fpostinv; - else if (fpostinv) -- fens = new CompoundStatement(0, fpostinv, fens); -+ fens = new CompoundStatement(Loc(), fpostinv, fens); - -- LabelStatement *ls = new LabelStatement(0, Id::returnLabel, fens); -+ LabelStatement *ls = new LabelStatement(Loc(), Id::returnLabel, fens); - returnLabel->statement = ls; - a->push(returnLabel->statement); - - if (type->nextOf()->ty != Tvoid && vresult) - { - // Create: return vresult; -- Expression *e = new VarExp(0, vresult); -+ Expression *e = new VarExp(Loc(), vresult); - if (tintro) - { e = e->implicitCastTo(sc, tintro->nextOf()); - e = e->semantic(sc); - } -- ReturnStatement *s = new ReturnStatement(0, e); -+ ReturnStatement *s = new ReturnStatement(Loc(), e); - a->push(s); - } - } - if (isMain() && type->nextOf()->ty == Tvoid) - { // Add a return 0; statement -- Statement *s = new ReturnStatement(0, new IntegerExp(0)); -+ Statement *s = new ReturnStatement(Loc(), new IntegerExp(0)); - a->push(s); - } - -- fbody = new CompoundStatement(0, a); -+ fbody = new CompoundStatement(Loc(), a); - #if DMDV2 - /* Append destructor calls for parameters as finally blocks. - */ -@@ -1591,19 +1720,19 @@ void FuncDeclaration::semantic3(Scope *s - - Expression *e = v->edtor; - if (e) -- { Statement *s = new ExpStatement(0, e); -+ { Statement *s = new ExpStatement(Loc(), e); - s = s->semantic(sc2); - int nothrowErrors = global.errors; - bool isnothrow = f->isnothrow & !(flags & FUNCFLAGnothrowInprocess); - int blockexit = s->blockExit(isnothrow); - if (f->isnothrow && (global.errors != nothrowErrors) ) -- error("'%s' is nothrow yet may throw", toChars()); -+ ::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars()); - if (flags & FUNCFLAGnothrowInprocess && blockexit & BEthrow) - f->isnothrow = FALSE; - if (fbody->blockExit(f->isnothrow) == BEfallthru) -- fbody = new CompoundStatement(0, fbody, s); -+ fbody = new CompoundStatement(Loc(), fbody, s); - else -- fbody = new TryFinallyStatement(0, fbody, s); -+ fbody = new TryFinallyStatement(Loc(), fbody, s); - } - } - } -@@ -1621,7 +1750,7 @@ void FuncDeclaration::semantic3(Scope *s - { - if (!global.params.is64bit && - global.params.isWindows && -- !isStatic() && !fbody->usesEH()) -+ !isStatic() && !fbody->usesEH() && !global.params.trace) - { - /* The back end uses the "jmonitor" hack for syncing; - * no need to do the sync at this level. -@@ -1659,14 +1788,14 @@ void FuncDeclaration::semantic3(Scope *s - if (flags & FUNCFLAGpurityInprocess) - { - flags &= ~FUNCFLAGpurityInprocess; -- if (type == f) f = f->copy(); -+ if (type == f) f = (TypeFunction *)f->copy(); - f->purity = PUREfwdref; - } - - if (flags & FUNCFLAGsafetyInprocess) - { - flags &= ~FUNCFLAGsafetyInprocess; -- if (type == f) f = f->copy(); -+ if (type == f) f = (TypeFunction *)f->copy(); - f->trust = TRUSTsafe; - } - -@@ -1678,6 +1807,7 @@ void FuncDeclaration::semantic3(Scope *s - if (!f->deco) - { - sc = sc->push(); -+ sc->stc = 0; - sc->linkage = linkage; // Bugzilla 8496 - type = f->semantic(loc, sc); - sc = sc->pop(); -@@ -1705,7 +1835,10 @@ void FuncDeclaration::semantic3(Scope *s - - bool FuncDeclaration::functionSemantic() - { -- if (scope && !originalType) // semantic not yet run -+ if (!scope) -+ return true; -+ -+ if (!originalType) // semantic not yet run - { - TemplateInstance *spec = isSpeculative(); - unsigned olderrs = global.errors; -@@ -1721,10 +1854,26 @@ bool FuncDeclaration::functionSemantic() - } - - // if inferring return type, sematic3 needs to be run -- if (scope && (inferRetType && type && !type->nextOf() || -- getFuncTemplateDecl(this))) -- { -+ if (inferRetType && type && !type->nextOf()) - return functionSemantic3(); -+ -+ TemplateInstance *ti = parent->isTemplateInstance(); -+ if (ti && !ti->isTemplateMixin() && ti->name == ident) -+ return functionSemantic3(); -+ -+ AggregateDeclaration *ad = isThis(); -+ if (ad && ad->parent && ad->parent->isTemplateInstance() && !isVirtualMethod()) -+ { -+ if (ad->sizeok != SIZEOKdone) -+ { -+ /* Currently dmd cannot resolve forward references per methods, -+ * then setting SIZOKfwd is too conservative and would break existing code. -+ * So, just stop method attributes inference until ad->semantic() done. -+ */ -+ //ad->sizeok = SIZEOKfwd; -+ } -+ else -+ return functionSemantic3(); - } - - return true; -@@ -1791,8 +1940,6 @@ VarDeclaration *FuncDeclaration::declare - Type *thandle = ad->handle; - thandle = thandle->addMod(type->mod); - thandle = thandle->addStorageClass(storage_class); -- //if (isPure()) -- //thandle = thandle->addMod(MODconst); - v = new ThisDeclaration(loc, thandle); - //v = new ThisDeclaration(loc, isCtorDeclaration() ? ad->handle : thandle); - v->storage_class |= STCparameter; -@@ -1823,24 +1970,38 @@ VarDeclaration *FuncDeclaration::declare - return NULL; - } - --int FuncDeclaration::equals(Object *o) -+bool FuncDeclaration::equals(RootObject *o) - { - if (this == o) -- return TRUE; -+ return true; - - Dsymbol *s = isDsymbol(o); - if (s) - { -- FuncDeclaration *fd1 = this->toAliasFunc(); -+ FuncDeclaration *fd1 = this; - FuncDeclaration *fd2 = s->isFuncDeclaration(); -- if (fd2) -- { -- fd2 = fd2->toAliasFunc(); -- return fd1->toParent()->equals(fd2->toParent()) && -- fd1->ident->equals(fd2->ident) && fd1->type->equals(fd2->type); -+ if (!fd2) -+ return false; -+ -+ FuncAliasDeclaration *fa1 = fd1->isFuncAliasDeclaration(); -+ FuncAliasDeclaration *fa2 = fd2->isFuncAliasDeclaration(); -+ if (fa1 && fa2) -+ { -+ return fa1->toAliasFunc()->equals(fa2->toAliasFunc()) && -+ fa1->hasOverloads == fa2->hasOverloads; - } -+ -+ if (fa1 && (fd1 = fa1->toAliasFunc())->isUnique() && !fa1->hasOverloads) -+ fa1 = NULL; -+ if (fa2 && (fd2 = fa2->toAliasFunc())->isUnique() && !fa2->hasOverloads) -+ fa2 = NULL; -+ if ((fa1 != NULL) != (fa2 != NULL)) -+ return false; -+ -+ return fd1->toParent()->equals(fd2->toParent()) && -+ fd1->ident->equals(fd2->ident) && fd1->type->equals(fd2->type); - } -- return FALSE; -+ return false; - } - - void FuncDeclaration::bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -1909,7 +2070,7 @@ void FuncDeclaration::buildResultVar() - - assert(type->nextOf()); - assert(type->nextOf()->toBasetype()->ty != Tvoid); -- TypeFunction *tf = (TypeFunction *)(type); -+ TypeFunction *tf = (TypeFunction *)type; - - Loc loc = this->loc; - -@@ -2024,7 +2185,7 @@ Statement *FuncDeclaration::mergeFrequir - * 'out's are AND'd together, i.e. all of them need to pass. - */ - --Statement *FuncDeclaration::mergeFensure(Statement *sf) -+Statement *FuncDeclaration::mergeFensure(Statement *sf, Identifier *oid) - { - /* Same comments as for mergeFrequire(), except that we take care - * of generating a consistent reference to the 'result' local by -@@ -2051,7 +2212,7 @@ Statement *FuncDeclaration::mergeFensure - sc->pop(); - } - -- sf = fdv->mergeFensure(sf); -+ sf = fdv->mergeFensure(sf, oid); - if (fdv->fdensure) - { - //printf("fdv->fensure: %s\n", fdv->fensure->toChars()); -@@ -2059,22 +2220,21 @@ Statement *FuncDeclaration::mergeFensure - Expression *eresult = NULL; - if (outId) - { -- eresult = new IdentifierExp(loc, outId); -+ eresult = new IdentifierExp(loc, oid); - - Type *t1 = fdv->type->nextOf()->toBasetype(); - Type *t2 = this->type->nextOf()->toBasetype(); -- int offset; -- if (t1->isBaseOf(t2, &offset) && offset != 0) -+ if (t1->isBaseOf(t2, NULL)) - { - /* Making temporary reference variable is necessary -- * to match offset difference in covariant return. -- * See bugzilla 5204. -+ * in covariant return. -+ * See bugzilla 5204 and 10479. - */ -- ExpInitializer *ei = new ExpInitializer(0, eresult); -- VarDeclaration *v = new VarDeclaration(0, t1, Lexer::uniqueId("__covres"), ei); -- DeclarationExp *de = new DeclarationExp(0, v); -- VarExp *ve = new VarExp(0, v); -- eresult = new CommaExp(0, de, ve); -+ ExpInitializer *ei = new ExpInitializer(Loc(), eresult); -+ VarDeclaration *v = new VarDeclaration(Loc(), t1, Lexer::uniqueId("__covres"), ei); -+ DeclarationExp *de = new DeclarationExp(Loc(), v); -+ VarExp *ve = new VarExp(Loc(), v); -+ eresult = new CommaExp(Loc(), de, ve); - } - } - Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure, 0), eresult); -@@ -2082,7 +2242,7 @@ Statement *FuncDeclaration::mergeFensure - - if (sf) - { -- sf = new CompoundStatement(fensure->loc, s2, sf); -+ sf = new CompoundStatement(sf->loc, s2, sf); - } - else - sf = s2; -@@ -2187,41 +2347,43 @@ int FuncDeclaration::findVtblIndex(Dsymb - type = type->addStorageClass(mismatchstc); - bestvi = mismatchvi; - } -- else -- error("of type %s overrides but is not covariant with %s of type %s", -- type->toChars(), mismatch->toPrettyChars(), mismatch->type->toChars()); - } - return bestvi; - } - - /**************************************************** - * Overload this FuncDeclaration with the new one f. -- * Return !=0 if successful; i.e. no conflict. -+ * Return true if successful; i.e. no conflict. - */ - --int FuncDeclaration::overloadInsert(Dsymbol *s) -+bool FuncDeclaration::overloadInsert(Dsymbol *s) - { -- FuncDeclaration *f; -- AliasDeclaration *a; -- - //printf("FuncDeclaration::overloadInsert(s = %s) this = %s\n", s->toChars(), toChars()); -- a = s->isAliasDeclaration(); -- if (a) -+ AliasDeclaration *ad = s->isAliasDeclaration(); -+ if (ad) - { - if (overnext) -- return overnext->overloadInsert(a); -- if (!a->aliassym && a->type->ty != Tident && a->type->ty != Tinstance) -+ return overnext->overloadInsert(ad); -+ if (!ad->aliassym && ad->type->ty != Tident && ad->type->ty != Tinstance) - { -- //printf("\ta = '%s'\n", a->type->toChars()); -- return FALSE; -+ //printf("\tad = '%s'\n", ad->type->toChars()); -+ return false; - } -- overnext = a; -+ overnext = ad; - //printf("\ttrue: no conflict\n"); -+ return true; -+ } -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (td) -+ { -+ if (overnext) -+ return overnext->overloadInsert(td); -+ overnext = td; - return TRUE; - } -- f = s->isFuncDeclaration(); -- if (!f) -- return FALSE; -+ FuncDeclaration *fd = s->isFuncDeclaration(); -+ if (!fd) -+ return false; - - #if 0 - /* Disable this check because: -@@ -2231,11 +2393,11 @@ int FuncDeclaration::overloadInsert(Dsym - */ - if (type) - { printf("type = %s\n", type->toChars()); -- printf("f->type = %s\n", f->type->toChars()); -+ printf("fd->type = %s\n", fd->type->toChars()); - } -- if (type && f->type && // can be NULL for overloaded constructors -- f->type->covariant(type) && -- f->type->mod == type->mod && -+ if (type && fd->type && // can be NULL for overloaded constructors -+ fd->type->covariant(type) && -+ fd->type->mod == type->mod && - !isFuncAliasDeclaration()) - { - //printf("\tfalse: conflict %s\n", kind()); -@@ -2244,80 +2406,78 @@ int FuncDeclaration::overloadInsert(Dsym - #endif - - if (overnext) -- return overnext->overloadInsert(f); -- overnext = f; -+ { -+ td = overnext->isTemplateDeclaration(); -+ if (td) -+ fd->overloadInsert(td); -+ else -+ return overnext->overloadInsert(fd); -+ } -+ overnext = fd; - //printf("\ttrue: no conflict\n"); -- return TRUE; -+ return true; - } - --/******************************************** -- * Find function in overload list that exactly matches t. -- */ -- - /*************************************************** -- * Visit each overloaded function in turn, and call -- * (*fp)(param, f) on it. -- * Exit when no more, or (*fp)(param, f) returns 1. -+ * Visit each overloaded function/template in turn, and call -+ * (*fp)(param, s) on it. -+ * Exit when no more, or (*fp)(param, f) returns nonzero. - * Returns: -- * 0 continue -- * 1 done -+ * ==0 continue -+ * !=0 done - */ - --int overloadApply(FuncDeclaration *fstart, -- int (*fp)(void *, FuncDeclaration *), -- void *param) -+int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *)) - { -- FuncDeclaration *f; -- Declaration *d; -- Declaration *next; -- -+ Dsymbol *d; -+ Dsymbol *next; - for (d = fstart; d; d = next) -- { FuncAliasDeclaration *fa = d->isFuncAliasDeclaration(); -- -- if (fa) -+ { -+ if (FuncAliasDeclaration *fa = d->isFuncAliasDeclaration()) - { - if (fa->hasOverloads) - { -- if (overloadApply(fa->funcalias, fp, param)) -- return 1; -+ if (int r = overloadApply(fa->funcalias, param, fp)) -+ return r; - } - else - { -- f = fa->toAliasFunc(); -- if (!f) -- { d->error("is aliased to a function"); -+ FuncDeclaration *fd = fa->toAliasFunc(); -+ if (!fd) -+ { -+ d->error("is aliased to a function"); - break; - } -- if ((*fp)(param, f)) -- return 1; -+ if (int r = (*fp)(param, fd)) -+ return r; - } - next = fa->overnext; - } -+ else if (AliasDeclaration *ad = d->isAliasDeclaration()) -+ { -+ next = ad->toAlias(); -+ if (next == ad) -+ break; -+ if (next == fstart) -+ break; -+ } -+ else if (TemplateDeclaration *td = d->isTemplateDeclaration()) -+ { -+ if (int r = (*fp)(param, td)) -+ return r; -+ next = td->overnext; -+ } - else - { -- AliasDeclaration *a = d->isAliasDeclaration(); -- -- if (a) -- { -- Dsymbol *s = a->toAlias(); -- next = s->isDeclaration(); -- if (next == a) -- break; -- if (next == fstart) -- break; -- } -- else -+ FuncDeclaration *fd = d->isFuncDeclaration(); -+ if (!fd) - { -- f = d->isFuncDeclaration(); -- if (!f) -- { d->error("is aliased to a function"); -- break; // BUG: should print error message? -- } -- if ((*fp)(param, f)) -- return 1; -- -- next = f->overnext; -+ d->error("is aliased to a function"); -+ break; // BUG: should print error message? - } -+ if (int r = (*fp)(param, fd)) -+ return r; -+ next = fd->overnext; - } - } - return 0; -@@ -2328,23 +2488,31 @@ int overloadApply(FuncDeclaration *fstar - * otherwise return NULL. - */ - --static int fpunique(void *param, FuncDeclaration *f) --{ FuncDeclaration **pf = (FuncDeclaration **)param; -- -- if (*pf) -- { *pf = NULL; -- return 1; // ambiguous, done -- } -- else -- { *pf = f; -- return 0; -- } --} -- - FuncDeclaration *FuncDeclaration::isUnique() --{ FuncDeclaration *result = NULL; -+{ -+ struct ParamUnique -+ { -+ static int fp(void *param, Dsymbol *s) -+ { -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ if (!f) -+ return 0; -+ FuncDeclaration **pf = (FuncDeclaration **)param; - -- overloadApply(this, &fpunique, &result); -+ if (*pf) -+ { -+ *pf = NULL; -+ return 1; // ambiguous, done -+ } -+ else -+ { -+ *pf = f; -+ return 0; -+ } -+ } -+ }; -+ FuncDeclaration *result = NULL; -+ overloadApply(this, &result, &ParamUnique::fp); - return result; - } - -@@ -2352,179 +2520,62 @@ FuncDeclaration *FuncDeclaration::isUniq - * Find function in overload list that exactly matches t. - */ - --struct Param1 -+FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t) - { -+ struct ParamExact -+ { - Type *t; // type to match - FuncDeclaration *f; // return value --}; -- --int fp1(void *param, FuncDeclaration *f) --{ Param1 *p = (Param1 *)param; -- Type *t = p->t; - -- if (t->equals(f->type)) -- { p->f = f; -- return 1; -- } -+ static int fp(void *param, Dsymbol *s) -+ { -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ if (!f) -+ return 0; -+ ParamExact *p = (ParamExact *)param; -+ Type *t = p->t; - --#if DMDV2 -- /* Allow covariant matches, as long as the return type -- * is just a const conversion. -- * This allows things like pure functions to match with an impure function type. -- */ -- if (t->ty == Tfunction) -- { TypeFunction *tf = (TypeFunction *)f->type; -- if (tf->covariant(t) == 1 && -- tf->nextOf()->implicitConvTo(t->nextOf()) >= MATCHconst) -+ if (t->equals(f->type)) - { - p->f = f; - return 1; - } -- } --#endif -- return 0; --} - --FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t) --{ -- Param1 p; -+#if DMDV2 -+ /* Allow covariant matches, as long as the return type -+ * is just a const conversion. -+ * This allows things like pure functions to match with an impure function type. -+ */ -+ if (t->ty == Tfunction) -+ { TypeFunction *tf = (TypeFunction *)f->type; -+ if (tf->covariant(t) == 1 && -+ tf->nextOf()->implicitConvTo(t->nextOf()) >= MATCHconst) -+ { -+ p->f = f; -+ return 1; -+ } -+ } -+#endif -+ return 0; -+ } -+ }; -+ ParamExact p; - p.t = t; - p.f = NULL; -- overloadApply(this, &fp1, &p); -+ overloadApply(this, &p, &ParamExact::fp); - return p.f; - } - -- --/******************************************** -- * Decide which function matches the arguments best. -- * flags 1: do not issue error message on no match, just return NULL -- * 2: do not issue error on ambiguous matches and need explicit this -- */ -- --struct Param2 -+static void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod) - { -- Match *m; --#if DMDV2 -- Expression *ethis; -- int property; // 0: unintialized -- // 1: seen @property -- // 2: not @property --#endif -- Expressions *arguments; --}; -- --int fp2(void *param, FuncDeclaration *f) --{ Param2 *p = (Param2 *)param; -- Match *m = p->m; -- Expressions *arguments = p->arguments; -- MATCH match; -- -- if (f != m->lastf) // skip duplicates -- { -- m->anyf = f; -- TypeFunction *tf = (TypeFunction *)f->type; -- -- int property = (tf->isproperty) ? 1 : 2; -- if (p->property == 0) -- p->property = property; -- else if (p->property != property) -- error(f->loc, "cannot overload both property and non-property functions"); -- -- /* For constructors, don't worry about the right type of ethis. It's a problem -- * anyway, because the constructor attribute may not match the ethis attribute, -- * but we don't care because the attribute on the ethis doesn't matter until -- * after it's constructed. -- */ -- match = (MATCH) tf->callMatch(f->needThis() && !f->isCtorDeclaration() ? p->ethis : NULL, arguments); -- //printf("test1: match = %d\n", match); -- if (match != MATCHnomatch) -- { -- if (match > m->last) -- goto LfIsBetter; -+ bool bothMutable = ((lhsMod & rhsMod) == 0); -+ bool sharedMismatch = ((lhsMod ^ rhsMod) & MODshared); -+ bool sharedMismatchOnly = ((lhsMod ^ rhsMod) == MODshared); - -- if (match < m->last) -- goto LlastIsBetter; -- -- /* See if one of the matches overrides the other. -- */ -- if (m->lastf->overrides(f)) -- goto LlastIsBetter; -- else if (f->overrides(m->lastf)) -- goto LfIsBetter; -- --#if DMDV2 -- /* Try to disambiguate using template-style partial ordering rules. -- * In essence, if f() and g() are ambiguous, if f() can call g(), -- * but g() cannot call f(), then pick f(). -- * This is because f() is "more specialized." -- */ -- { -- MATCH c1 = f->leastAsSpecialized(m->lastf); -- MATCH c2 = m->lastf->leastAsSpecialized(f); -- //printf("c1 = %d, c2 = %d\n", c1, c2); -- if (c1 > c2) -- goto LfIsBetter; -- if (c1 < c2) -- goto LlastIsBetter; -- } -- -- /* If the two functions are the same function, like: -- * int foo(int); -- * int foo(int x) { ... } -- * then pick the one with the body. -- */ -- if (tf->equals(m->lastf->type) && -- f->storage_class == m->lastf->storage_class && -- f->parent == m->lastf->parent && -- f->protection == m->lastf->protection && -- f->linkage == m->lastf->linkage) -- { -- if (f->fbody && !m->lastf->fbody) -- goto LfIsBetter; -- else if (!f->fbody && m->lastf->fbody) -- goto LlastIsBetter; -- } --#endif -- Lambiguous: -- m->nextf = f; -- m->count++; -- return 0; -- -- LfIsBetter: -- m->last = match; -- m->lastf = f; -- m->count = 1; -- return 0; -- -- LlastIsBetter: -- return 0; -- } -- } -- return 0; --} -- -- --void overloadResolveX(Match *m, FuncDeclaration *fstart, -- Expression *ethis, Expressions *arguments) --{ -- Param2 p; -- p.m = m; -- p.ethis = ethis; -- p.property = 0; -- p.arguments = arguments; -- overloadApply(fstart, &fp2, &p); --} -- --static void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod) --{ -- bool bothMutable = ((lhsMod & rhsMod) == 0); -- bool sharedMismatch = ((lhsMod ^ rhsMod) & MODshared); -- bool sharedMismatchOnly = ((lhsMod ^ rhsMod) == MODshared); -- -- if (lhsMod & MODshared) -- buf->writestring("shared "); -- else if (sharedMismatch && !(lhsMod & MODimmutable)) -- buf->writestring("non-shared "); -+ if (lhsMod & MODshared) -+ buf->writestring("shared "); -+ else if (sharedMismatch && !(lhsMod & MODimmutable)) -+ buf->writestring("non-shared "); - - if (bothMutable && sharedMismatchOnly) - { } -@@ -2538,95 +2589,22 @@ static void MODMatchToBuffer(OutBuffer * - buf->writestring("mutable "); - } - --FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags) --{ -- TypeFunction *tf; -- Match m; -- --#if 0 --printf("FuncDeclaration::overloadResolve('%s')\n", toChars()); --if (arguments) --{ int i; -- -- for (i = 0; i < arguments->dim; i++) -- { Expression *arg; -- -- arg = (*arguments)[i]; -- assert(arg->type); -- printf("\t%s: ", arg->toChars()); -- arg->type->print(); -- } --} --#endif -- -- memset(&m, 0, sizeof(m)); -- m.last = MATCHnomatch; -- overloadResolveX(&m, this, ethis, arguments); -+/******************************************** -+ * find function template root in overload list -+ */ - -- if (m.count == 1) // exactly one match -+TemplateDeclaration *FuncDeclaration::findTemplateDeclRoot() -+{ -+ FuncDeclaration *f = this; -+ while (f && f->overnext) - { -- return m.lastf; -- } -- else -- { -- OutBuffer buf; -- -- buf.writeByte('('); -- if (arguments && arguments->dim) -- { -- HdrGenState hgs; -- argExpTypesToCBuffer(&buf, arguments, &hgs); -- } -- buf.writeByte(')'); -- if (ethis) -- ethis->type->modToBuffer(&buf); -- -- if (m.last == MATCHnomatch) -- { -- if (flags & 1) // if do not print error messages -- return NULL; // no match -- -- tf = (TypeFunction *)type; -- if (ethis && !MODimplicitConv(ethis->type->mod, tf->mod)) // modifier mismatch -- { -- OutBuffer thisBuf, funcBuf; -- MODMatchToBuffer(&thisBuf, ethis->type->mod, tf->mod); -- MODMatchToBuffer(&funcBuf, tf->mod, ethis->type->mod); -- ::error(loc, "%smethod %s is not callable using a %sobject", -- funcBuf.toChars(), this->toPrettyChars(), thisBuf.toChars()); -- } -- else -- { -- //printf("tf = %s, args = %s\n", tf->deco, (*arguments)[0]->type->deco); -- error(loc, "%s%s is not callable using argument types %s", -- Parameter::argsTypesToChars(tf->parameters, tf->varargs), -- tf->modToChars(), -- buf.toChars()); -- } -- -- return m.anyf; // as long as it's not a FuncAliasDeclaration -- } -- else -- { -- if ((flags & 2) && m.lastf->needThis() && !ethis) -- return m.lastf; --#if 1 -- TypeFunction *t1 = (TypeFunction *)m.lastf->type; -- TypeFunction *t2 = (TypeFunction *)m.nextf->type; -- -- error(loc, "called with argument types:\n\t(%s)\nmatches both:\n\t%s(%d): %s%s\nand:\n\t%s(%d): %s%s", -- buf.toChars(), -- m.lastf->loc.filename, m.lastf->loc.linnum, m.lastf->toPrettyChars(), Parameter::argsTypesToChars(t1->parameters, t1->varargs), -- m.nextf->loc.filename, m.nextf->loc.linnum, m.nextf->toPrettyChars(), Parameter::argsTypesToChars(t2->parameters, t2->varargs)); --#else -- error(loc, "overloads %s and %s both match argument list for %s", -- m.lastf->type->toChars(), -- m.nextf->type->toChars(), -- m.lastf->toChars()); --#endif -- return m.lastf; -- } -+ //printf("f->overnext = %p %s\n", f->overnext, f->overnext->toChars()); -+ TemplateDeclaration *td = f->overnext->isTemplateDeclaration(); -+ if (td) -+ return td; -+ f = f->overnext->isFuncDeclaration(); - } -+ return NULL; - } - - /************************************* -@@ -2637,7 +2615,6 @@ if (arguments) - * 0 g is more specialized than 'this' - */ - --#if DMDV2 - MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g) - { - #define LOG_LEASTAS 0 -@@ -2661,15 +2638,22 @@ MATCH FuncDeclaration::leastAsSpecialize - /* If both functions have a 'this' pointer, and the mods are not - * the same and g's is not const, then this is less specialized. - */ -- if (needThis() && g->needThis()) -+ if (needThis() && g->needThis() && tf->mod != tg->mod) - { -- if (tf->mod != tg->mod) -+ if (isCtorDeclaration()) - { -- if (MODimplicitConv(tf->mod, tg->mod)) -+ if (MODimplicitConv(tg->mod, tf->mod)) - match = MATCHconst; - else - return MATCHnomatch; - } -+ else -+ { -+ if (MODimplicitConv(tf->mod, tg->mod)) -+ match = MATCHconst; -+ else -+ return MATCHnomatch; -+ } - } - - /* Create a dummy array of arguments out of the parameters to f() -@@ -2682,11 +2666,11 @@ MATCH FuncDeclaration::leastAsSpecialize - Expression *e; - if (p->storageClass & (STCref | STCout)) - { -- e = new IdentifierExp(0, p->ident); -+ e = new IdentifierExp(Loc(), p->ident); - e->type = p->type; - } - else -- e = p->type->defaultInitLiteral(0); -+ e = p->type->defaultInitLiteral(Loc()); - args[u] = e; - } - -@@ -2714,34 +2698,172 @@ MATCH FuncDeclaration::leastAsSpecialize - /******************************************* - * Given a symbol that could be either a FuncDeclaration or - * a function template, resolve it to a function symbol. -- * sc instantiation scope - * loc instantiation location -- * targsi initial list of template arguments -- * ethis if !NULL, the 'this' pointer argument -+ * sc instantiation scope -+ * tiargs initial list of template arguments -+ * tthis if !NULL, the 'this' pointer argument - * fargs arguments to function - * flags 1: do not issue error message on no match, just return NULL -+ * 2: overloadResolve only - */ - --FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s, -+FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s, - Objects *tiargs, -- Expression *ethis, -- Expressions *arguments, -+ Type *tthis, -+ Expressions *fargs, - int flags) - { - if (!s) - return NULL; // no match -- FuncDeclaration *f = s->isFuncDeclaration(); -- if (f) -- f = f->overloadResolve(loc, ethis, arguments); -- else -- { TemplateDeclaration *td = s->isTemplateDeclaration(); -- assert(td); -- f = td->deduceFunctionTemplate(sc, loc, tiargs, NULL, arguments, flags); -+ -+#if 0 -+ printf("resolveFuncCall('%s')\n", toChars()); -+ if (fargs) -+ { -+ for (size_t i = 0; i < fargs->dim; i++) -+ { -+ Expression *arg = (*fargs)[i]; -+ assert(arg->type); -+ printf("\t%s: ", arg->toChars()); -+ arg->type->print(); -+ } - } -- return f; --} - #endif - -+ if (tiargs && arrayObjectIsError(tiargs) || -+ fargs && arrayObjectIsError((Objects *)fargs)) -+ { -+ return NULL; -+ } -+ -+ Match m; -+ memset(&m, 0, sizeof(m)); -+ m.last = MATCHnomatch; -+ -+ functionResolve(&m, s, loc, sc, tiargs, tthis, fargs); -+ -+ if (m.count == 1) // exactly one match -+ { -+ assert(m.lastf); -+ if (!(flags & 1)) -+ m.lastf->functionSemantic(); -+ return m.lastf; -+ } -+ if (m.last != MATCHnomatch && (flags & 2) && !tthis && m.lastf->needThis()) -+ { -+ return m.lastf; -+ } -+ -+Lerror: -+ /* Failed to find a best match. -+ * Do nothing or print error. -+ */ -+ if (m.last == MATCHnomatch && (flags & 1)) -+ { // if do not print error messages -+ return NULL; // no match -+ } -+ -+ HdrGenState hgs; -+ -+ FuncDeclaration *fd = s->isFuncDeclaration(); -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (td && td->funcroot) -+ s = fd = td->funcroot; -+ -+ OutBuffer tiargsBuf; -+ size_t dim = tiargs ? tiargs->dim : 0; -+ for (size_t i = 0; i < dim; i++) -+ { -+ if (i) -+ tiargsBuf.writestring(", "); -+ RootObject *oarg = (*tiargs)[i]; -+ ObjectToCBuffer(&tiargsBuf, &hgs, oarg); -+ } -+ -+ OutBuffer fargsBuf; -+ fargsBuf.writeByte('('); -+ argExpTypesToCBuffer(&fargsBuf, fargs, &hgs); -+ fargsBuf.writeByte(')'); -+ if (tthis) -+ tthis->modToBuffer(&fargsBuf); -+ -+ assert(!m.lastf || m.nextf); -+ if (!m.lastf && !(flags & 1)) // no match -+ { -+ if (td) -+ { -+ if (!fd) // all of overloads are template -+ { -+ ::error(loc, "%s %s.%s does not match any function template declaration. Candidates are:", -+ td->kind(), td->parent->toPrettyChars(), td->ident->toChars()); -+ -+ // Display candidate template functions -+ int numToDisplay = 5; // sensible number to display -+ for (TemplateDeclaration *tdx = td; tdx; tdx = tdx->overnext) -+ { -+ ::errorSupplemental(tdx->loc, "%s", tdx->toPrettyChars()); -+ if (!global.params.verbose && --numToDisplay == 0) -+ { -+ // Too many overloads to sensibly display. -+ // Just show count of remaining overloads. -+ int remaining = 0; -+ for (; tdx; tdx = tdx->overnext) -+ ++remaining; -+ if (remaining > 0) -+ ::errorSupplemental(loc, "... (%d more, -v to show) ...", remaining); -+ break; -+ } -+ } -+ } -+ td->error(loc, "cannot deduce template function from argument types !(%s)%s", -+ tiargsBuf.toChars(), fargsBuf.toChars()); -+ } -+ else -+ { -+ assert(fd); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ if (tthis && !MODimplicitConv(tthis->mod, tf->mod)) // modifier mismatch -+ { -+ OutBuffer thisBuf, funcBuf; -+ MODMatchToBuffer(&thisBuf, tthis->mod, tf->mod); -+ MODMatchToBuffer(&funcBuf, tf->mod, tthis->mod); -+ ::error(loc, "%smethod %s is not callable using a %sobject", -+ funcBuf.toChars(), fd->toPrettyChars(), thisBuf.toChars()); -+ } -+ else -+ { -+ //printf("tf = %s, args = %s\n", tf->deco, (*fargs)[0]->type->deco); -+ fd->error(loc, "%s%s is not callable using argument types %s", -+ Parameter::argsTypesToChars(tf->parameters, tf->varargs), -+ tf->modToChars(), -+ fargsBuf.toChars()); -+ } -+ } -+ } -+ else if (m.nextf) -+ { -+ /* CAUTION: m.lastf and m.nextf might be incompletely instantiated functions -+ * (created by doHeaderInstantiation), so call toPrettyChars will segfault. -+ */ -+ assert(m.lastf); -+ TypeFunction *t1 = (TypeFunction *)m.lastf->type; -+ TypeFunction *t2 = (TypeFunction *)m.nextf->type; -+ TemplateInstance *lastti = m.lastf->parent->isTemplateInstance(); -+ TemplateInstance *nextti = m.nextf->parent->isTemplateInstance(); -+ Dsymbol *lasts = lastti ? (Dsymbol *)lastti->tempdecl : (Dsymbol *)m.lastf; -+ Dsymbol *nexts = nextti ? (Dsymbol *)nextti->tempdecl : (Dsymbol *)m.nextf; -+ const char *lastprms = lastti ? "" : Parameter::argsTypesToChars(t1->parameters, t1->varargs); -+ const char *nextprms = nextti ? "" : Parameter::argsTypesToChars(t2->parameters, t2->varargs); -+ ::error(loc, "%s.%s called with argument types %s matches both:\n" -+ "\t%s(%d): %s%s\nand:\n\t%s(%d): %s%s", -+ s->parent->toPrettyChars(), s->ident->toChars(), -+ fargsBuf.toChars(), -+ lasts->loc.filename, lasts->loc.linnum, lasts->toChars(), lastprms, -+ nexts->loc.filename, nexts->loc.linnum, nexts->toChars(), nextprms); -+ } -+ return NULL; -+} -+ - /******************************** - * Labels are in a separate scope, one per function. - */ -@@ -2828,7 +2950,8 @@ int FuncDeclaration::getLevel(Loc loc, S - //printf("\ts = %s, '%s'\n", s->kind(), s->toChars()); - FuncDeclaration *thisfd = s->isFuncDeclaration(); - if (thisfd) -- { if (!thisfd->isNested() && !thisfd->vthis && !sc->intypeof) -+ { -+ if (!thisfd->isNested() && !thisfd->vthis && !sc->intypeof) - goto Lerr; - } - else -@@ -2862,14 +2985,18 @@ int FuncDeclaration::getLevel(Loc loc, S - Lerr: - // Don't give error if in template constraint - if (!((sc->flags & SCOPEstaticif) && parent->isTemplateDeclaration())) -- error(loc, "cannot access frame of function %s", fd->toPrettyChars()); -+ { -+ // better diagnostics for static functions -+ ::error(loc, "%s%s %s cannot access frame of function %s", -+ isStatic() ? "static " : "", kind(), toPrettyChars(), fd->toPrettyChars()); -+ } - return 1; - } - - void FuncDeclaration::appendExp(Expression *e) - { Statement *s; - -- s = new ExpStatement(0, e); -+ s = new ExpStatement(Loc(), e); - appendState(s); - } - -@@ -2888,7 +3015,7 @@ void FuncDeclaration::appendState(Statem - cs->statements->push(s); - } - else -- fbody = new CompoundStatement(0, fbody, s); -+ fbody = new CompoundStatement(Loc(), fbody, s); - } - } - -@@ -2900,17 +3027,27 @@ const char *FuncDeclaration::toPrettyCha - return Dsymbol::toPrettyChars(); - } - --int FuncDeclaration::isMain() -+/** for diagnostics, e.g. 'int foo(int x, int y) pure' */ -+const char *FuncDeclaration::toFullSignature() -+{ -+ OutBuffer buf; -+ HdrGenState hgs; -+ functionToCBuffer2((TypeFunction *)type, &buf, &hgs, 0, toChars()); -+ buf.writeByte(0); -+ return buf.extractData(); -+} -+ -+bool FuncDeclaration::isMain() - { - return ident == Id::main && - linkage != LINKc && !isMember() && !isNested(); - } - --int FuncDeclaration::isWinMain() -+bool FuncDeclaration::isWinMain() - { - //printf("FuncDeclaration::isWinMain() %s\n", toChars()); - #if 0 -- int x = ident == Id::WinMain && -+ bool x = ident == Id::WinMain && - linkage != LINKc && !isMember(); - printf("%s\n", x ? "yes" : "no"); - return x; -@@ -2920,18 +3057,18 @@ int FuncDeclaration::isWinMain() - #endif - } - --int FuncDeclaration::isDllMain() -+bool FuncDeclaration::isDllMain() - { - return ident == Id::DllMain && - linkage != LINKc && !isMember(); - } - --int FuncDeclaration::isExport() -+bool FuncDeclaration::isExport() - { - return protection == PROTexport; - } - --int FuncDeclaration::isImportedSymbol() -+bool FuncDeclaration::isImportedSymbol() - { - //printf("isImportedSymbol()\n"); - //printf("protection = %d\n", protection); -@@ -2940,7 +3077,7 @@ int FuncDeclaration::isImportedSymbol() - - // Determine if function goes into virtual function pointer table - --int FuncDeclaration::isVirtual() -+bool FuncDeclaration::isVirtual() - { - if (toAliasFunc() != this) - return toAliasFunc()->isVirtual(); -@@ -2953,40 +3090,40 @@ int FuncDeclaration::isVirtual() - isMember() && - !(isStatic() || protection == PROTprivate || protection == PROTpackage) && - p->isClassDeclaration() && -- !(p->isInterfaceDeclaration() && isFinal())); -+ !(p->isInterfaceDeclaration() && isFinalFunc())); - #endif - return isMember() && - !(isStatic() || protection == PROTprivate || protection == PROTpackage) && - p->isClassDeclaration() && -- !(p->isInterfaceDeclaration() && isFinal()); -+ !(p->isInterfaceDeclaration() && isFinalFunc()); - } - - // Determine if a function is pedantically virtual - --int FuncDeclaration::isVirtualMethod() -+bool FuncDeclaration::isVirtualMethod() - { - if (toAliasFunc() != this) - return toAliasFunc()->isVirtualMethod(); - - //printf("FuncDeclaration::isVirtualMethod() %s\n", toChars()); - if (!isVirtual()) -- return 0; -+ return false; - // If it's a final method, and does not override anything, then it is not virtual -- if (isFinal() && foverrides.dim == 0) -+ if (isFinalFunc() && foverrides.dim == 0) - { -- return 0; -+ return false; - } -- return 1; -+ return true; - } - --int FuncDeclaration::isFinal() -+bool FuncDeclaration::isFinalFunc() - { - if (toAliasFunc() != this) -- return toAliasFunc()->isFinal(); -+ return toAliasFunc()->isFinalFunc(); - - ClassDeclaration *cd; - #if 0 -- printf("FuncDeclaration::isFinal(%s), %x\n", toChars(), Declaration::isFinal()); -+ printf("FuncDeclaration::isFinalFunc(%s), %x\n", toChars(), Declaration::isFinal()); - printf("%p %d %d %d\n", isMember(), isStatic(), Declaration::isFinal(), ((cd = toParent()->isClassDeclaration()) != NULL && cd->storage_class & STCfinal)); - printf("result is %d\n", - isMember() && -@@ -3005,27 +3142,22 @@ int FuncDeclaration::isFinal() - ((cd = toParent()->isClassDeclaration()) != NULL && cd->storage_class & STCfinal)); - } - --int FuncDeclaration::isAbstract() --{ -- return storage_class & STCabstract; --} -- --int FuncDeclaration::isCodeseg() -+bool FuncDeclaration::isCodeseg() - { -- return TRUE; // functions are always in the code segment -+ return true; // functions are always in the code segment - } - --int FuncDeclaration::isOverloadable() -+bool FuncDeclaration::isOverloadable() - { -- return 1; // functions can be overloaded -+ return true; // functions can be overloaded - } - --int FuncDeclaration::hasOverloads() -+bool FuncDeclaration::hasOverloads() - { - return overnext != NULL; - } - --enum PURE FuncDeclaration::isPure() -+PURE FuncDeclaration::isPure() - { - //printf("FuncDeclaration::isPure() '%s'\n", toChars()); - assert(type->ty == Tfunction); -@@ -3034,14 +3166,14 @@ enum PURE FuncDeclaration::isPure() - setImpure(); - if (tf->purity == PUREfwdref) - tf->purityLevel(); -- enum PURE purity = tf->purity; -+ PURE purity = tf->purity; - if (purity > PUREweak && isNested()) - purity = PUREweak; - if (purity > PUREweak && needThis()) - { // The attribute of the 'this' reference affects purity strength -- if (type->mod & (MODimmutable | MODwild)) -+ if (type->mod & MODimmutable) - ; -- else if (type->mod & MODconst && purity >= PUREconst) -+ else if (type->mod & (MODconst | MODwild) && purity >= PUREconst) - purity = PUREconst; - else - purity = PUREweak; -@@ -3052,12 +3184,10 @@ enum PURE FuncDeclaration::isPure() - return purity; - } - --enum PURE FuncDeclaration::isPureBypassingInference() -+PURE FuncDeclaration::isPureBypassingInference() - { - if (flags & FUNCFLAGpurityInprocess) - return PUREfwdref; -- else if (type->nextOf() == NULL) -- return PUREfwdref; - else - return isPure(); - } -@@ -3078,7 +3208,7 @@ bool FuncDeclaration::setImpure() - return FALSE; - } - --int FuncDeclaration::isSafe() -+bool FuncDeclaration::isSafe() - { - assert(type->ty == Tfunction); - if (flags & FUNCFLAGsafetyInprocess) -@@ -3094,7 +3224,7 @@ bool FuncDeclaration::isSafeBypassingInf - return isSafe(); - } - --int FuncDeclaration::isTrusted() -+bool FuncDeclaration::isTrusted() - { - assert(type->ty == Tfunction); - if (flags & FUNCFLAGsafetyInprocess) -@@ -3119,10 +3249,168 @@ bool FuncDeclaration::setUnsafe() - return FALSE; - } - -+/************************************** -+ * Returns an indirect type one step from t. -+ */ -+ -+Type *getIndirection(Type *t) -+{ -+ t = t->baseElemOf(); -+ if (t->ty == Tarray || t->ty == Tpointer) -+ return t->nextOf()->toBasetype(); -+ if (t->ty == Taarray || t->ty == Tclass) -+ return t; -+ if (t->ty == Tstruct) -+ return t->hasPointers() ? t : NULL; // TODO -+ -+ // should consider TypeDelegate? -+ return NULL; -+} -+ -+/************************************** -+ * Traverse this and t, and then check the indirections convertibility. -+ */ -+ -+int traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool a2b = true) -+{ -+ if (a2b) // check ta appears in tb -+ { -+ //printf("\ttraverse(1) %s appears in %s\n", ta->toChars(), tb->toChars()); -+ if (ta->constConv(tb)) -+ return 1; -+ else if (ta->immutableOf()->equals(tb->immutableOf())) -+ return 0; -+ else if (tb->ty == Tvoid && MODimplicitConv(ta->mod, tb->mod)) -+ return 1; -+ } -+ else // check tb appears in ta -+ { -+ //printf("\ttraverse(2) %s appears in %s\n", tb->toChars(), ta->toChars()); -+ if (tb->constConv(ta)) -+ return 1; -+ else if (tb->immutableOf()->equals(ta->immutableOf())) -+ return 0; -+ else if (ta->ty == Tvoid && MODimplicitConv(tb->mod, ta->mod)) -+ return 1; -+ } -+ -+ // context date to detect circular look up -+ struct Ctxt -+ { -+ Ctxt *prev; -+ Type *type; -+ }; -+ Ctxt *ctxt = (Ctxt *)p; -+ -+ Type *tbb = tb->toBasetype(); -+ if (tbb != tb) -+ return traverseIndirections(ta, tbb, ctxt, a2b); -+ -+ tb = tb->baseElemOf(); -+ if (tb->ty == Tclass || tb->ty == Tstruct) -+ { -+ for (Ctxt *c = ctxt; c; c = c->prev) -+ if (tb == c->type) return 0; -+ Ctxt c; -+ c.prev = ctxt; -+ c.type = tb; -+ -+ AggregateDeclaration *sym = tb->toDsymbol(NULL)->isAggregateDeclaration(); -+ for (size_t i = 0; i < sym->fields.dim; i++) -+ { -+ VarDeclaration *v = sym->fields[i]; -+ Type *tprmi = v->type->addMod(tb->mod); -+ if (!(v->storage_class & STCref)) -+ tprmi = getIndirection(tprmi); -+ if (!tprmi) -+ continue; -+ -+ //printf("\ttb = %s, tprmi = %s\n", tb->toChars(), tprmi->toChars()); -+ if (traverseIndirections(ta, tprmi, &c, a2b)) -+ return 1; -+ } -+ } -+ else if (tb->ty == Tarray || tb->ty == Taarray || tb->ty == Tpointer) -+ { -+ Type *tind = tb->nextOf(); -+ if (traverseIndirections(ta, tind, ctxt, a2b)) -+ return 1; -+ } -+ else if (tb->hasPointers()) -+ { -+ // FIXME: function pointer/delegate types should be considered. -+ return 1; -+ } -+ if (a2b) -+ return traverseIndirections(tb, ta, ctxt, false); -+ -+ return 0; -+} -+ -+/******************************************** -+ * Returns true if the function return value has no indirection -+ * which comes from the parameters. -+ */ -+ -+bool FuncDeclaration::isolateReturn() -+{ -+ assert(type->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)type; -+ assert(tf->next); -+ -+ Type *treti = tf->next; -+ treti = tf->isref ? treti : getIndirection(treti); -+ if (!treti) -+ return true; // target has no mutable indirection -+ return parametersIntersect(treti); -+} -+ -+/******************************************** -+ * Returns true if an object typed t can have indirections -+ * which come from the parameters. -+ */ -+ -+bool FuncDeclaration::parametersIntersect(Type *t) -+{ -+ assert(t); -+ if (!isPureBypassingInference() || isNested()) -+ return false; -+ -+ assert(type->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)type; -+ -+ //printf("parametersIntersect(%s) t = %s\n", tf->toChars(), t->toChars()); -+ -+ size_t dim = Parameter::dim(tf->parameters); -+ for (size_t i = 0; i < dim; i++) -+ { -+ Parameter *fparam = Parameter::getNth(tf->parameters, i); -+ if (!fparam->type) -+ continue; -+ Type *tprmi = (fparam->storageClass & (STClazy | STCout | STCref)) -+ ? fparam->type : getIndirection(fparam->type); -+ if (!tprmi) -+ continue; // there is no mutable indirection -+ -+ //printf("\t[%d] tprmi = %d %s\n", i, tprmi->ty, tprmi->toChars()); -+ if (traverseIndirections(tprmi, t)) -+ return false; -+ } -+ if (AggregateDeclaration *ad = isCtorDeclaration() ? NULL : isThis()) -+ { -+ Type *tthis = ad ? ad->getType()->addMod(tf->mod) : NULL; -+ //printf("\ttthis = %s\n", tthis->toChars()); -+ if (traverseIndirections(tthis, t)) -+ return false; -+ } -+ -+ return true; -+} -+ - // Determine if function needs - // a static frame pointer to its lexically enclosing function - --int FuncDeclaration::isNested() -+bool FuncDeclaration::isNested() - { - FuncDeclaration *f = toAliasFunc(); - //printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars()); -@@ -3131,16 +3419,17 @@ int FuncDeclaration::isNested() - (f->toParent2()->isFuncDeclaration() != NULL); - } - --int FuncDeclaration::needThis() -+bool FuncDeclaration::needThis() - { - //printf("FuncDeclaration::needThis() '%s'\n", toChars()); - return toAliasFunc()->isThis() != NULL; - } - --int FuncDeclaration::addPreInvariant() -+bool FuncDeclaration::addPreInvariant() - { - AggregateDeclaration *ad = isThis(); -- return (ad && -+ ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL; -+ return (ad && !(cd && cd->isCPPclass()) && - //ad->isClassDeclaration() && - global.params.useInvariants && - (protection == PROTprotected || protection == PROTpublic || protection == PROTexport) && -@@ -3148,10 +3437,11 @@ int FuncDeclaration::addPreInvariant() - ident != Id::cpctor); - } - --int FuncDeclaration::addPostInvariant() -+bool FuncDeclaration::addPostInvariant() - { - AggregateDeclaration *ad = isThis(); -- return (ad && -+ ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL; -+ return (ad && !(cd && cd->isCPPclass()) && - ad->inv && - //ad->isClassDeclaration() && - global.params.useInvariants && -@@ -3164,12 +3454,12 @@ int FuncDeclaration::addPostInvariant() - * Generate a FuncDeclaration for a runtime library function. - */ - --FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, const char *name) -+FuncDeclaration *FuncDeclaration::genCfunc(Parameters *args, Type *treturn, const char *name) - { -- return genCfunc(treturn, Lexer::idPool(name)); -+ return genCfunc(args, treturn, Lexer::idPool(name)); - } - --FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, Identifier *id) -+FuncDeclaration *FuncDeclaration::genCfunc(Parameters *args, Type *treturn, Identifier *id) - { - FuncDeclaration *fd; - TypeFunction *tf; -@@ -3191,8 +3481,8 @@ FuncDeclaration *FuncDeclaration::genCfu - } - else - { -- tf = new TypeFunction(NULL, treturn, 0, LINKc); -- fd = new FuncDeclaration(0, 0, id, STCstatic, tf); -+ tf = new TypeFunction(args, treturn, 0, LINKc); -+ fd = new FuncDeclaration(Loc(), Loc(), id, STCstatic, tf); - fd->protection = PROTpublic; - fd->linkage = LINKc; - -@@ -3275,7 +3565,7 @@ void FuncDeclaration::checkNestedReferen - */ - void markAsNeedingClosure(Dsymbol *f, FuncDeclaration *outerFunc) - { -- for (Dsymbol *sx = f; sx != outerFunc; sx = sx->parent) -+ for (Dsymbol *sx = f; sx && sx != outerFunc; sx = sx->parent) - { - FuncDeclaration *fy = sx->isFuncDeclaration(); - if (fy && fy->closureVars.dim) -@@ -3323,7 +3613,7 @@ bool checkEscapingSiblings(FuncDeclarati - */ - - #if DMDV2 --int FuncDeclaration::needsClosure() -+bool FuncDeclaration::needsClosure() - { - /* Need a closure for all the closureVars[] if any of the - * closureVars[] are accessed by a -@@ -3411,11 +3701,11 @@ int FuncDeclaration::needsClosure() - } - } - -- return 0; -+ return false; - - Lyes: - //printf("\tneeds closure\n"); -- return 1; -+ return true; - } - #endif - -@@ -3424,14 +3714,14 @@ Lyes: - * nested within it. - */ - --int FuncDeclaration::hasNestedFrameRefs() -+bool FuncDeclaration::hasNestedFrameRefs() - { - #if DMDV2 - if (closureVars.dim) - #else - if (nestedFrameRef) - #endif -- return 1; -+ return true; - - /* If a virtual method has contracts, assume its variables are referenced - * by those contracts, even if they aren't. Because they might be referenced -@@ -3441,7 +3731,7 @@ int FuncDeclaration::hasNestedFrameRefs( - * context had better match, or Bugzilla 7337 will bite. - */ - if ((fdrequire || fdensure) && isVirtualMethod()) -- return 1; -+ return true; - - if (foverrides.dim && isVirtualMethod()) - { -@@ -3449,11 +3739,11 @@ int FuncDeclaration::hasNestedFrameRefs( - { - FuncDeclaration *fdv = foverrides[i]; - if (fdv->hasNestedFrameRefs()) -- return 1; -+ return true; - } - } - -- return 0; -+ return false; - } - - /********************************************* -@@ -3462,8 +3752,8 @@ int FuncDeclaration::hasNestedFrameRefs( - */ - - Parameters *FuncDeclaration::getParameters(int *pvarargs) --{ Parameters *fparameters; -- int fvarargs; -+{ Parameters *fparameters = NULL; -+ int fvarargs = 0; - - if (type) - { -@@ -3482,7 +3772,7 @@ Parameters *FuncDeclaration::getParamete - - // Used as a way to import a set of functions from another scope into this one. - --FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias, int hasOverloads) -+FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias, bool hasOverloads) - : FuncDeclaration(funcalias->loc, funcalias->endloc, funcalias->ident, - funcalias->storage_class, funcalias->type) - { -@@ -3498,7 +3788,7 @@ FuncAliasDeclaration::FuncAliasDeclarati - else - { // for internal use - assert(!funcalias->isFuncAliasDeclaration()); -- this->hasOverloads = 0; -+ this->hasOverloads = false; - } - userAttributes = funcalias->userAttributes; - } -@@ -3517,20 +3807,10 @@ FuncDeclaration *FuncAliasDeclaration::t - /****************************** FuncLiteralDeclaration ************************/ - - FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, -- enum TOK tok, ForeachStatement *fes) -+ TOK tok, ForeachStatement *fes, Identifier *id) - : FuncDeclaration(loc, endloc, NULL, STCundefined, type) - { -- const char *id; -- -- if (fes) -- id = "__foreachbody"; -- else if (tok == TOKreserved) -- id = "__lambda"; -- else if (tok == TOKdelegate) -- id = "__dgliteral"; -- else -- id = "__funcliteral"; -- this->ident = Lexer::uniqueId(id); -+ this->ident = id ? id : Id::empty; - this->tok = tok; - this->fes = fes; - this->treq = NULL; -@@ -3545,23 +3825,21 @@ Dsymbol *FuncLiteralDeclaration::syntaxC - if (s) - f = (FuncLiteralDeclaration *)s; - else -- { f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes); -- f->ident = ident; // keep old identifier -- f->treq = treq; // don't need to copy -- } -+ f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes, ident); -+ f->treq = treq; // don't need to copy - FuncDeclaration::syntaxCopy(f); - return f; - } - --int FuncLiteralDeclaration::isNested() -+bool FuncLiteralDeclaration::isNested() - { - //printf("FuncLiteralDeclaration::isNested() '%s'\n", toChars()); - return (tok != TOKfunction); - } - --int FuncLiteralDeclaration::isVirtual() -+bool FuncLiteralDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - - const char *FuncLiteralDeclaration::kind() -@@ -3580,16 +3858,24 @@ void FuncLiteralDeclaration::toCBuffer(O - - TypeFunction *tf = (TypeFunction *)type; - // Don't print tf->mod, tf->trust, and tf->linkage -- if (tf->next) -+ if (!inferRetType && tf->next) - tf->next->toCBuffer2(buf, hgs, 0); - Parameter::argsToCBuffer(buf, hgs, tf->parameters, tf->varargs); - -- ReturnStatement *ret = !fbody->isCompoundStatement() ? -- fbody->isReturnStatement() : NULL; -- if (ret && ret->exp) -+ CompoundStatement *cs = fbody->isCompoundStatement(); -+ Statement *s1; -+ if (semanticRun >= PASSsemantic3done) -+ { -+ assert(cs); -+ s1 = (*cs->statements)[cs->statements->dim - 1]; -+ } -+ else -+ s1 = !cs ? fbody : NULL; -+ ReturnStatement *rs = s1 ? s1->isReturnStatement() : NULL; -+ if (rs && rs->exp) - { - buf->writestring(" => "); -- ret->exp->toCBuffer(buf, hgs); -+ rs->exp->toCBuffer(buf, hgs); - } - else - { -@@ -3606,7 +3892,6 @@ CtorDeclaration::CtorDeclaration(Loc loc - : FuncDeclaration(loc, endloc, Id::ctor, stc, type) - { - //printf("CtorDeclaration(loc = %s) %s\n", loc.toChars(), toChars()); -- this->isImplicit = false; - } - - Dsymbol *CtorDeclaration::syntaxCopy(Dsymbol *s) -@@ -3638,33 +3923,13 @@ void CtorDeclaration::semantic(Scope *sc - sc->stc &= ~STCstatic; // not a static constructor - sc->flags |= SCOPEctor; - -- parent = sc->parent; -- Dsymbol *parent = toParent2(); -- Type *tret; -- AggregateDeclaration *ad = parent->isAggregateDeclaration(); -- if (!ad || parent->isUnionDeclaration()) -- { -- error("constructors are only for class or struct definitions"); -- tret = Type::tvoid; -- } -- else -- { tret = ad->handle; -- assert(tret); -- tret = tret->addStorageClass(storage_class | sc->stc); -- tret = tret->addMod(type->mod); -- } -- tf->next = tret; -- if (!originalType) -- originalType = type->syntaxCopy(); -- type = type->semantic(loc, sc); -- -- if (ad && ad->isStructDeclaration()) -- ((TypeFunction *)type)->isref = 1; -- - FuncDeclaration::semantic(sc); - - sc->pop(); - -+ Dsymbol *parent = toParent2(); -+ AggregateDeclaration *ad = parent->isAggregateDeclaration(); -+ - /* See if it's the default constructor - * But, template constructor should not become a default constructor. - */ -@@ -3698,17 +3963,17 @@ char *CtorDeclaration::toChars() - return (char *)"this"; - } - --int CtorDeclaration::isVirtual() -+bool CtorDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - --int CtorDeclaration::addPreInvariant() -+bool CtorDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int CtorDeclaration::addPostInvariant() -+bool CtorDeclaration::addPostInvariant() - { - return (isThis() && vthis && global.params.useInvariants); - } -@@ -3761,24 +4026,24 @@ void PostBlitDeclaration::semantic(Scope - sc->pop(); - } - --int PostBlitDeclaration::overloadInsert(Dsymbol *s) -+bool PostBlitDeclaration::overloadInsert(Dsymbol *s) - { -- return FALSE; // cannot overload postblits -+ return false; // cannot overload postblits - } - --int PostBlitDeclaration::addPreInvariant() -+bool PostBlitDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int PostBlitDeclaration::addPostInvariant() -+bool PostBlitDeclaration::addPostInvariant() - { - return (isThis() && vthis && global.params.useInvariants); - } - --int PostBlitDeclaration::isVirtual() -+bool PostBlitDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - - void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -3795,15 +4060,15 @@ DtorDeclaration::DtorDeclaration(Loc loc - { - } - --DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc, Identifier *id) -- : FuncDeclaration(loc, endloc, id, STCundefined, NULL) -+DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id) -+ : FuncDeclaration(loc, endloc, id, stc, NULL) - { - } - - Dsymbol *DtorDeclaration::syntaxCopy(Dsymbol *s) - { - assert(!s); -- DtorDeclaration *dd = new DtorDeclaration(loc, endloc, ident); -+ DtorDeclaration *dd = new DtorDeclaration(loc, endloc, storage_class, ident); - return FuncDeclaration::syntaxCopy(dd); - } - -@@ -3827,7 +4092,7 @@ void DtorDeclaration::semantic(Scope *sc - ad->dtors.push(this); - - if (!type) -- type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); -+ type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd, storage_class); - - sc = sc->push(); - sc->stc &= ~STCstatic; // not a static destructor -@@ -3838,19 +4103,19 @@ void DtorDeclaration::semantic(Scope *sc - sc->pop(); - } - --int DtorDeclaration::overloadInsert(Dsymbol *s) -+bool DtorDeclaration::overloadInsert(Dsymbol *s) - { -- return FALSE; // cannot overload destructors -+ return false; // cannot overload destructors - } - --int DtorDeclaration::addPreInvariant() -+bool DtorDeclaration::addPreInvariant() - { - return (isThis() && vthis && global.params.useInvariants); - } - --int DtorDeclaration::addPostInvariant() -+bool DtorDeclaration::addPostInvariant() - { -- return FALSE; -+ return false; - } - - const char *DtorDeclaration::kind() -@@ -3863,10 +4128,10 @@ char *DtorDeclaration::toChars() - return (char *)"~this"; - } - --int DtorDeclaration::isVirtual() -+bool DtorDeclaration::isVirtual() - { -- // FALSE so that dtor's don't get put into the vtbl[] -- return FALSE; -+ // false so that dtor's don't get put into the vtbl[] -+ return false; - } - - void DtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -3922,19 +4187,19 @@ void StaticCtorDeclaration::semantic(Sco - * during static construction. - */ - Identifier *id = Lexer::idPool("__gate"); -- VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL); -+ VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, id, NULL); - v->storage_class = isSharedStaticCtorDeclaration() ? STCstatic : STCtls; - Statements *sa = new Statements(); -- Statement *s = new ExpStatement(0, v); -+ Statement *s = new ExpStatement(Loc(), v); - sa->push(s); -- Expression *e = new IdentifierExp(0, id); -- e = new AddAssignExp(0, e, new IntegerExp(1)); -- e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(1)); -- s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL); -+ Expression *e = new IdentifierExp(Loc(), id); -+ e = new AddAssignExp(Loc(), e, new IntegerExp(1)); -+ e = new EqualExp(TOKnotequal, Loc(), e, new IntegerExp(1)); -+ s = new IfStatement(Loc(), NULL, e, new ReturnStatement(Loc(), NULL), NULL); - sa->push(s); - if (fbody) - sa->push(fbody); -- fbody = new CompoundStatement(0, sa); -+ fbody = new CompoundStatement(Loc(), sa); - } - - FuncDeclaration::semantic(sc); -@@ -3954,9 +4219,9 @@ AggregateDeclaration *StaticCtorDeclarat - return NULL; - } - --int StaticCtorDeclaration::isVirtual() -+bool StaticCtorDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - - bool StaticCtorDeclaration::hasStaticCtorOrDtor() -@@ -3964,14 +4229,14 @@ bool StaticCtorDeclaration::hasStaticCto - return TRUE; - } - --int StaticCtorDeclaration::addPreInvariant() -+bool StaticCtorDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int StaticCtorDeclaration::addPostInvariant() -+bool StaticCtorDeclaration::addPostInvariant() - { -- return FALSE; -+ return false; - } - - void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -4008,16 +4273,16 @@ void SharedStaticCtorDeclaration::toCBuf - - /********************************* StaticDtorDeclaration ****************************/ - --StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc) -+StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc) - : FuncDeclaration(loc, endloc, -- Identifier::generateId("_staticDtor"), STCstatic, NULL) -+ Identifier::generateId("_staticDtor"), STCstatic | stc, NULL) - { - vgate = NULL; - } - --StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc, const char *name) -+StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc) - : FuncDeclaration(loc, endloc, -- Identifier::generateId(name), STCstatic, NULL) -+ Identifier::generateId(name), STCstatic | stc, NULL) - { - vgate = NULL; - } -@@ -4025,7 +4290,7 @@ StaticDtorDeclaration::StaticDtorDeclara - Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s) - { - assert(!s); -- StaticDtorDeclaration *sdd = new StaticDtorDeclaration(loc, endloc); -+ StaticDtorDeclaration *sdd = new StaticDtorDeclaration(loc, endloc, storage_class); - return FuncDeclaration::syntaxCopy(sdd); - } - -@@ -4037,10 +4302,8 @@ void StaticDtorDeclaration::semantic(Sco - scope = NULL; - } - -- ClassDeclaration *cd = sc->scopesym->isClassDeclaration(); -- - if (!type) -- type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); -+ type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd, storage_class); - - /* If the static ctor appears within a template instantiation, - * it could get called multiple times by the module constructors -@@ -4056,19 +4319,19 @@ void StaticDtorDeclaration::semantic(Sco - * during static destruction. - */ - Identifier *id = Lexer::idPool("__gate"); -- VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL); -+ VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, id, NULL); - v->storage_class = isSharedStaticDtorDeclaration() ? STCstatic : STCtls; - Statements *sa = new Statements(); -- Statement *s = new ExpStatement(0, v); -+ Statement *s = new ExpStatement(Loc(), v); - sa->push(s); -- Expression *e = new IdentifierExp(0, id); -- e = new AddAssignExp(0, e, new IntegerExp(-1)); -- e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(0)); -- s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL); -+ Expression *e = new IdentifierExp(Loc(), id); -+ e = new AddAssignExp(Loc(), e, new IntegerExp(-1)); -+ e = new EqualExp(TOKnotequal, Loc(), e, new IntegerExp(0)); -+ s = new IfStatement(Loc(), NULL, e, new ReturnStatement(Loc(), NULL), NULL); - sa->push(s); - if (fbody) - sa->push(fbody); -- fbody = new CompoundStatement(0, sa); -+ fbody = new CompoundStatement(Loc(), sa); - vgate = v; - } - -@@ -4089,9 +4352,9 @@ AggregateDeclaration *StaticDtorDeclarat - return NULL; - } - --int StaticDtorDeclaration::isVirtual() -+bool StaticDtorDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - - bool StaticDtorDeclaration::hasStaticCtorOrDtor() -@@ -4099,14 +4362,14 @@ bool StaticDtorDeclaration::hasStaticCto - return TRUE; - } - --int StaticDtorDeclaration::addPreInvariant() -+bool StaticDtorDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int StaticDtorDeclaration::addPostInvariant() -+bool StaticDtorDeclaration::addPostInvariant() - { -- return FALSE; -+ return false; - } - - void StaticDtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -4119,15 +4382,15 @@ void StaticDtorDeclaration::toCBuffer(Ou - - /********************************* SharedStaticDtorDeclaration ****************************/ - --SharedStaticDtorDeclaration::SharedStaticDtorDeclaration(Loc loc, Loc endloc) -- : StaticDtorDeclaration(loc, endloc, "_sharedStaticDtor") -+SharedStaticDtorDeclaration::SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc) -+ : StaticDtorDeclaration(loc, endloc, "_sharedStaticDtor", stc) - { - } - - Dsymbol *SharedStaticDtorDeclaration::syntaxCopy(Dsymbol *s) - { - assert(!s); -- SharedStaticDtorDeclaration *sdd = new SharedStaticDtorDeclaration(loc, endloc); -+ SharedStaticDtorDeclaration *sdd = new SharedStaticDtorDeclaration(loc, endloc, storage_class); - return FuncDeclaration::syntaxCopy(sdd); - } - -@@ -4143,8 +4406,10 @@ void SharedStaticDtorDeclaration::toCBuf - - /********************************* InvariantDeclaration ****************************/ - --InvariantDeclaration::InvariantDeclaration(Loc loc, Loc endloc) -- : FuncDeclaration(loc, endloc, Id::classInvariant, STCundefined, NULL) -+InvariantDeclaration::InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id) -+ : FuncDeclaration(loc, endloc, -+ id ? id : Identifier::generateId("__invariant"), -+ stc, NULL) - { - } - -@@ -4153,7 +4418,7 @@ Dsymbol *InvariantDeclaration::syntaxCop - InvariantDeclaration *id; - - assert(!s); -- id = new InvariantDeclaration(loc, endloc); -+ id = new InvariantDeclaration(loc, endloc, storage_class); - FuncDeclaration::syntaxCopy(id); - return id; - } -@@ -4173,13 +4438,12 @@ void InvariantDeclaration::semantic(Scop - error("invariants are only for struct/union/class definitions"); - return; - } -- else if (ad->inv && ad->inv != this && semanticRun < PASSsemantic) -+ if (ident != Id::classInvariant && semanticRun < PASSsemantic) - { -- error("more than one invariant for %s", ad->toChars()); -+ ad->invs.push(this); - } -- ad->inv = this; - if (!type) -- type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); -+ type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd, storage_class); - - sc = sc->push(); - sc->stc &= ~STCstatic; // not a static invariant -@@ -4192,19 +4456,19 @@ void InvariantDeclaration::semantic(Scop - sc->pop(); - } - --int InvariantDeclaration::isVirtual() -+bool InvariantDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - --int InvariantDeclaration::addPreInvariant() -+bool InvariantDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int InvariantDeclaration::addPostInvariant() -+bool InvariantDeclaration::addPostInvariant() - { -- return FALSE; -+ return false; - } - - void InvariantDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -4223,22 +4487,21 @@ void InvariantDeclaration::toCBuffer(Out - * instances per module. - */ - --#if __DMC__ || _MSC_VER --#define snprintf _snprintf --#endif - static Identifier *unitTestId(Loc loc) - { - char name[24]; -+#if __DMC__ || _MSC_VER -+ _snprintf(name, 24, "__unittestL%u_", loc.linnum); -+#else - snprintf(name, 24, "__unittestL%u_", loc.linnum); -+#endif - return Lexer::uniqueId(name); - } --#if __DMC__ || _MSC_VER --#undef snprintf --#endif - --UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc) -+UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc, char *codedoc) - : FuncDeclaration(loc, endloc, unitTestId(loc), STCundefined, NULL) - { -+ this->codedoc = codedoc; - } - - Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s) -@@ -4246,13 +4509,15 @@ Dsymbol *UnitTestDeclaration::syntaxCopy - UnitTestDeclaration *utd; - - assert(!s); -- utd = new UnitTestDeclaration(loc, endloc); -+ utd = new UnitTestDeclaration(loc, endloc, codedoc); - return FuncDeclaration::syntaxCopy(utd); - } - - - void UnitTestDeclaration::semantic(Scope *sc) - { -+ protection = sc->protection; -+ - if (scope) - { sc = scope; - scope = NULL; -@@ -4263,8 +4528,6 @@ void UnitTestDeclaration::semantic(Scope - if (!type) - type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); - Scope *sc2 = sc->push(); -- // It makes no sense for unit tests to be pure or nothrow. -- sc2->stc &= ~(STCnothrow | STCpure); - sc2->linkage = LINKd; - FuncDeclaration::semantic(sc2); - sc2->pop(); -@@ -4291,19 +4554,19 @@ AggregateDeclaration *UnitTestDeclaratio - return NULL; - } - --int UnitTestDeclaration::isVirtual() -+bool UnitTestDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - --int UnitTestDeclaration::addPreInvariant() -+bool UnitTestDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int UnitTestDeclaration::addPostInvariant() -+bool UnitTestDeclaration::addPostInvariant() - { -- return FALSE; -+ return false; - } - - void UnitTestDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -4381,19 +4644,19 @@ const char *NewDeclaration::kind() - return "allocator"; - } - --int NewDeclaration::isVirtual() -+bool NewDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - --int NewDeclaration::addPreInvariant() -+bool NewDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int NewDeclaration::addPostInvariant() -+bool NewDeclaration::addPostInvariant() - { -- return FALSE; -+ return false; - } - - void NewDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -4469,24 +4732,24 @@ const char *DeleteDeclaration::kind() - return "deallocator"; - } - --int DeleteDeclaration::isDelete() -+bool DeleteDeclaration::isDelete() - { -- return TRUE; -+ return true; - } - --int DeleteDeclaration::isVirtual() -+bool DeleteDeclaration::isVirtual() - { -- return FALSE; -+ return false; - } - --int DeleteDeclaration::addPreInvariant() -+bool DeleteDeclaration::addPreInvariant() - { -- return FALSE; -+ return false; - } - --int DeleteDeclaration::addPostInvariant() -+bool DeleteDeclaration::addPostInvariant() - { -- return FALSE; -+ return false; - } - - void DeleteDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) ---- a/src/gcc/d/dfrontend/gpl.txt 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/gpl.txt 2014-04-01 16:32:51.000000000 +0100 -@@ -1,248 +1,248 @@ -- GNU GENERAL PUBLIC LICENSE -- Version 1, February 1989 -- -- Copyright (C) 1989 Free Software Foundation, Inc. -- 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA -- Everyone is permitted to copy and distribute verbatim copies -- of this license document, but changing it is not allowed. -- -- Preamble -- -- The license agreements of most software companies try to keep users --at the mercy of those companies. By contrast, our General Public --License is intended to guarantee your freedom to share and change free --software--to make sure the software is free for all its users. The --General Public License applies to the Free Software Foundation's --software and to any other program whose authors commit to using it. --You can use it for your programs, too. -- -- When we speak of free software, we are referring to freedom, not --price. Specifically, the General Public License is designed to make --sure that you have the freedom to give away or sell copies of free --software, that you receive source code or can get it if you want it, --that you can change the software or use pieces of it in new free --programs; and that you know you can do these things. -- -- To protect your rights, we need to make restrictions that forbid --anyone to deny you these rights or to ask you to surrender the rights. --These restrictions translate to certain responsibilities for you if you --distribute copies of the software, or if you modify it. -- -- For example, if you distribute copies of a such a program, whether --gratis or for a fee, you must give the recipients all the rights that --you have. You must make sure that they, too, receive or can get the --source code. And you must tell them their rights. -- -- We protect your rights with two steps: (1) copyright the software, and --(2) offer you this license which gives you legal permission to copy, --distribute and/or modify the software. -- -- Also, for each author's protection and ours, we want to make certain --that everyone understands that there is no warranty for this free --software. If the software is modified by someone else and passed on, we --want its recipients to know that what they have is not the original, so --that any problems introduced by others will not reflect on the original --authors' reputations. -- -- The precise terms and conditions for copying, distribution and --modification follow. -- -- GNU GENERAL PUBLIC LICENSE -- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -- -- 0. This License Agreement applies to any program or other work which --contains a notice placed by the copyright holder saying it may be --distributed under the terms of this General Public License. The --"Program", below, refers to any such program or work, and a "work based --on the Program" means either the Program or any work containing the --Program or a portion of it, either verbatim or with modifications. Each --licensee is addressed as "you". -- -- 1. You may copy and distribute verbatim copies of the Program's source --code as you receive it, in any medium, provided that you conspicuously and --appropriately publish on each copy an appropriate copyright notice and --disclaimer of warranty; keep intact all the notices that refer to this --General Public License and to the absence of any warranty; and give any --other recipients of the Program a copy of this General Public License --along with the Program. You may charge a fee for the physical act of --transferring a copy. -- -- 2. You may modify your copy or copies of the Program or any portion of --it, and copy and distribute such modifications under the terms of Paragraph --1 above, provided that you also do the following: -- -- a) cause the modified files to carry prominent notices stating that -- you changed the files and the date of any change; and -- -- b) cause the whole of any work that you distribute or publish, that -- in whole or in part contains the Program or any part thereof, either -- with or without modifications, to be licensed at no charge to all -- third parties under the terms of this General Public License (except -- that you may choose to grant warranty protection to some or all -- third parties, at your option). -- -- c) If the modified program normally reads commands interactively when -- run, you must cause it, when started running for such interactive use -- in the simplest and most usual way, to print or display an -- announcement including an appropriate copyright notice and a notice -- that there is no warranty (or else, saying that you provide a -- warranty) and that users may redistribute the program under these -- conditions, and telling the user how to view a copy of this General -- Public License. -- -- d) You may charge a fee for the physical act of transferring a -- copy, and you may at your option offer warranty protection in -- exchange for a fee. -- --Mere aggregation of another independent work with the Program (or its --derivative) on a volume of a storage or distribution medium does not bring --the other work under the scope of these terms. -- -- 3. You may copy and distribute the Program (or a portion or derivative of --it, under Paragraph 2) in object code or executable form under the terms of --Paragraphs 1 and 2 above provided that you also do one of the following: -- -- a) accompany it with the complete corresponding machine-readable -- source code, which must be distributed under the terms of -- Paragraphs 1 and 2 above; or, -- -- b) accompany it with a written offer, valid for at least three -- years, to give any third party free (except for a nominal charge -- for the cost of distribution) a complete machine-readable copy of the -- corresponding source code, to be distributed under the terms of -- Paragraphs 1 and 2 above; or, -- -- c) accompany it with the information you received as to where the -- corresponding source code may be obtained. (This alternative is -- allowed only for noncommercial distribution and only if you -- received the program in object code or executable form alone.) -- --Source code for a work means the preferred form of the work for making --modifications to it. For an executable file, complete source code means --all the source code for all modules it contains; but, as a special --exception, it need not include source code for modules which are standard --libraries that accompany the operating system on which the executable --file runs, or for standard header files or definitions files that --accompany that operating system. -- -- 4. You may not copy, modify, sublicense, distribute or transfer the --Program except as expressly provided under this General Public License. --Any attempt otherwise to copy, modify, sublicense, distribute or transfer --the Program is void, and will automatically terminate your rights to use --the Program under this License. However, parties who have received --copies, or rights to use copies, from you under this General Public --License will not have their licenses terminated so long as such parties --remain in full compliance. -- -- 5. By copying, distributing or modifying the Program (or any work based --on the Program) you indicate your acceptance of this license to do so, --and all its terms and conditions. -- -- 6. Each time you redistribute the Program (or any work based on the --Program), the recipient automatically receives a license from the original --licensor to copy, distribute or modify the Program subject to these --terms and conditions. You may not impose any further restrictions on the --recipients' exercise of the rights granted herein. -- -- 7. The Free Software Foundation may publish revised and/or new versions --of the General Public License from time to time. Such new versions will --be similar in spirit to the present version, but may differ in detail to --address new problems or concerns. -- --Each version is given a distinguishing version number. If the Program --specifies a version number of the license which applies to it and "any --later version", you have the option of following the terms and conditions --either of that version or of any later version published by the Free --Software Foundation. If the Program does not specify a version number of --the license, you may choose any version ever published by the Free Software --Foundation. -- -- 8. If you wish to incorporate parts of the Program into other free --programs whose distribution conditions are different, write to the author --to ask for permission. For software which is copyrighted by the Free --Software Foundation, write to the Free Software Foundation; we sometimes --make exceptions for this. Our decision will be guided by the two goals --of preserving the free status of all derivatives of our free software and --of promoting the sharing and reuse of software generally. -- -- NO WARRANTY -- -- 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY --FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN --OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES --PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED --OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF --MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS --TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE --PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, --REPAIR OR CORRECTION. -- -- 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING --WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR --REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, --INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING --OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED --TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY --YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER --PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE --POSSIBILITY OF SUCH DAMAGES. -- -- END OF TERMS AND CONDITIONS -- -- Appendix: How to Apply These Terms to Your New Programs -- -- If you develop a new program, and you want it to be of the greatest --possible use to humanity, the best way to achieve this is to make it --free software which everyone can redistribute and change under these --terms. -- -- To do so, attach the following notices to the program. It is safest to --attach them to the start of each source file to most effectively convey --the exclusion of warranty; and each file should have at least the --"copyright" line and a pointer to where the full notice is found. -- -- -- Copyright (C) 19yy -- -- 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 1, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -- --Also add information on how to contact you by electronic and paper mail. -- --If the program is interactive, make it output a short notice like this --when it starts in an interactive mode: -- -- Gnomovision version 69, Copyright (C) 19xx name of author -- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -- This is free software, and you are welcome to redistribute it -- under certain conditions; type `show c' for details. -- --The hypothetical commands `show w' and `show c' should show the --appropriate parts of the General Public License. Of course, the --commands you use may be called something other than `show w' and `show --c'; they could even be mouse-clicks or menu items--whatever suits your --program. -- --You should also get your employer (if you work as a programmer) or your --school, if any, to sign a "copyright disclaimer" for the program, if --necessary. Here a sample; alter the names: -- -- Yoyodyne, Inc., hereby disclaims all copyright interest in the -- program `Gnomovision' (a program to direct compilers to make passes -- at assemblers) written by James Hacker. -- -- , 1 April 1989 -- Ty Coon, President of Vice -- --That's all there is to it! -+ GNU GENERAL PUBLIC LICENSE -+ Version 1, February 1989 -+ -+ Copyright (C) 1989 Free Software Foundation, Inc. -+ 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The license agreements of most software companies try to keep users -+at the mercy of those companies. By contrast, our General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. The -+General Public License applies to the Free Software Foundation's -+software and to any other program whose authors commit to using it. -+You can use it for your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Specifically, the General Public License is designed to make -+sure that you have the freedom to give away or sell copies of free -+software, that you receive source code or can get it if you want it, -+that you can change the software or use pieces of it in new free -+programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of a such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must tell them their rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License Agreement applies to any program or other work which -+contains a notice placed by the copyright holder saying it may be -+distributed under the terms of this General Public License. The -+"Program", below, refers to any such program or work, and a "work based -+on the Program" means either the Program or any work containing the -+Program or a portion of it, either verbatim or with modifications. Each -+licensee is addressed as "you". -+ -+ 1. You may copy and distribute verbatim copies of the Program's source -+code as you receive it, in any medium, provided that you conspicuously and -+appropriately publish on each copy an appropriate copyright notice and -+disclaimer of warranty; keep intact all the notices that refer to this -+General Public License and to the absence of any warranty; and give any -+other recipients of the Program a copy of this General Public License -+along with the Program. You may charge a fee for the physical act of -+transferring a copy. -+ -+ 2. You may modify your copy or copies of the Program or any portion of -+it, and copy and distribute such modifications under the terms of Paragraph -+1 above, provided that you also do the following: -+ -+ a) cause the modified files to carry prominent notices stating that -+ you changed the files and the date of any change; and -+ -+ b) cause the whole of any work that you distribute or publish, that -+ in whole or in part contains the Program or any part thereof, either -+ with or without modifications, to be licensed at no charge to all -+ third parties under the terms of this General Public License (except -+ that you may choose to grant warranty protection to some or all -+ third parties, at your option). -+ -+ c) If the modified program normally reads commands interactively when -+ run, you must cause it, when started running for such interactive use -+ in the simplest and most usual way, to print or display an -+ announcement including an appropriate copyright notice and a notice -+ that there is no warranty (or else, saying that you provide a -+ warranty) and that users may redistribute the program under these -+ conditions, and telling the user how to view a copy of this General -+ Public License. -+ -+ d) You may charge a fee for the physical act of transferring a -+ copy, and you may at your option offer warranty protection in -+ exchange for a fee. -+ -+Mere aggregation of another independent work with the Program (or its -+derivative) on a volume of a storage or distribution medium does not bring -+the other work under the scope of these terms. -+ -+ 3. You may copy and distribute the Program (or a portion or derivative of -+it, under Paragraph 2) in object code or executable form under the terms of -+Paragraphs 1 and 2 above provided that you also do one of the following: -+ -+ a) accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of -+ Paragraphs 1 and 2 above; or, -+ -+ b) accompany it with a written offer, valid for at least three -+ years, to give any third party free (except for a nominal charge -+ for the cost of distribution) a complete machine-readable copy of the -+ corresponding source code, to be distributed under the terms of -+ Paragraphs 1 and 2 above; or, -+ -+ c) accompany it with the information you received as to where the -+ corresponding source code may be obtained. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form alone.) -+ -+Source code for a work means the preferred form of the work for making -+modifications to it. For an executable file, complete source code means -+all the source code for all modules it contains; but, as a special -+exception, it need not include source code for modules which are standard -+libraries that accompany the operating system on which the executable -+file runs, or for standard header files or definitions files that -+accompany that operating system. -+ -+ 4. You may not copy, modify, sublicense, distribute or transfer the -+Program except as expressly provided under this General Public License. -+Any attempt otherwise to copy, modify, sublicense, distribute or transfer -+the Program is void, and will automatically terminate your rights to use -+the Program under this License. However, parties who have received -+copies, or rights to use copies, from you under this General Public -+License will not have their licenses terminated so long as such parties -+remain in full compliance. -+ -+ 5. By copying, distributing or modifying the Program (or any work based -+on the Program) you indicate your acceptance of this license to do so, -+and all its terms and conditions. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the original -+licensor to copy, distribute or modify the Program subject to these -+terms and conditions. You may not impose any further restrictions on the -+recipients' exercise of the rights granted herein. -+ -+ 7. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of the license which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+the license, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 8. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ Appendix: How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to humanity, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these -+terms. -+ -+ To do so, attach the following notices to the program. It is safest to -+attach them to the start of each source file to most effectively convey -+the exclusion of warranty; and each file should have at least the -+"copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) 19yy -+ -+ 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 1, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) 19xx name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the -+appropriate parts of the General Public License. Of course, the -+commands you use may be called something other than `show w' and `show -+c'; they could even be mouse-clicks or menu items--whatever suits your -+program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the -+ program `Gnomovision' (a program to direct compilers to make passes -+ at assemblers) written by James Hacker. -+ -+ , 1 April 1989 -+ Ty Coon, President of Vice -+ -+That's all there is to it! ---- a/src/gcc/d/dfrontend/hdrgen.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/hdrgen.c 2014-04-01 16:32:51.000000000 +0100 -@@ -66,8 +66,8 @@ void Module::genhdrfile() - hdrfile->setbuffer(hdrbufr.data, hdrbufr.offset); - hdrbufr.data = NULL; - -- FileName::ensurePathToNameExists(hdrfile->toChars()); -- hdrfile->writev(); -+ ensurePathToNameExists(Loc(), hdrfile->toChars()); -+ writeFile(loc, hdrfile); - } - - ---- a/src/gcc/d/dfrontend/identifier.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/identifier.c 2014-04-01 16:32:51.000000000 +0100 -@@ -25,17 +25,12 @@ Identifier::Identifier(const char *strin - this->len = strlen(string); - } - --hash_t Identifier::hashCode() --{ -- return String::calcHash(string); --} -- --int Identifier::equals(Object *o) -+bool Identifier::equals(RootObject *o) - { - return this == o || memcmp(string,o->toChars(),len+1) == 0; - } - --int Identifier::compare(Object *o) -+int Identifier::compare(RootObject *o) - { - return memcmp(string, o->toChars(), len + 1); - } -@@ -51,7 +46,6 @@ const char *Identifier::toHChars2() - - if (this == Id::ctor) p = "this"; - else if (this == Id::dtor) p = "~this"; -- else if (this == Id::classInvariant) p = "invariant"; - else if (this == Id::unitTest) p = "unittest"; - else if (this == Id::dollar) p = "$"; - else if (this == Id::withSym) p = "with"; -@@ -65,6 +59,8 @@ const char *Identifier::toHChars2() - p = "static this"; - else if (memcmp(p, "_staticDtor", 11) == 0) - p = "static ~this"; -+ else if (memcmp(p, "__invariant", 11) == 0) -+ p = "invariant"; - } - } - -@@ -73,7 +69,7 @@ const char *Identifier::toHChars2() - - void Identifier::print() - { -- fprintf(stdmsg, "%s",string); -+ fprintf(stderr, "%s",string); - } - - int Identifier::dyncast() ---- a/src/gcc/d/dfrontend/identifier.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/identifier.h 2014-04-01 16:32:51.000000000 +0100 -@@ -17,19 +17,18 @@ - - #include "root.h" - --struct Identifier : Object -+class Identifier : public RootObject - { -+public: - int value; - const char *string; - size_t len; - - Identifier(const char *string, int value); -- int equals(Object *o); -- hash_t hashCode(); -- int compare(Object *o); -+ bool equals(RootObject *o); -+ int compare(RootObject *o); - void print(); - char *toChars(); -- char *toHChars(); - const char *toHChars2(); - int dyncast(); - ---- a/src/gcc/d/dfrontend/idgen.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/idgen.c 2014-04-01 16:32:51.000000000 +0100 -@@ -108,6 +108,9 @@ Msgtable msgtable[] = - - { "LINE", "__LINE__" }, - { "FILE", "__FILE__" }, -+ { "MODULE", "__MODULE__" }, -+ { "FUNCTION", "__FUNCTION__" }, -+ { "PRETTY_FUNCTION", "__PRETTY_FUNCTION__" }, - { "DATE", "__DATE__" }, - { "TIME", "__TIME__" }, - { "TIMESTAMP", "__TIMESTAMP__" }, -@@ -263,6 +266,7 @@ Msgtable msgtable[] = - { "lib" }, - { "msg" }, - { "startaddress" }, -+ { "mangle" }, - - // For special functions - { "tohash", "toHash" }, -@@ -275,6 +279,7 @@ Msgtable msgtable[] = - { "WinMain" }, - { "DllMain" }, - { "tls_get_addr", "___tls_get_addr" }, -+ { "entrypoint", "__entrypoint" }, - - // varargs implementation - { "va_argsave_t", "__va_argsave_t" }, -@@ -307,6 +312,7 @@ Msgtable msgtable[] = - { "isAssociativeArray" }, - { "isFinalClass" }, - { "isPOD" }, -+ { "isNested" }, - { "isFloating" }, - { "isIntegral" }, - { "isScalar" }, -@@ -335,6 +341,9 @@ Msgtable msgtable[] = - { "compiles" }, - { "parameters" }, - { "getAttributes" }, -+ { "getUnitTests" }, -+ { "isOverrideFunction" }, -+ { "getVirtualIndex" } - }; - - -@@ -356,7 +365,7 @@ int main() - #endif - fprintf(fp, "#ifndef DMD_ID_H\n"); - fprintf(fp, "#define DMD_ID_H 1\n"); -- fprintf(fp, "struct Identifier;\n"); -+ fprintf(fp, "class Identifier;\n"); - fprintf(fp, "struct Id\n"); - fprintf(fp, "{\n"); - ---- a/src/gcc/d/dfrontend/impcnvgen.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/impcnvgen.c 2014-04-01 16:32:51.000000000 +0100 -@@ -381,44 +381,64 @@ int main() - fprintf(fp,"unsigned char Type::impcnvResult[TMAX][TMAX] =\n{\n"); - for (i = 0; i < TMAX; i++) - { -+ if (i) -+ fprintf(fp, ","); -+ fprintf(fp, "{"); - for (j = 0; j < TMAX; j++) - { -- fprintf(fp, "%d,",impcnvResult[i][j]); -+ if (j) -+ fprintf(fp, ","); -+ fprintf(fp, "%d",impcnvResult[i][j]); - } -- fprintf(fp, "\n"); -+ fprintf(fp, "}\n"); - } - fprintf(fp,"};\n"); - - fprintf(fp,"unsigned char Type::impcnvType1[TMAX][TMAX] =\n{\n"); - for (i = 0; i < TMAX; i++) - { -+ if (i) -+ fprintf(fp, ","); -+ fprintf(fp, "{"); - for (j = 0; j < TMAX; j++) - { -- fprintf(fp, "%d,",impcnvType1[i][j]); -+ if (j) -+ fprintf(fp, ","); -+ fprintf(fp, "%d",impcnvType1[i][j]); - } -- fprintf(fp, "\n"); -+ fprintf(fp, "}\n"); - } - fprintf(fp,"};\n"); - - fprintf(fp,"unsigned char Type::impcnvType2[TMAX][TMAX] =\n{\n"); - for (i = 0; i < TMAX; i++) - { -+ if (i) -+ fprintf(fp, ","); -+ fprintf(fp, "{"); - for (j = 0; j < TMAX; j++) - { -- fprintf(fp, "%d,",impcnvType2[i][j]); -+ if (j) -+ fprintf(fp, ","); -+ fprintf(fp, "%d",impcnvType2[i][j]); - } -- fprintf(fp, "\n"); -+ fprintf(fp, "}\n"); - } - fprintf(fp,"};\n"); - - fprintf(fp,"unsigned char Type::impcnvWarn[TMAX][TMAX] =\n{\n"); - for (i = 0; i < TMAX; i++) - { -+ if (i) -+ fprintf(fp, ","); -+ fprintf(fp, "{"); - for (j = 0; j < TMAX; j++) - { -- fprintf(fp, "%d,",impcnvWarn[i][j]); -+ if (j) -+ fprintf(fp, ","); -+ fprintf(fp, "%d",impcnvWarn[i][j]); - } -- fprintf(fp, "\n"); -+ fprintf(fp, "}\n"); - } - fprintf(fp,"};\n"); - ---- a/src/gcc/d/dfrontend/import.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/import.c 2014-04-01 16:32:51.000000000 +0100 -@@ -30,6 +30,18 @@ Import::Import(Loc loc, Identifiers *pac - : Dsymbol(NULL) - { - assert(id); -+#if 0 -+ printf("Import::Import("); -+ if (packages && packages->dim) -+ { -+ for (size_t i = 0; i < packages->dim; i++) -+ { -+ Identifier *id = (*packages)[i]; -+ printf("%s.", id->toChars()); -+ } -+ } -+ printf("%s)\n", id->toChars()); -+#endif - this->loc = loc; - this->packages = packages; - this->id = id; -@@ -68,7 +80,7 @@ const char *Import::kind() - return isstatic ? (char *)"static import" : (char *)"import"; - } - --enum PROT Import::prot() -+PROT Import::prot() - { - return protection; - } -@@ -89,10 +101,11 @@ Dsymbol *Import::syntaxCopy(Dsymbol *s) - - void Import::load(Scope *sc) - { -- //printf("Import::load('%s')\n", toChars()); -+ //printf("Import::load('%s') %p\n", toPrettyChars(), this); - - // See if existing module - DsymbolTable *dst = Package::resolve(packages, NULL, &pkg); -+#if 0 - if (pkg && pkg->isModule()) - { - ::error(loc, "can only import from a module, not from a member of module %s. Did you mean `import %s : %s`?", -@@ -100,6 +113,7 @@ void Import::load(Scope *sc) - mod = pkg->isModule(); // Error recovery - treat as import of that module - return; - } -+#endif - Dsymbol *s = dst->lookup(id); - if (s) - { -@@ -107,7 +121,31 @@ void Import::load(Scope *sc) - mod = (Module *)s; - else - { -- if (pkg) -+ if (s->isAliasDeclaration()) -+ { -+ ::error(loc, "%s %s conflicts with %s", s->kind(), s->toPrettyChars(), id->toChars()); -+ } -+ else if (Package *p = s->isPackage()) -+ { -+ if (p->isPkgMod == PKGunknown) -+ { -+ mod = Module::load(loc, packages, id); -+ if (!mod) -+ p->isPkgMod = PKGpackage; -+ else -+ assert(p->isPkgMod == PKGmodule); -+ } -+ else if (p->isPkgMod == PKGmodule) -+ { -+ mod = p->mod; -+ } -+ if (p->isPkgMod != PKGmodule) -+ { -+ ::error(loc, "can only import from a module, not from package %s.%s", -+ p->toPrettyChars(), id->toChars()); -+ } -+ } -+ else if (pkg) - { - ::error(loc, "can only import from a module, not from package %s.%s", - pkg->toPrettyChars(), id->toChars()); -@@ -128,43 +166,23 @@ void Import::load(Scope *sc) - { - dst->insert(id, mod); // id may be different from mod->ident, - // if so then insert alias -- if (!mod->importedFrom) -- mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule; - } - } -+ if (mod && !mod->importedFrom) -+ mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule; - if (!pkg) - pkg = mod; - - //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg); - } - --void escapePath(OutBuffer *buf, const char *fname) --{ -- while (1) -- { -- switch (*fname) -- { -- case 0: -- return; -- case '(': -- case ')': -- case '\\': -- buf->writebyte('\\'); -- default: -- buf->writebyte(*fname); -- break; -- } -- fname++; -- } --} -- - void Import::importAll(Scope *sc) - { - if (!mod) - { - load(sc); - if (mod) // if successfully loaded module -- { mod->importAll(0); -+ { mod->importAll(NULL); - - if (!isstatic && !aliasId && !names.dim) - { -@@ -178,7 +196,7 @@ void Import::importAll(Scope *sc) - - void Import::semantic(Scope *sc) - { -- //printf("Import::semantic('%s')\n", toChars()); -+ //printf("Import::semantic('%s')\n", toPrettyChars()); - - if (scope) - { sc = scope; -@@ -189,7 +207,7 @@ void Import::semantic(Scope *sc) - if (!mod) - { load(sc); - if (mod) -- mod->importAll(0); -+ mod->importAll(NULL); - } - - if (mod) -@@ -245,7 +263,6 @@ void Import::semantic(Scope *sc) - if (mod->search(loc, names[i], 0)) - { - ad->semantic(sc); -- ad->import = NULL; // forward reference resolved - } - else - { -@@ -261,7 +278,10 @@ void Import::semantic(Scope *sc) - - if (global.params.moduleDeps != NULL && - // object self-imports itself, so skip that (Bugzilla 7547) -- !(id == Id::object && sc->module->ident == Id::object)) -+ !(id == Id::object && sc->module->ident == Id::object) && -+ // don't list pseudo modules __entrypoint.d, __main.d (Bugzilla 11117, 11164) -+ sc->module->ident != Id::entrypoint && -+ strcmp(sc->module->ident->string, "__main") != 0) - { - /* The grammar of the file is: - * ImportDeclaration -@@ -277,10 +297,12 @@ void Import::semantic(Scope *sc) - */ - - OutBuffer *ob = global.params.moduleDeps; -- -- ob->writestring(sc->module->toPrettyChars()); -+ Module* imod = sc->instantiatingModule ? sc->instantiatingModule : sc->module; -+ if (!global.params.moduleDepsFile) -+ ob->writestring("depsImport "); -+ ob->writestring(imod->toPrettyChars()); - ob->writestring(" ("); -- escapePath(ob, sc->module->srcfile->toChars()); -+ escapePath(ob, imod->srcfile->toChars()); - ob->writestring(") : "); - - // use protection instead of sc->protection because it couldn't be -@@ -404,7 +426,7 @@ Dsymbol *Import::search(Loc loc, Identif - return pkg->search(loc, ident, flags); - } - --int Import::overloadInsert(Dsymbol *s) -+bool Import::overloadInsert(Dsymbol *s) - { - /* Allow multiple imports with the same package base, but disallow - * alias collisions (Bugzilla 5412). -@@ -412,9 +434,9 @@ int Import::overloadInsert(Dsymbol *s) - assert(ident && ident == s->ident); - Import *imp; - if (!aliasId && (imp = s->isImport()) != NULL && !imp->aliasId) -- return TRUE; -+ return true; - else -- return FALSE; -+ return false; - } - - void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs) ---- a/src/gcc/d/dfrontend/import.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/import.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2007 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -18,37 +18,41 @@ - #include "dsymbol.h" - - --struct Identifier; -+class Identifier; - struct Scope; - struct OutBuffer; --struct Module; --struct Package; --struct AliasDeclaration; -+class Module; -+class Package; -+class AliasDeclaration; - struct HdrGenState; - --struct Import : Dsymbol -+class Import : public Dsymbol - { -+public: -+ /* static import aliasId = pkg1.pkg2.id : alias1 = name1, alias2 = name2; -+ */ -+ - Identifiers *packages; // array of Identifier's representing packages - Identifier *id; // module Identifier - Identifier *aliasId; - int isstatic; // !=0 if static import -- enum PROT protection; -+ PROT protection; - - // Pairs of alias=name to bind into current namespace - Identifiers names; - Identifiers aliases; - -- AliasDeclarations aliasdecls; // AliasDeclarations for names/aliases -- -- Module *mod; -- Package *pkg; // leftmost package/module -- - Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *aliasId, - int isstatic); - void addAlias(Identifier *name, Identifier *alias); - -+ AliasDeclarations aliasdecls; // corresponding AliasDeclarations for alias=name pairs -+ -+ Module *mod; -+ Package *pkg; // leftmost package/module -+ - const char *kind(); -- enum PROT prot(); -+ PROT prot(); - Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees - void load(Scope *sc); - void importAll(Scope *sc); -@@ -57,7 +61,7 @@ struct Import : Dsymbol - Dsymbol *toAlias(); - int addMember(Scope *sc, ScopeDsymbol *s, int memnum); - Dsymbol *search(Loc loc, Identifier *ident, int flags); -- int overloadInsert(Dsymbol *s); -+ bool overloadInsert(Dsymbol *s); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - void toJson(JsonOut *json); - ---- a/src/gcc/d/dfrontend/init.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/init.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -65,15 +65,48 @@ Initializers *Initializer::arraySyntaxCo - } - - char *Initializer::toChars() --{ OutBuffer *buf; -+{ - HdrGenState hgs; - -- memset(&hgs, 0, sizeof(hgs)); -- buf = new OutBuffer(); -- toCBuffer(buf, &hgs); -- return buf->toChars(); -+ OutBuffer buf; -+ toCBuffer(&buf, &hgs); -+ buf.writebyte(0); -+ return buf.extractData(); -+} -+ -+/********************************** ErrorInitializer ***************************/ -+ -+ErrorInitializer::ErrorInitializer() -+ : Initializer(Loc()) -+{ -+} -+ -+ -+Initializer *ErrorInitializer::syntaxCopy() -+{ -+ return this; -+} -+ -+ -+Initializer *ErrorInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret) -+{ -+ //printf("ErrorInitializer::semantic(t = %p)\n", t); -+ return this; -+} -+ -+ -+Expression *ErrorInitializer::toExpression(Type *t) -+{ -+ return new ErrorExp(); -+} -+ -+ -+void ErrorInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -+{ -+ buf->writestring("__error__"); - } - -+ - /********************************** VoidInitializer ***************************/ - - VoidInitializer::VoidInitializer(Loc loc) -@@ -97,10 +130,9 @@ Initializer *VoidInitializer::semantic(S - } - - --Expression *VoidInitializer::toExpression() -+Expression *VoidInitializer::toExpression(Type *t) - { -- error(loc, "void initializer has no value"); -- return new IntegerExp(0); -+ return NULL; - } - - -@@ -115,7 +147,6 @@ void VoidInitializer::toCBuffer(OutBuffe - StructInitializer::StructInitializer(Loc loc) - : Initializer(loc) - { -- ad = NULL; - } - - Initializer *StructInitializer::syntaxCopy() -@@ -145,69 +176,48 @@ void StructInitializer::addInit(Identifi - - Initializer *StructInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret) - { -- int errors = 0; -- - //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars()); -- vars.setDim(field.dim); - t = t->toBasetype(); - if (t->ty == Tsarray && t->nextOf()->toBasetype()->ty == Tstruct) - t = t->nextOf()->toBasetype(); - if (t->ty == Tstruct) - { -- size_t fieldi = 0; -- -- TypeStruct *ts = (TypeStruct *)t; -- ad = ts->sym; -- if (ad->ctor) -+ StructDeclaration *sd = ((TypeStruct *)t)->sym; -+ if (sd->ctor) -+ { - error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead", -- ad->kind(), ad->toChars(), ad->toChars()); -- StructDeclaration *sd = ad->isStructDeclaration(); -- assert(sd); -+ sd->kind(), sd->toChars(), sd->toChars()); -+ return new ErrorInitializer(); -+ } - sd->size(loc); - if (sd->sizeok != SIZEOKdone) -- { -- error(loc, "struct %s is forward referenced", sd->toChars()); -- errors = 1; -- goto Lerror; -- } -- size_t nfields = sd->fields.dim; -- if (sd->isnested) -- nfields--; -- for (size_t i = 0; i < field.dim; i++) -- { -- Identifier *id = field[i]; -- Initializer *val = value[i]; -- Dsymbol *s; -- VarDeclaration *v; -+ return new ErrorInitializer(); -+ size_t nfields = sd->fields.dim - sd->isNested(); - -- if (id == NULL) -- { -- if (fieldi >= nfields) -- { error(loc, "too many initializers for %s", ad->toChars()); -- errors = 1; -- field.remove(i); -- i--; -- continue; -- } -- else -- { -- s = ad->fields[fieldi]; -- } -- } -- else -+ //expandTuples for non-identity arguments? -+ -+ Expressions *elements = new Expressions(); -+ elements->setDim(nfields); -+ for (size_t i = 0; i < elements->dim; i++) -+ (*elements)[i] = NULL; -+ -+ // Run semantic for explicitly given initializers -+ // TODO: this part is slightly different from StructLiteralExp::semantic. -+ bool errors = false; -+ for (size_t fieldi = 0, i = 0; i < field.dim; i++) -+ { -+ if (Identifier *id = field[i]) - { -- //s = ad->symtab->lookup(id); -- s = ad->search(loc, id, 0); -+ Dsymbol *s = sd->search(loc, id, 0); - if (!s) - { -- s = ad->search_correct(id); -+ s = sd->search_correct(id); - if (s) - error(loc, "'%s' is not a member of '%s', did you mean '%s %s'?", -- id->toChars(), t->toChars(), s->kind(), s->toChars()); -+ id->toChars(), sd->toChars(), s->kind(), s->toChars()); - else -- error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars()); -- errors = 1; -- continue; -+ error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars()); -+ return new ErrorInitializer(); - } - s = s->toAlias(); - -@@ -217,52 +227,82 @@ Initializer *StructInitializer::semantic - if (fieldi >= nfields) - { - error(loc, "%s.%s is not a per-instance initializable field", -- t->toChars(), s->toChars()); -- errors = 1; -- break; -+ sd->toChars(), s->toChars()); -+ return new ErrorInitializer(); - } -- if (s == ad->fields[fieldi]) -+ if (s == sd->fields[fieldi]) - break; - } - } -- if (s && (v = s->isVarDeclaration()) != NULL) -+ else if (fieldi >= nfields) - { -- val = val->semantic(sc, v->type->addMod(t->mod), needInterpret); -- value[i] = val; -- vars[i] = v; -+ error(loc, "too many initializers for %s", sd->toChars()); -+ return new ErrorInitializer(); - } -- else -- { error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars()); -- errors = 1; -+ -+ VarDeclaration *vd = sd->fields[fieldi]; -+ if ((*elements)[fieldi]) -+ { -+ error(loc, "duplicate initializer for field '%s'", vd->toChars()); -+ errors = true; -+ continue; - } -- fieldi++; -- } -+ for (size_t j = 0; j < nfields; j++) -+ { -+ VarDeclaration *v2 = sd->fields[j]; -+ bool overlap = (vd->offset < v2->offset + v2->type->size() && -+ v2->offset < vd->offset + vd->type->size()); -+ if (overlap && (*elements)[j]) -+ { -+ error(loc, "overlapping initialization for field %s and %s", -+ v2->toChars(), vd->toChars()); -+ errors = true; -+ continue; -+ } -+ } -+ -+ assert(sc); -+ Initializer *iz = value[i]; -+ iz = iz->semantic(sc, vd->type->addMod(t->mod), needInterpret); -+ Expression *ex = iz->toExpression(); -+ if (ex->op == TOKerror) -+ { -+ errors = true; -+ continue; -+ } -+ value[i] = iz; -+ (*elements)[fieldi] = ex; -+ ++fieldi; -+ } -+ if (errors) -+ return new ErrorInitializer(); -+ -+ StructLiteralExp *sle = new StructLiteralExp(loc, sd, elements, t); -+ Expression *e = sle->fill(false); -+ if (e->op == TOKerror) -+ return new ErrorInitializer(); -+ -+ e->type = t; -+ -+ ExpInitializer *ie = new ExpInitializer(loc, e); -+ return ie->semantic(sc, t, needInterpret); - } - else if (t->ty == Tdelegate && value.dim == 0) -- { /* Rewrite as empty delegate literal { } -+ { -+ /* Rewrite as empty delegate literal { } - */ - Parameters *arguments = new Parameters; - Type *tf = new TypeFunction(arguments, NULL, 0, LINKd); -- FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL); -+ FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, Loc(), tf, TOKdelegate, NULL); - fd->fbody = new CompoundStatement(loc, new Statements()); - fd->endloc = loc; - Expression *e = new FuncExp(loc, fd); - ExpInitializer *ie = new ExpInitializer(loc, e); - return ie->semantic(sc, t, needInterpret); - } -- else -- { -- error(loc, "a struct is not a valid initializer for a %s", t->toChars()); -- errors = 1; -- } --Lerror: -- if (errors) -- { -- field.setDim(0); -- value.setDim(0); -- vars.setDim(0); -- } -- return this; -+ -+ error(loc, "a struct is not a valid initializer for a %s", t->toChars()); -+ return new ErrorInitializer(); - } - - /*************************************** -@@ -270,156 +310,12 @@ Lerror: - * a struct literal. In the future, the two should be the - * same thing. - */ --Expression *StructInitializer::toExpression() --{ Expression *e; -- size_t offset; -- -- //printf("StructInitializer::toExpression() %s\n", toChars()); -- if (!ad) // if fwd referenced -- return NULL; -- StructDeclaration *sd = ad->isStructDeclaration(); -- if (!sd) -- return NULL; -- -- Expressions *elements = new Expressions(); -- size_t nfields = ad->fields.dim; --#if DMDV2 -- if (sd->isnested) -- nfields--; --#endif -- elements->setDim(nfields); -- for (size_t i = 0; i < elements->dim; i++) -- { -- (*elements)[i] = NULL; -- } -- size_t fieldi = 0; -- for (size_t i = 0; i < value.dim; i++) -- { -- Identifier *id = field[i]; -- if (id) -- { -- Dsymbol * s = ad->search(loc, id, 0); -- if (!s) -- { -- error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars()); -- goto Lno; -- } -- s = s->toAlias(); -- -- // Find out which field index it is -- for (fieldi = 0; 1; fieldi++) -- { -- if (fieldi >= nfields) -- { -- s->error("is not a per-instance initializable field"); -- goto Lno; -- } -- if (s == ad->fields[fieldi]) -- break; -- } -- } -- else if (fieldi >= nfields) -- { error(loc, "too many initializers for '%s'", ad->toChars()); -- goto Lno; -- } -- Initializer *iz = value[i]; -- if (!iz) -- goto Lno; -- Expression *ex = iz->toExpression(); -- if (!ex) -- goto Lno; -- if ((*elements)[fieldi]) -- { error(loc, "duplicate initializer for field '%s'", -- ad->fields[fieldi]->toChars()); -- goto Lno; -- } -- (*elements)[fieldi] = ex; -- ++fieldi; -- } -- // Now, fill in any missing elements with default initializers. -- // We also need to validate any anonymous unions -- offset = 0; -- for (size_t i = 0; i < elements->dim; ) -- { -- VarDeclaration * vd = ad->fields[i]->isVarDeclaration(); -- -- //printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset); -- if (vd->offset < offset) -- { -- // Only the first field of a union can have an initializer -- if ((*elements)[i]) -- goto Lno; -- } -- else -- { -- if (!(*elements)[i]) -- { // Default initialize -- if (vd->init) -- { -- if (vd->scope) -- { // Do deferred semantic analysis -- Initializer *i2 = vd->init->syntaxCopy(); -- i2 = i2->semantic(vd->scope, vd->type, INITinterpret); -- (*elements)[i] = i2->toExpression(); -- if (!global.gag) -- { vd->scope = NULL; -- vd->init = i2; // save result -- } -- } -- else -- (*elements)[i] = vd->init->toExpression(); -- } -- else -- (*elements)[i] = vd->type->defaultInit(); -- } -- } -- offset = vd->offset + vd->type->size(); -- i++; --#if 0 -- int unionSize = ad->numFieldsInUnion(i); -- if (unionSize == 1) -- { // Not a union -- default initialize if missing -- if (!(*elements)[i]) -- (*elements)[i] = vd->type->defaultInit(); -- } -- else -- { // anonymous union -- check for errors -- int found = -1; // index of the first field with an initializer -- for (size_t j = i; j < i + unionSize; ++j) -- { -- if (!(*elements)[j]) -- continue; -- if (found >= 0) -- { -- VarDeclaration * v1 = ((Dsymbol *)ad->fields.data[found])->isVarDeclaration(); -- VarDeclaration * v = ((Dsymbol *)ad->fields.data[j])->isVarDeclaration(); -- error(loc, "%s cannot have initializers for fields %s and %s in same union", -- ad->toChars(), -- v1->toChars(), v->toChars()); -- goto Lno; -- } -- found = j; -- } -- if (found == -1) -- { -- error(loc, "no initializer for union that contains field %s", -- vd->toChars()); -- goto Lno; -- } -- } -- i += unionSize; --#endif -- } -- e = new StructLiteralExp(loc, sd, elements); -- e->type = sd->type; -- return e; -- --Lno: -- delete elements; -+Expression *StructInitializer::toExpression(Type *t) -+{ -+ // cannot convert to an expression without target 'ad' - return NULL; - } - -- - void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - //printf("StructInitializer::toCBuffer()\n"); -@@ -427,7 +323,7 @@ void StructInitializer::toCBuffer(OutBuf - for (size_t i = 0; i < field.dim; i++) - { - if (i > 0) -- buf->writebyte(','); -+ buf->writestring(", "); - Identifier *id = field[i]; - if (id) - { -@@ -485,6 +381,7 @@ Initializer *ArrayInitializer::semantic( - { - size_t length; - const unsigned amax = 0x80000000; -+ bool errors = false; - - //printf("ArrayInitializer::semantic(%s)\n", t->toChars()); - if (sem) // if semantic() already run -@@ -519,10 +416,15 @@ Initializer *ArrayInitializer::semantic( - { - Expression *idx = index[i]; - if (idx) -- { idx = idx->semantic(sc); -+ { -+ sc = sc->startCTFE(); -+ idx = idx->semantic(sc); -+ sc = sc->endCTFE(); - idx = idx->ctfeInterpret(); - index[i] = idx; - length = idx->toInteger(); -+ if (idx->op == TOKerror) -+ errors = true; - } - - Initializer *val = value[i]; -@@ -530,6 +432,8 @@ Initializer *ArrayInitializer::semantic( - if (ei && !idx) - ei->expandTuples = 1; - val = val->semantic(sc, t->nextOf(), needInterpret); -+ if (val->isErrorInitializer()) -+ errors = true; - - ei = val->isExpInitializer(); - // found a tuple, expand it -@@ -570,6 +474,8 @@ Initializer *ArrayInitializer::semantic( - goto Lerr; - } - } -+ if (errors) -+ goto Lerr; - - if ((uinteger_t) dim * t->nextOf()->size() >= amax) - { error(loc, "array dimension %u exceeds max of %u", (unsigned) dim, (unsigned)(amax / t->nextOf()->size())); -@@ -578,7 +484,7 @@ Initializer *ArrayInitializer::semantic( - return this; - - Lerr: -- return new ExpInitializer(loc, new ErrorExp()); -+ return new ErrorInitializer(); - } - - /******************************** -@@ -586,12 +492,12 @@ Lerr: - * Otherwise return NULL. - */ - --Expression *ArrayInitializer::toExpression() --{ Expressions *elements; -- -+Expression *ArrayInitializer::toExpression(Type *tx) -+{ - //printf("ArrayInitializer::toExpression(), dim = %d\n", dim); - //static int i; if (++i == 2) halt(); - -+ Expressions *elements; - size_t edim; - Type *t = NULL; - if (type) -@@ -606,6 +512,11 @@ Expression *ArrayInitializer::toExpressi - edim = ((TypeSArray *)t)->dim->toInteger(); - break; - -+ case Tvector: -+ t = ((TypeVector *)t)->basetype; -+ edim = ((TypeSArray *)t)->dim->toInteger(); -+ break; -+ - case Tpointer: - case Tarray: - edim = dim; -@@ -667,6 +578,12 @@ Expression *ArrayInitializer::toExpressi - } - } - -+ for (size_t i = 0; i < edim; i++) -+ { Expression *e = (*elements)[i]; -+ if (e->op == TOKerror) -+ return e; -+ } -+ - Expression *e = new ArrayLiteralExp(loc, elements); - e->type = type; - return e; -@@ -782,7 +699,7 @@ void ArrayInitializer::toCBuffer(OutBuff - for (size_t i = 0; i < index.dim; i++) - { - if (i > 0) -- buf->writebyte(','); -+ buf->writestring(", "); - Expression *ex = index[i]; - if (ex) - { -@@ -842,6 +759,27 @@ bool hasNonConstPointers(Expression *e) - return arrayHasNonConstPointers(ae->keys); - return false; - } -+ if(e->op == TOKaddress) -+ { -+ AddrExp *ae = (AddrExp *)e; -+ if (ae->e1->op == TOKstructliteral) -+ { -+ StructLiteralExp *se = (StructLiteralExp *)ae->e1; -+ if (!(se->stageflags & stageSearchPointers)) -+ { -+ int old = se->stageflags; -+ se->stageflags |= stageSearchPointers; -+ bool ret = arrayHasNonConstPointers(se->elements); -+ se->stageflags = old; -+ return ret; -+ } -+ else -+ { -+ return false; -+ } -+ } -+ return true; -+ } - if (e->type->ty== Tpointer && e->type->nextOf()->ty != Tfunction) - { - if (e->op == TOKsymoff) // address of a global is OK -@@ -870,8 +808,10 @@ bool arrayHasNonConstPointers(Expression - Initializer *ExpInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret) - { - //printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars()); -+ if (needInterpret) sc = sc->startCTFE(); - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); -+ if (needInterpret) sc = sc->endCTFE(); - if (exp->op == TOKerror) - return this; - -@@ -884,13 +824,16 @@ Initializer *ExpInitializer::semantic(Sc - return this; // Failed, suppress duplicate error messages - - if (exp->op == TOKtype) -+ { - exp->error("initializer must be an expression, not '%s'", exp->toChars()); -+ return new ErrorInitializer(); -+ } - - // Make sure all pointers are constants - if (needInterpret && hasNonConstPointers(exp)) - { - exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", exp->toChars()); -- return this; -+ return new ErrorInitializer(); - } - - Type *tb = t->toBasetype(); -@@ -946,6 +889,9 @@ Initializer *ExpInitializer::semantic(Sc - exp->implicitConvTo(tb->nextOf()) - ) - { -+ /* If the variable is not actually used in compile time, array creation is -+ * redundant. So delay it until invocation of toExpression() or toDt(). -+ */ - t = tb->nextOf(); - } - -@@ -978,18 +924,33 @@ Type *ExpInitializer::inferType(Scope *s - - // Give error for overloaded function addresses - if (exp->op == TOKsymoff) -- { SymOffExp *se = (SymOffExp *)exp; -+ { -+ SymOffExp *se = (SymOffExp *)exp; - if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique()) -+ { - exp->error("cannot infer type from overloaded function symbol %s", exp->toChars()); -+ return Type::terror; -+ } - } -- -- // Give error for overloaded function addresses - if (exp->op == TOKdelegate) -- { DelegateExp *se = (DelegateExp *)exp; -+ { -+ DelegateExp *se = (DelegateExp *)exp; - if (se->hasOverloads && - se->func->isFuncDeclaration() && - !se->func->isFuncDeclaration()->isUnique()) -+ { - exp->error("cannot infer type from overloaded function symbol %s", exp->toChars()); -+ return Type::terror; -+ } -+ } -+ if (exp->op == TOKaddress) -+ { -+ AddrExp *ae = (AddrExp *)exp; -+ if (ae->e1->op == TOKoverloadset) -+ { -+ exp->error("cannot infer type from overloaded function symbol %s", exp->toChars()); -+ return Type::terror; -+ } - } - - Type *t = exp->type; -@@ -998,8 +959,24 @@ Type *ExpInitializer::inferType(Scope *s - return t; - } - --Expression *ExpInitializer::toExpression() -+Expression *ExpInitializer::toExpression(Type *t) - { -+ if (t) -+ { -+ Type *tb = t->toBasetype(); -+ if (tb->ty == Tsarray && exp->implicitConvTo(tb->nextOf())) -+ { -+ TypeSArray *tsa = (TypeSArray *)tb; -+ size_t d = tsa->dim->toInteger(); -+ Expressions *elements = new Expressions(); -+ elements->setDim(d); -+ for (size_t i = 0; i < d; i++) -+ (*elements)[i] = exp; -+ ArrayLiteralExp *ae = new ArrayLiteralExp(exp->loc, elements); -+ ae->type = t; -+ exp = ae; -+ } -+ } - return exp; - } - ---- a/src/gcc/d/dfrontend/init.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/init.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2007 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -16,28 +16,28 @@ - #include "mars.h" - #include "arraytypes.h" - --struct Identifier; --struct Expression; -+class Identifier; -+class Expression; - struct Scope; --struct Type; -- -+class Type; - #ifdef IN_GCC - typedef union tree_node dt_t; - #else - struct dt_t; - #endif -- --struct AggregateDeclaration; --struct VoidInitializer; --struct StructInitializer; --struct ArrayInitializer; --struct ExpInitializer; -+class AggregateDeclaration; -+class ErrorInitializer; -+class VoidInitializer; -+class StructInitializer; -+class ArrayInitializer; -+class ExpInitializer; - struct HdrGenState; - - enum NeedInterpret { INITnointerpret, INITinterpret }; - --struct Initializer : Object -+class Initializer : public RootObject - { -+public: - Loc loc; - - Initializer(Loc loc); -@@ -45,7 +45,7 @@ struct Initializer : Object - // needInterpret is INITinterpret if must be a manifest constant, 0 if not. - virtual Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret); - virtual Type *inferType(Scope *sc); -- virtual Expression *toExpression() = 0; -+ virtual Expression *toExpression(Type *t = NULL) = 0; - virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0; - char *toChars(); - -@@ -53,20 +53,22 @@ struct Initializer : Object - - virtual dt_t *toDt(); - -- virtual VoidInitializer *isVoidInitializer() { return NULL; } -+ virtual ErrorInitializer *isErrorInitializer() { return NULL; } -+ virtual VoidInitializer *isVoidInitializer() { return NULL; } - virtual StructInitializer *isStructInitializer() { return NULL; } -- virtual ArrayInitializer *isArrayInitializer() { return NULL; } -- virtual ExpInitializer *isExpInitializer() { return NULL; } -+ virtual ArrayInitializer *isArrayInitializer() { return NULL; } -+ virtual ExpInitializer *isExpInitializer() { return NULL; } - }; - --struct VoidInitializer : Initializer -+class VoidInitializer : public Initializer - { -+public: - Type *type; // type that this will initialize to - - VoidInitializer(Loc loc); - Initializer *syntaxCopy(); - Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret); -- Expression *toExpression(); -+ Expression *toExpression(Type *t = NULL); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - dt_t *toDt(); -@@ -74,19 +76,29 @@ struct VoidInitializer : Initializer - virtual VoidInitializer *isVoidInitializer() { return this; } - }; - --struct StructInitializer : Initializer -+class ErrorInitializer : public Initializer -+{ -+public: -+ ErrorInitializer(); -+ Initializer *syntaxCopy(); -+ Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret); -+ Expression *toExpression(Type *t = NULL); -+ void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -+ -+ virtual ErrorInitializer *isErrorInitializer() { return this; } -+}; -+ -+class StructInitializer : public Initializer - { -+public: - Identifiers field; // of Identifier *'s - Initializers value; // parallel array of Initializer *'s - -- VarDeclarations vars; // parallel array of VarDeclaration *'s -- AggregateDeclaration *ad; // which aggregate this is for -- - StructInitializer(Loc loc); - Initializer *syntaxCopy(); - void addInit(Identifier *field, Initializer *value); - Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret); -- Expression *toExpression(); -+ Expression *toExpression(Type *t = NULL); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - dt_t *toDt(); -@@ -94,8 +106,9 @@ struct StructInitializer : Initializer - StructInitializer *isStructInitializer() { return this; } - }; - --struct ArrayInitializer : Initializer -+class ArrayInitializer : public Initializer - { -+public: - Expressions index; // indices - Initializers value; // of Initializer *'s - size_t dim; // length of array being initialized -@@ -108,7 +121,7 @@ struct ArrayInitializer : Initializer - Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret); - int isAssociativeArray(); - Type *inferType(Scope *sc); -- Expression *toExpression(); -+ Expression *toExpression(Type *t = NULL); - Expression *toAssocArrayLiteral(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - -@@ -117,8 +130,9 @@ struct ArrayInitializer : Initializer - ArrayInitializer *isArrayInitializer() { return this; } - }; - --struct ExpInitializer : Initializer -+class ExpInitializer : public Initializer - { -+public: - Expression *exp; - int expandTuples; - -@@ -126,7 +140,7 @@ struct ExpInitializer : Initializer - Initializer *syntaxCopy(); - Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret); - Type *inferType(Scope *sc); -- Expression *toExpression(); -+ Expression *toExpression(Type *t = NULL); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - dt_t *toDt(); ---- a/src/gcc/d/dfrontend/inline.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/inline.c 2014-04-01 16:32:51.000000000 +0100 -@@ -213,7 +213,7 @@ int VarExp::inlineCost3(InlineCostState - if (tb->ty == Tstruct) - { - StructDeclaration *sd = ((TypeStruct *)tb)->sym; -- if (sd->isnested) -+ if (sd->isNested()) - /* An inner struct will be nested inside another function hierarchy than where - * we're inlining into, so don't inline it. - * At least not until we figure out how to 'move' the struct to be nested -@@ -246,7 +246,7 @@ int StructLiteralExp::inlineCost3(Inline - { - //printf("StructLiteralExp::inlineCost3() %s\n", toChars()); - #if DMDV2 -- if (sd->isnested) -+ if (sd->isNested()) - return COST_MAX; - #endif - return 1; -@@ -280,7 +280,7 @@ int DeclarationExp::inlineCost3(InlineCo - return COST_MAX; // finish DeclarationExp::doInline - #else - for (size_t i = 0; i < td->objects->dim; i++) -- { Object *o = (*td->objects)[i]; -+ { RootObject *o = (*td->objects)[i]; - if (o->dyncast() != DYNCAST_EXPRESSION) - return COST_MAX; - Expression *eo = (Expression *)o; -@@ -577,7 +577,7 @@ Expression *IfStatement::doInline(Inline - Expression *ReturnStatement::doInline(InlineDoState *ids) - { - //printf("ReturnStatement::doInline() '%s'\n", exp ? exp->toChars() : ""); -- return exp ? exp->doInline(ids) : 0; -+ return exp ? exp->doInline(ids) : NULL; - } - - #if DMDV2 -@@ -648,11 +648,69 @@ Expression *VarExp::doInline(InlineDoSta - } - } - if (ids->fd && var == ids->fd->vthis) -- { VarExp *ve = new VarExp(loc, ids->vthis); -+ { -+ VarExp *ve = new VarExp(loc, ids->vthis); - ve->type = type; - return ve; - } - -+ /* Inlining context pointer access for nested referenced variables. -+ * For example: -+ * auto fun() { -+ * int i = 40; -+ * auto foo() { -+ * int g = 2; -+ * struct Result { -+ * auto bar() { return i + g; } -+ * } -+ * return Result(); -+ * } -+ * return foo(); -+ * } -+ * auto t = fun(); -+ * 'i' and 'g' are nested referenced variables in Result.bar(), so: -+ * auto x = t.bar(); -+ * should be inlined to: -+ * auto x = *(t.vthis.vthis + i->voffset) + *(t.vthis + g->voffset) -+ */ -+ VarDeclaration *v = var->isVarDeclaration(); -+ if (v && v->nestedrefs.dim && ids->vthis) -+ { -+ Dsymbol *s = ids->fd; -+ FuncDeclaration *fdv = v->toParent()->isFuncDeclaration(); -+ assert(fdv); -+ Expression *ve = new VarExp(loc, ids->vthis); -+ ve->type = ids->vthis->type; -+ while (s != fdv) -+ { -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ if (AggregateDeclaration *ad = s->isThis()) -+ { -+ assert(ad->vthis); -+ ve = new DotVarExp(loc, ve, ad->vthis); -+ ve->type = ad->vthis->type; -+ s = ad->toParent2(); -+ } -+ else if (f && f->isNested()) -+ { -+ assert(f->vthis); -+ if (f->hasNestedFrameRefs()) -+ { -+ ve = new DotVarExp(loc, ve, f->vthis); -+ ve->type = f->vthis->type; -+ } -+ s = f->toParent2(); -+ } -+ else -+ assert(0); -+ assert(s); -+ } -+ ve = new DotVarExp(loc, ve, v); -+ ve->type = v->type; -+ //printf("\t==> ve = %s, type = %s\n", ve->toChars(), ve->type->toChars()); -+ return ve; -+ } -+ - return this; - } - -@@ -707,7 +765,7 @@ Expression *DeclarationExp::doInline(Inl - VarDeclaration *vto; - - vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); -- *vto = *vd; -+ memcpy((void*)vto, (void*)vd, sizeof(VarDeclaration)); - vto->parent = ids->parent; - vto->csym = NULL; - vto->isym = NULL; -@@ -801,7 +859,7 @@ Expression *IndexExp::doInline(InlineDoS - VarDeclaration *vto; - - vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); -- *vto = *vd; -+ memcpy((void*)vto, (void*)vd, sizeof(VarDeclaration)); - vto->parent = ids->parent; - vto->csym = NULL; - vto->isym = NULL; -@@ -838,7 +896,7 @@ Expression *SliceExp::doInline(InlineDoS - VarDeclaration *vto; - - vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); -- *vto = *vd; -+ memcpy((void*)vto, (void*)vd, sizeof(VarDeclaration)); - vto->parent = ids->parent; - vto->csym = NULL; - vto->isym = NULL; -@@ -869,6 +927,8 @@ Expression *TupleExp::doInline(InlineDoS - TupleExp *ce; - - ce = (TupleExp *)copy(); -+ if (e0) -+ ce->e0 = e0->doInline(ids); - ce->exps = arrayExpressiondoInline(exps, ids); - return ce; - } -@@ -897,10 +957,12 @@ Expression *AssocArrayLiteralExp::doInli - - Expression *StructLiteralExp::doInline(InlineDoState *ids) - { -+ if(inlinecopy) return inlinecopy; - StructLiteralExp *ce; -- - ce = (StructLiteralExp *)copy(); -+ inlinecopy = ce; - ce->elements = arrayExpressiondoInline(elements, ids); -+ inlinecopy = NULL; - return ce; - } - -@@ -1106,12 +1168,7 @@ Statement *ReturnStatement::inlineScan(I - { - //printf("ReturnStatement::inlineScan()\n"); - if (exp) -- { - exp = exp->inlineScan(iss); -- -- FuncDeclaration *func = iss->fd; -- TypeFunction *tf = (TypeFunction *)(func->type); -- } - return this; - } - -@@ -1203,6 +1260,7 @@ Expression *Expression::inlineScan(Inlin - - void scanVar(Dsymbol *s, InlineScanState *iss) - { -+ //printf("scanVar(%s %s)\n", s->kind(), s->toPrettyChars()); - VarDeclaration *vd = s->isVarDeclaration(); - if (vd) - { -@@ -1254,6 +1312,10 @@ void scanVar(Dsymbol *s, InlineScanState - } - } - } -+ else -+ { -+ s->inlineScan(); -+ } - } - - Expression *DeclarationExp::inlineScan(InlineScanState *iss) -@@ -1342,6 +1404,8 @@ Expression *TupleExp::inlineScan(InlineS - { Expression *e = this; - - //printf("TupleExp::inlineScan()\n"); -+ if (e0) -+ e0->inlineScan(iss); - arrayInlineScan(iss, exps); - - return e; -@@ -1373,8 +1437,11 @@ Expression *StructLiteralExp::inlineScan - { Expression *e = this; - - //printf("StructLiteralExp::inlineScan()\n"); -+ if(stageflags & stageInlineScan) return e; -+ int old = stageflags; -+ stageflags |= stageInlineScan; - arrayInlineScan(iss, elements); -- -+ stageflags = old; - return e; - } - -@@ -1406,7 +1473,7 @@ void FuncDeclaration::inlineScan() - InlineScanState iss; - - #if LOG -- printf("FuncDeclaration::inlineScan('%s')\n", toChars()); -+ printf("FuncDeclaration::inlineScan('%s')\n", toPrettyChars()); - #endif - memset(&iss, 0, sizeof(iss)); - iss.fd = this; -@@ -1426,7 +1493,7 @@ int FuncDeclaration::canInline(int hasth - #define CANINLINE_LOG 0 - - #if CANINLINE_LOG -- printf("FuncDeclaration::canInline(hasthis = %d, statementsToo = %d, '%s')\n", hasthis, statementsToo, toChars()); -+ printf("FuncDeclaration::canInline(hasthis = %d, statementsToo = %d, '%s')\n", hasthis, statementsToo, toPrettyChars()); - #endif - - if (needThis() && !hasthis) -@@ -1465,7 +1532,7 @@ int FuncDeclaration::canInline(int hasth - - if (type) - { assert(type->ty == Tfunction); -- TypeFunction *tf = (TypeFunction *)(type); -+ TypeFunction *tf = (TypeFunction *)type; - if (tf->varargs == 1) // no variadic parameter lists - goto Lno; - -@@ -1496,7 +1563,7 @@ int FuncDeclaration::canInline(int hasth - isSynchronized() || - isImportedSymbol() || - hasNestedFrameRefs() || // no nested references to this frame -- (isVirtual() && !isFinal()) -+ (isVirtual() && !isFinalFunc()) - )) - { - goto Lno; -@@ -1637,7 +1704,7 @@ Expression *FuncDeclaration::expandInlin - // Set up parameters - if (ethis) - { -- e = new DeclarationExp(0, ids.vthis); -+ e = new DeclarationExp(Loc(), ids.vthis); - e->type = Type::tvoid; - if (as) - as->push(new ExpStatement(e->loc, e)); -@@ -1677,11 +1744,11 @@ Expression *FuncDeclaration::expandInlin - ids.from.push(vfrom); - ids.to.push(vto); - -- de = new DeclarationExp(0, vto); -+ de = new DeclarationExp(Loc(), vto); - de->type = Type::tvoid; - - if (as) -- as->push(new ExpStatement(0, de)); -+ as->push(new ExpStatement(Loc(), de)); - else - e = Expression::combine(e, de); - } -@@ -1692,7 +1759,7 @@ Expression *FuncDeclaration::expandInlin - inlineNest++; - Statement *s = fbody->doInlineStatement(&ids); - as->push(s); -- *ps = new ScopeStatement(0, new CompoundStatement(0, as)); -+ *ps = new ScopeStatement(Loc(), new CompoundStatement(Loc(), as)); - inlineNest--; - } - else -@@ -1705,6 +1772,7 @@ Expression *FuncDeclaration::expandInlin - //eb->print(); - //eb->dump(0); - } -+ //printf("%s->expandInline = { %s }\n", toChars(), e->toChars()); - - /* There's a problem if what the function returns is used subsequently as an - * lvalue, as in a struct return that is then used as a 'this'. -@@ -1736,7 +1804,7 @@ Expression *FuncDeclaration::expandInlin - ei->exp = new ConstructExp(loc, ve, e); - ei->exp->type = ve->type; - -- DeclarationExp* de = new DeclarationExp(0, vd); -+ DeclarationExp* de = new DeclarationExp(Loc(), vd); - de->type = Type::tvoid; - - // Chain the two together: ---- a/src/gcc/d/dfrontend/interpret.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/interpret.c 2014-04-01 16:32:51.000000000 +0100 -@@ -37,6 +37,7 @@ - - #define LOG 0 - #define LOGASSIGN 0 -+#define LOGCOMPILE 0 - #define SHOWPERFORMANCE 0 - - // Maximum allowable recursive function calls in CTFE -@@ -57,28 +58,36 @@ private: - the stack might not be empty when CTFE begins. - - Ctfe Stack addresses are just 0-based integers, but we save -- them as 'void *' because ArrayBase can only do pointers. -+ them as 'void *' because Array can only do pointers. - */ - Expressions values; // values on the stack - VarDeclarations vars; // corresponding variables -- ArrayBase savedId; // id of the previous state of that var -+ Array savedId; // id of the previous state of that var -+ -+ Array frames; // all previous frame pointers -+ Expressions savedThis; // all previous values of localThis - - /* Global constants get saved here after evaluation, so we never - * have to redo them. This saves a lot of time and memory. - */ - Expressions globalValues; // values of global constants -- size_t framepointer; // current frame pointer -- size_t maxStackPointer; // most stack we've ever used -+ -+ size_t framepointer; // current frame pointer -+ size_t maxStackPointer; // most stack we've ever used -+ Expression *localThis; // value of 'this', or NULL if none - public: - CtfeStack(); - - size_t stackPointer(); - -+ // The current value of 'this', or NULL if none -+ Expression *getThis(); -+ - // Largest number of stack positions we've used - size_t maxStackUsage(); -- // return the previous frame -- size_t startFrame(); -- void endFrame(size_t oldframe); -+ // Start a new stack frame, using the provided 'this'. -+ void startFrame(Expression *thisexp); -+ void endFrame(); - bool isInCurrentFrame(VarDeclaration *v); - Expression *getValue(VarDeclaration *v); - void setValue(VarDeclaration *v, Expression *e); -@@ -92,13 +101,11 @@ struct InterState - { - InterState *caller; // calling function's InterState - FuncDeclaration *fd; // function being interpreted -- size_t framepointer; // frame pointer of previous frame - Statement *start; // if !=NULL, start execution at this statement - Statement *gotoTarget; /* target of EXP_GOTO_INTERPRET result; also - * target of labelled EXP_BREAK_INTERPRET or - * EXP_CONTINUE_INTERPRET. (NULL if no label). - */ -- Expression *localThis; // value of 'this', or NULL if none - bool awaitingLvalueReturn; // Support for ref return values: - // Any return to this function should return an lvalue. - InterState(); -@@ -117,24 +124,34 @@ size_t CtfeStack::stackPointer() - return values.dim; - } - -+Expression *CtfeStack::getThis() -+{ -+ return localThis; -+} -+ - // Largest number of stack positions we've used - size_t CtfeStack::maxStackUsage() - { - return maxStackPointer; - } - --// return the previous frame --size_t CtfeStack::startFrame() -+void CtfeStack::startFrame(Expression *thisexp) - { - size_t oldframe = framepointer; -+ frames.push((void *)(size_t)(framepointer)); -+ savedThis.push(localThis); - framepointer = stackPointer(); -- return oldframe; -+ localThis = thisexp; - } - --void CtfeStack::endFrame(size_t oldframe) -+void CtfeStack::endFrame() - { -+ size_t oldframe = (size_t)(frames[frames.dim-1]); -+ localThis = savedThis[savedThis.dim-1]; - popAll(framepointer); - framepointer = oldframe; -+ frames.setDim(frames.dim - 1); -+ savedThis.setDim(savedThis.dim -1); - } - - bool CtfeStack::isInCurrentFrame(VarDeclaration *v) -@@ -244,13 +261,438 @@ void printCtfePerformanceStats() - } - - --Expression * resolveReferences(Expression *e, Expression *thisval); -+Expression * resolveReferences(Expression *e); - Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal); --VarDeclaration *findParentVar(Expression *e, Expression *thisval); -+VarDeclaration *findParentVar(Expression *e); - Expression *evaluateIfBuiltin(InterState *istate, Loc loc, - FuncDeclaration *fd, Expressions *arguments, Expression *pthis); - Expression *scrubReturnValue(Loc loc, Expression *e); - -+ -+ -+/************************************* -+ * CTFE-object code for a single function -+ * -+ * Currently only counts the number of local variables in the function -+ */ -+struct CompiledCtfeFunction -+{ -+ FuncDeclaration *func; // Function being compiled, NULL if global scope -+ int numVars; // Number of variables declared in this function -+ Loc callingloc; -+ -+ CompiledCtfeFunction(FuncDeclaration *f) -+ { -+ func = f; -+ numVars = 0; -+ } -+ -+ void onDeclaration(VarDeclaration *v) -+ { -+ //printf("%s CTFE declare %s\n", v->loc.toChars(), v->toChars()); -+ ++numVars; -+ } -+ static int walkAllVars(Expression *e, void *_this); -+ void onExpression(Expression *e) -+ { -+ e->apply(&walkAllVars, this); -+ } -+}; -+ -+int CompiledCtfeFunction::walkAllVars(Expression *e, void *_this) -+{ -+ CompiledCtfeFunction *ccf = (CompiledCtfeFunction *)_this; -+ if (e->op == TOKerror) -+ { -+ // Currently there's a front-end bug: silent errors -+ // can occur inside delegate literals inside is(typeof()). -+ // Suppress the check in this case. -+ if (global.gag && ccf->func) -+ return 1; -+ -+ e->error("CTFE internal error: ErrorExp in %s\n", ccf->func ? ccf->func->loc.toChars() : ccf->callingloc.toChars()); -+ assert(0); -+ } -+ if (e->op == TOKdeclaration) -+ { -+ DeclarationExp *decl = (DeclarationExp *)e; -+ VarDeclaration *v = decl->declaration->isVarDeclaration(); -+ if (!v) -+ return 0; -+ TupleDeclaration *td = v->toAlias()->isTupleDeclaration(); -+ if (td) -+ { -+ if (!td->objects) -+ return 0; -+ for(size_t i= 0; i < td->objects->dim; ++i) -+ { -+ RootObject *o = td->objects->tdata()[i]; -+ Expression *ex = isExpression(o); -+ DsymbolExp *s = (ex && ex->op == TOKdsymbol) ? (DsymbolExp *)ex : NULL; -+ assert(s); -+ VarDeclaration *v2 = s->s->isVarDeclaration(); -+ assert(v2); -+ if (!v2->isDataseg() || v2->isCTFE()) -+ ccf->onDeclaration(v2); -+ } -+ } -+ else if (!(v->isDataseg() || v->storage_class & STCmanifest) || v->isCTFE()) -+ ccf->onDeclaration(v); -+ Dsymbol *s = v->toAlias(); -+ if (s == v && !v->isStatic() && v->init) -+ { -+ ExpInitializer *ie = v->init->isExpInitializer(); -+ if (ie) -+ ccf->onExpression(ie->exp); -+ } -+ } -+ else if (e->op == TOKindex && ((IndexExp *)e)->lengthVar) -+ ccf->onDeclaration( ((IndexExp *)e)->lengthVar); -+ else if (e->op == TOKslice && ((SliceExp *)e)->lengthVar) -+ ccf->onDeclaration( ((SliceExp *)e)->lengthVar); -+ return 0; -+} -+ -+void Statement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s Statement::ctfeCompile %s\n", loc.toChars(), toChars()); -+#endif -+ assert(0); -+} -+ -+void ExpStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ExpStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (exp) -+ ccf->onExpression(exp); -+} -+ -+void CompoundStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s CompoundStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ for (size_t i = 0; i < statements->dim; i++) -+ { Statement *s = (*statements)[i]; -+ if (s) -+ s->ctfeCompile(ccf); -+ } -+} -+ -+void UnrolledLoopStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s UnrolledLoopStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ for (size_t i = 0; i < statements->dim; i++) -+ { Statement *s = (*statements)[i]; -+ if (s) -+ s->ctfeCompile(ccf); -+ } -+} -+ -+void IfStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s IfStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ -+ ccf->onExpression(condition); -+ if (ifbody) -+ ifbody->ctfeCompile(ccf); -+ if (elsebody) -+ elsebody->ctfeCompile(ccf); -+} -+ -+void ScopeStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ScopeStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (statement) -+ statement->ctfeCompile(ccf); -+} -+ -+void OnScopeStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s OnScopeStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // rewritten to try/catch/finally -+ assert(0); -+} -+ -+void DoStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s DoStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ ccf->onExpression(condition); -+ if (body) -+ body->ctfeCompile(ccf); -+} -+ -+void WhileStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s WhileStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // rewritten to ForStatement -+ assert(0); -+} -+ -+void ForStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ForStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ -+ if (init) -+ init->ctfeCompile(ccf); -+ if (condition) -+ ccf->onExpression(condition); -+ if (increment) -+ ccf->onExpression(increment); -+ if (body) -+ body->ctfeCompile(ccf); -+} -+ -+void ForeachStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ForeachStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // rewritten for ForStatement -+ assert(0); -+} -+ -+ -+void SwitchStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s SwitchStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ ccf->onExpression(condition); -+ // Note that the body contains the the Case and Default -+ // statements, so we only need to compile the expressions -+ for (size_t i = 0; i < cases->dim; i++) -+ { -+ ccf->onExpression((*cases)[i]->exp); -+ } -+ if (body) -+ body->ctfeCompile(ccf); -+} -+ -+void CaseStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s CaseStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (statement) -+ statement->ctfeCompile(ccf); -+} -+ -+void DefaultStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s DefaultStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (statement) -+ statement->ctfeCompile(ccf); -+} -+ -+void GotoDefaultStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s GotoDefaultStatement::ctfeCompile\n", loc.toChars()); -+#endif -+} -+ -+void GotoCaseStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s GotoCaseStatement::ctfeCompile\n", loc.toChars()); -+#endif -+} -+ -+void SwitchErrorStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s SwitchErrorStatement::ctfeCompile\n", loc.toChars()); -+#endif -+} -+ -+void ReturnStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ReturnStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (exp) -+ ccf->onExpression(exp); -+} -+ -+void BreakStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s BreakStatement::ctfeCompile\n", loc.toChars()); -+#endif -+} -+ -+void ContinueStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ContinueStatement::ctfeCompile\n", loc.toChars()); -+#endif -+} -+ -+void WithStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s WithStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // If it is with(Enum) {...}, just execute the body. -+ if (exp->op == TOKimport || exp->op == TOKtype) -+ {} -+ else -+ { -+ ccf->onDeclaration(wthis); -+ ccf->onExpression(exp); -+ } -+ if (body) -+ body->ctfeCompile(ccf); -+} -+ -+void TryCatchStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s TryCatchStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (body) -+ body->ctfeCompile(ccf); -+ for (size_t i = 0; i < catches->dim; i++) -+ { -+#if DMDV1 -+ Catch *ca = (Catch *)catches->data[i]; -+#else -+ Catch *ca = catches->tdata()[i]; -+#endif -+ if (ca->var) -+ ccf->onDeclaration(ca->var); -+ if (ca->handler) -+ ca->handler->ctfeCompile(ccf); -+ } -+} -+ -+void TryFinallyStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s TryFinallyStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (body) -+ body->ctfeCompile(ccf); -+ if (finalbody) -+ finalbody->ctfeCompile(ccf); -+} -+ -+void ThrowStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ThrowStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ ccf->onExpression(exp); -+} -+ -+void GotoStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s GotoStatement::ctfeCompile\n", loc.toChars()); -+#endif -+} -+ -+void LabelStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s LabelStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ if (statement) -+ statement->ctfeCompile(ccf); -+} -+ -+#if DMDV2 -+void ImportStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ImportStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // Contains no variables or executable code -+} -+ -+void ForeachRangeStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s ForeachRangeStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // rewritten for ForStatement -+ assert(0); -+} -+ -+#endif -+ -+void AsmStatement::ctfeCompile(CompiledCtfeFunction *ccf) -+{ -+#if LOGCOMPILE -+ printf("%s AsmStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // we can't compile asm statements -+} -+ -+#ifdef IN_GCC -+// CTFE compile extended asm statement. -+ -+void -+ExtAsmStatement::ctfeCompile (CompiledCtfeFunction *) -+{ -+#if LOGCOMPILE -+ printf("%s ExtAsmStatement::ctfeCompile\n", loc.toChars()); -+#endif -+ // We can't compile extended asm statements. -+} -+#endif -+ -+/************************************* -+ * Compile this function for CTFE. -+ * At present, this merely allocates variables. -+ */ -+void FuncDeclaration::ctfeCompile() -+{ -+#if LOGCOMPILE -+ printf("\n%s FuncDeclaration::ctfeCompile %s\n", loc.toChars(), toChars()); -+#endif -+ assert(!ctfeCode); -+ assert(!semantic3Errors); -+ assert(semanticRun == PASSsemantic3done); -+ -+ ctfeCode = new CompiledCtfeFunction(this); -+ if (parameters) -+ { -+ Type *tb = type->toBasetype(); -+ assert(tb->ty == Tfunction); -+ TypeFunction *tf = (TypeFunction *)tb; -+ for (size_t i = 0; i < parameters->dim; i++) -+ { -+ Parameter *arg = Parameter::getNth(tf->parameters, i); -+ VarDeclaration *v = (*parameters)[i]; -+ ctfeCode->onDeclaration(v); -+ } -+ } -+ if (vresult) -+ ctfeCode->onDeclaration(vresult); -+ fbody->ctfeCompile(ctfeCode); -+} -+ - /************************************* - * - * Entry point for CTFE. -@@ -258,9 +700,75 @@ Expression *scrubReturnValue(Loc loc, Ex - */ - Expression *Expression::ctfeInterpret() - { -- return optimize(WANTvalue | WANTinterpret); -+ if (type == Type::terror) -+ return this; -+ -+ // This code is outside a function, but still needs to be compiled -+ // (there are compiler-generated temporary variables such as __dollar). -+ // However, this will only be run once and can then be discarded. -+ CompiledCtfeFunction ctfeCodeGlobal(NULL); -+ ctfeCodeGlobal.callingloc = loc; -+ ctfeCodeGlobal.onExpression(this); -+ -+ Expression *e = interpret(NULL); -+ if (e != EXP_CANT_INTERPRET) -+ e = scrubReturnValue(loc, e); -+ if (e == EXP_CANT_INTERPRET) -+ e = new ErrorExp(); -+ return e; -+} -+ -+/* Run CTFE on the expression, but allow the expression to be a TypeExp -+ * or a tuple containing a TypeExp. (This is required by pragma(msg)). -+ */ -+Expression *ctfeInterpretForPragmaMsg(Expression *e) -+{ -+ if (e->op == TOKerror || e->op == TOKtype) -+ return e; -+ -+ // It's also OK for it to be a function declaration (happens only with -+ // __traits(getOverloads)) -+ if (e->op == TOKvar && ((VarExp *)e)->var->isFuncDeclaration()) -+ { -+ return e; -+ } -+ -+ if (e->op != TOKtuple) -+ return e->ctfeInterpret(); -+ -+ // Tuples need to be treated seperately, since they are -+ // allowed to contain a TypeExp in this case. -+ -+ TupleExp *tup = (TupleExp *)e; -+ Expressions *expsx = NULL; -+ for (size_t i = 0; i < tup->exps->dim; ++i) -+ { -+ Expression *g = (*tup->exps)[i]; -+ Expression *h = g; -+ h = ctfeInterpretForPragmaMsg(g); -+ if (h != g) -+ { -+ if (!expsx) -+ { -+ expsx = new Expressions(); -+ expsx->setDim(tup->exps->dim); -+ for (size_t j = 0; j < tup->exps->dim; j++) -+ (*expsx)[j] = (*tup->exps)[j]; -+ } -+ (*expsx)[i] = h; -+ } -+ } -+ if (expsx) -+ { -+ TupleExp *te = new TupleExp(e->loc, expsx); -+ expandTuples(te->exps); -+ te->type = new TypeTuple(te->exps); -+ return te; -+ } -+ return e; - } - -+ - /************************************* - * Attempt to interpret a function given the arguments. - * Input: -@@ -287,10 +795,13 @@ Expression *FuncDeclaration::interpret(I - if (semanticRun < PASSsemantic3done) - return EXP_CANT_INTERPRET; - -+ // CTFE-compile the function -+ if (!ctfeCode) -+ ctfeCompile(); -+ - Type *tb = type->toBasetype(); - assert(tb->ty == Tfunction); - TypeFunction *tf = (TypeFunction *)tb; -- Type *tret = tf->next->toBasetype(); - if (tf->varargs && arguments && - ((parameters && arguments->dim != parameters->dim) || (!parameters && arguments->dim))) - { -@@ -303,15 +814,8 @@ Expression *FuncDeclaration::interpret(I - // Func literals report isNested() even if they are in global scope, - // so we need to check that the parent is a function. - if (isNested() && toParent2()->isFuncDeclaration() && !thisarg && istate) -- thisarg = istate->localThis; -+ thisarg = ctfeStack.getThis(); - -- InterState istatex; -- istatex.caller = istate; -- istatex.fd = this; -- istatex.localThis = thisarg; -- istatex.framepointer = ctfeStack.startFrame(); -- -- Expressions vsave; // place to save previous parameter values - size_t dim = 0; - if (needThis() && !thisarg) - { // error, no this. Prevent segfault. -@@ -324,16 +828,19 @@ Expression *FuncDeclaration::interpret(I - return EXP_CANT_INTERPRET; - } - static int evaluatingArgs = 0; -+ -+ // Place to hold all the arguments to the function while -+ // we are evaluating them. -+ Expressions eargs; -+ - if (arguments) - { - dim = arguments->dim; - assert(!dim || (parameters && (parameters->dim == dim))); -- vsave.setDim(dim); - - /* Evaluate all the arguments to the function, - * store the results in eargs[] - */ -- Expressions eargs; - eargs.setDim(dim); - for (size_t i = 0; i < dim; i++) - { Expression *earg = (*arguments)[i]; -@@ -391,6 +898,18 @@ Expression *FuncDeclaration::interpret(I - } - eargs[i] = earg; - } -+ } -+ -+ // Now that we've evaluated all the arguments, we can start the frame -+ // (this is the moment when the 'call' actually takes place). -+ -+ InterState istatex; -+ istatex.caller = istate; -+ istatex.fd = this; -+ ctfeStack.startFrame(thisarg); -+ -+ if (arguments) -+ { - - for (size_t i = 0; i < dim; i++) - { Expression *earg = eargs[i]; -@@ -475,7 +994,7 @@ Expression *FuncDeclaration::interpret(I - // Leave the function - --CtfeStatus::callDepth; - -- ctfeStack.endFrame(istatex.framepointer); -+ ctfeStack.endFrame(); - - // If fell off the end of a void function, return void - if (!e && type->toBasetype()->nextOf()->ty == Tvoid) -@@ -494,12 +1013,6 @@ Expression *FuncDeclaration::interpret(I - return EXP_CANT_INTERPRET; - } - -- // If we're about to leave CTFE, make sure we don't crash the -- // compiler by returning a CTFE-internal expression. -- if (!istate && !evaluatingArgs) -- { -- e = scrubReturnValue(loc, e); -- } - return e; - } - -@@ -682,8 +1195,11 @@ bool stopPointersEscaping(Loc loc, Expre - return true; - if ( isPointer(e->type) ) - { -- if (e->op == TOKvar && ((VarExp *)e)->var->isVarDeclaration() && -- ctfeStack.isInCurrentFrame( ((VarExp *)e)->var->isVarDeclaration() ) ) -+ Expression *x = e; -+ if (e->op == TOKaddress) -+ x = ((AddrExp *)e)->e1; -+ if (x->op == TOKvar && ((VarExp *)x)->var->isVarDeclaration() && -+ ctfeStack.isInCurrentFrame( ((VarExp *)x)->var->isVarDeclaration() ) ) - { error(loc, "returning a pointer to a local stack variable"); - return false; - } -@@ -714,7 +1230,7 @@ bool stopPointersEscapingFromArray(Loc l - { - for (size_t i = 0; i < elems->dim; i++) - { -- Expression *m = elems->tdata()[i]; -+ Expression *m = (*elems)[i]; - if (!m) - continue; - if (m) -@@ -735,8 +1251,16 @@ Expression *scrubReturnValue(Loc loc, Ex - { - if (e->op == TOKclassreference) - { -- error(loc, "%s class literals cannot be returned from CTFE", ((ClassReferenceExp*)e)->originalClass()->toChars()); -- return EXP_CANT_INTERPRET; -+ StructLiteralExp *se = ((ClassReferenceExp*)e)->value; -+ se->ownedByCtfe = false; -+ if (!(se->stageflags & stageScrub)) -+ { -+ int old = se->stageflags; -+ se->stageflags |= stageScrub; -+ if (!scrubArray(loc, se->elements, true)) -+ return EXP_CANT_INTERPRET; -+ se->stageflags = old; -+ } - } - if (e->op == TOKvoid) - { -@@ -751,8 +1275,14 @@ Expression *scrubReturnValue(Loc loc, Ex - { - StructLiteralExp *se = (StructLiteralExp *)e; - se->ownedByCtfe = false; -- if (!scrubArray(loc, se->elements, true)) -- return EXP_CANT_INTERPRET; -+ if (!(se->stageflags & stageScrub)) -+ { -+ int old = se->stageflags; -+ se->stageflags |= stageScrub; -+ if (!scrubArray(loc, se->elements, true)) -+ return EXP_CANT_INTERPRET; -+ se->stageflags = old; -+ } - } - if (e->op == TOKstring) - { -@@ -776,21 +1306,56 @@ Expression *scrubReturnValue(Loc loc, Ex - return e; - } - -+// Return true if every element is either void, -+// or is an array literal or struct literal of void elements. -+bool isEntirelyVoid(Expressions *elems) -+{ -+ for (size_t i = 0; i < elems->dim; i++) -+ { -+ Expression *m = (*elems)[i]; -+ // It can be NULL for performance reasons, -+ // see StructLiteralExp::interpret(). -+ if (!m) -+ continue; -+ -+ if (!(m->op == TOKvoid) && -+ !(m->op == TOKarrayliteral && isEntirelyVoid(((ArrayLiteralExp *)m)->elements)) && -+ !(m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements))) -+ { -+ return false; -+ } -+ } -+ return true; -+} -+ - // Scrub all members of an array. Return false if error - bool scrubArray(Loc loc, Expressions *elems, bool structlit) - { - for (size_t i = 0; i < elems->dim; i++) - { -- Expression *m = elems->tdata()[i]; -+ Expression *m = (*elems)[i]; -+ // It can be NULL for performance reasons, -+ // see StructLiteralExp::interpret(). - if (!m) - continue; -- if (m && m->op == TOKvoid && structlit) -- m = NULL; -- if (m) -+ -+ // A struct .init may contain void members. -+ // Static array members are a weird special case (bug 10994). -+ if (structlit && -+ ((m->op == TOKvoid) || -+ (m->op == TOKarrayliteral && m->type->ty == Tsarray && isEntirelyVoid(((ArrayLiteralExp *)m)->elements)) || -+ (m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements))) -+ ) -+ { -+ m = NULL; -+ } -+ else -+ { - m = scrubReturnValue(loc, m); -- if (m == EXP_CANT_INTERPRET) -- return false; -- elems->tdata()[i] = m; -+ if (m == EXP_CANT_INTERPRET) -+ return false; -+ } -+ (*elems)[i] = m; - } - return true; - } -@@ -835,21 +1400,19 @@ Expression *ReturnStatement::interpret(I - { e = exp->interpret(istate, ctfeNeedLvalue); - if (exceptionOrCantInterpret(e)) - return e; -- // Disallow returning pointers to stack-allocated variables (bug 7876) -- if (e->op == TOKvar && ((VarExp *)e)->var->isVarDeclaration() && -- ctfeStack.isInCurrentFrame( ((VarExp *)e)->var->isVarDeclaration() ) ) -- { error("returning a pointer to a local stack variable"); -- return EXP_CANT_INTERPRET; -- } - } - else - { - e = exp->interpret(istate); - if (exceptionOrCantInterpret(e)) - return e; -- if (!stopPointersEscaping(loc, e)) -- return EXP_CANT_INTERPRET; - } -+ -+ // Disallow returning pointers to stack-allocated variables (bug 7876) -+ -+ if (!stopPointersEscaping(loc, e)) -+ return EXP_CANT_INTERPRET; -+ - if (needToCopyLiteral(e)) - e = copyLiteral(e); - #if LOGASSIGN -@@ -866,13 +1429,19 @@ Expression *BreakStatement::interpret(In - #endif - START() - if (ident) -- { LabelDsymbol *label = istate->fd->searchLabel(ident); -+ { -+ LabelDsymbol *label = istate->fd->searchLabel(ident); - assert(label && label->statement); -- Statement *s = label->statement; -- if (s->isLabelStatement()) -- s = s->isLabelStatement()->statement; -- if (s->isScopeStatement()) -- s = s->isScopeStatement()->statement; -+ LabelStatement *ls = label->statement; -+ Statement *s; -+ if (ls->gotoTarget) -+ s = ls->gotoTarget; -+ else -+ { -+ s = ls->statement; -+ if (s->isScopeStatement()) -+ s = s->isScopeStatement()->statement; -+ } - istate->gotoTarget = s; - return EXP_BREAK_INTERPRET; - } -@@ -890,13 +1459,19 @@ Expression *ContinueStatement::interpret - #endif - START() - if (ident) -- { LabelDsymbol *label = istate->fd->searchLabel(ident); -+ { -+ LabelDsymbol *label = istate->fd->searchLabel(ident); - assert(label && label->statement); -- Statement *s = label->statement; -- if (s->isLabelStatement()) -- s = s->isLabelStatement()->statement; -- if (s->isScopeStatement()) -- s = s->isScopeStatement()->statement; -+ LabelStatement *ls = label->statement; -+ Statement *s; -+ if (ls->gotoTarget) -+ s = ls->gotoTarget; -+ else -+ { -+ s = ls->statement; -+ if (s->isScopeStatement()) -+ s = s->isScopeStatement()->statement; -+ } - istate->gotoTarget = s; - return EXP_CONTINUE_INTERPRET; - } -@@ -944,7 +1519,6 @@ Expression *DoStatement::interpret(Inter - if (istate->gotoTarget && istate->gotoTarget != this) - break; // continue at a higher level - -- Lcontinue: - istate->gotoTarget = NULL; - e = condition->interpret(istate); - if (exceptionOrCantInterpret(e)) -@@ -1206,7 +1780,7 @@ Expression *TryCatchStatement::interpret - #if DMDV1 - Catch *ca = (Catch *)catches->data[i]; - #else -- Catch *ca = catches->tdata()[i]; -+ Catch *ca = (*catches)[i]; - #endif - Type *catype = ca->type; - -@@ -1236,20 +1810,20 @@ ThrownExceptionExp *chainExceptions(Thro - #if DMDV2 - // Little sanity check to make sure it's really a Throwable - ClassReferenceExp *boss = oldest->thrown; -- assert(boss->value->elements->tdata()[4]->type->ty == Tclass); -+ assert((*boss->value->elements)[4]->type->ty == Tclass); - ClassReferenceExp *collateral = newest->thrown; - if (isAnErrorException(collateral->originalClass()) - && !isAnErrorException(boss->originalClass())) - { // The new exception bypass the existing chain -- assert(collateral->value->elements->tdata()[5]->type->ty == Tclass); -- collateral->value->elements->tdata()[5] = boss; -+ assert((*collateral->value->elements)[5]->type->ty == Tclass); -+ (*collateral->value->elements)[5] = boss; - return newest; - } -- while (boss->value->elements->tdata()[4]->op == TOKclassreference) -+ while ((*boss->value->elements)[4]->op == TOKclassreference) - { -- boss = (ClassReferenceExp *)(boss->value->elements->tdata()[4]); -+ boss = (ClassReferenceExp *)(*boss->value->elements)[4]; - } -- boss->value->elements->tdata()[4] = collateral; -+ (*boss->value->elements)[4] = collateral; - return oldest; - #else - // for D1, the newest exception just clobbers the older one -@@ -1335,6 +1909,18 @@ Expression *AsmStatement::interpret(Inte - return EXP_CANT_INTERPRET; - } - -+#ifdef IN_GCC -+Expression *ExtAsmStatement::interpret(InterState *istate) -+{ -+#if LOG -+ printf("%s ExtAsmStatement::interpret()\n", loc.toChars()); -+#endif -+ START() -+ error("extended asm statements cannot be interpreted at compile time"); -+ return EXP_CANT_INTERPRET; -+} -+#endif -+ - #if DMDV2 - Expression *ImportStatement::interpret(InterState *istate) - { -@@ -1361,12 +1947,11 @@ Expression *Expression::interpret(InterS - - Expression *ThisExp::interpret(InterState *istate, CtfeGoal goal) - { -- while (istate && !istate->localThis) -- istate = istate->caller; -- if (istate && istate->localThis && istate->localThis->op == TOKstructliteral) -- return istate->localThis; -- if (istate && istate->localThis) -- return istate->localThis->interpret(istate, goal); -+ Expression *localThis = ctfeStack.getThis(); -+ if (localThis && localThis->op == TOKstructliteral) -+ return localThis; -+ if (localThis) -+ return localThis->interpret(istate, goal); - error("value of 'this' is not known at compile time"); - return EXP_CANT_INTERPRET; - } -@@ -1407,11 +1992,11 @@ Expression *StringExp::interpret(InterSt - * In D2, we also disallow casts of read-only literals to mutable, - * though it isn't strictly necessary. - */ --#if DMDV2 -+#if 0 //DMDV2 - // Fixed-length char arrays always get duped later anyway. - if (type->ty == Tsarray) - return this; -- if (!(((TypeNext *)type)->next->mod & (MODconst | MODimmutable))) -+ if (!(((TypeNext *)type)->next->toBasetype()->mod & (MODconst | MODimmutable))) - { // It seems this happens only when there has been an explicit cast - error("cannot cast a read-only string literal to mutable in CTFE"); - return EXP_CANT_INTERPRET; -@@ -1437,12 +2022,35 @@ Expression *SymOffExp::interpret(InterSt - { - return this; - } -+ if (isTypeInfo_Class(type) && offset == 0) -+ { -+ return this; -+ } - if (type->ty != Tpointer) - { // Probably impossible - error("Cannot interpret %s at compile time", toChars()); - return EXP_CANT_INTERPRET; - } -- Type *pointee = ((TypePointer *)type)->next; -+ Type *pointee = ((TypePointer *)type)->next; -+ if ( var->isThreadlocal()) -+ { -+ error("cannot take address of thread-local variable %s at compile time", var->toChars()); -+ return EXP_CANT_INTERPRET; -+ } -+ // Check for taking an address of a shared variable. -+ // If the shared variable is an array, the offset might not be zero. -+ Type *fromType = NULL; -+ if (var->type->ty == Tarray || var->type->ty == Tsarray) -+ { -+ fromType = ((TypeArray *)(var->type))->next; -+ } -+ if ( var->isDataseg() && ( -+ (offset == 0 && isSafePointerCast(var->type, pointee)) || -+ (fromType && isSafePointerCast(fromType, pointee)) -+ )) -+ { -+ return this; -+ } - Expression *val = getVarExp(loc, istate, var, goal); - if (val == EXP_CANT_INTERPRET) - return val; -@@ -1472,7 +2080,6 @@ Expression *SymOffExp::interpret(InterSt - return EXP_CANT_INTERPRET; - } - -- TypeArray *tar = (TypeArray *)val->type; - dinteger_t sz = pointee->size(); - dinteger_t indx = offset/sz; - assert(sz * indx == offset); -@@ -1495,9 +2102,12 @@ Expression *SymOffExp::interpret(InterSt - } - else if ( offset == 0 && isSafePointerCast(var->type, pointee) ) - { -+ // Create a CTFE pointer &var - VarExp *ve = new VarExp(loc, var); -- ve->type = type; -- return ve; -+ ve->type = var->type; -+ AddrExp *re = new AddrExp(loc, ve); -+ re->type = type; -+ return re; - } - - error("Cannot convert &%s to %s at compile time", var->type->toChars(), type->toChars()); -@@ -1509,6 +2119,13 @@ Expression *AddrExp::interpret(InterStat - #if LOG - printf("%s AddrExp::interpret() %s\n", loc.toChars(), toChars()); - #endif -+ if (e1->op == TOKvar && ((VarExp *)e1)->var->isDataseg()) -+ { // Normally this is already done by optimize() -+ // Do it here in case optimize(0) wasn't run before CTFE -+ SymOffExp *se = new SymOffExp(loc, ((VarExp *)e1)->var, 0); -+ se->type = type; -+ return se; -+ } - // For reference types, we need to return an lvalue ref. - TY tb = e1->type->toBasetype()->ty; - bool needRef = (tb == Tarray || tb == Taarray || tb == Tclass); -@@ -1526,7 +2143,27 @@ Expression *DelegateExp::interpret(Inter - #if LOG - printf("%s DelegateExp::interpret() %s\n", loc.toChars(), toChars()); - #endif -- return this; -+ // TODO: Really we should create a CTFE-only delegate expression -+ // of a pointer and a funcptr. -+ -+ // If it is &nestedfunc, just return it -+ // TODO: We should save the context pointer -+ if (e1->op == TOKvar && ((VarExp *)e1)->var->isFuncDeclaration()) -+ return this; -+ -+ // If it has already been CTFE'd, just return it -+ if (e1->op == TOKstructliteral || e1->op == TOKclassreference) -+ return this; -+ -+ // Else change it into &structliteral.func or &classref.func -+ Expression *e = e1->interpret(istate, ctfeNeedLvalue); -+ -+ if (exceptionOrCantInterpret(e)) -+ return e; -+ -+ e = new DelegateExp(loc, e, func); -+ e->type = type; -+ return e; - } - - -@@ -1535,12 +2172,13 @@ Expression *DelegateExp::interpret(Inter - // ------------------------------------------------------------- - // The variable used in a dotvar, index, or slice expression, - // after 'out', 'ref', and 'this' have been removed. --Expression * resolveReferences(Expression *e, Expression *thisval) -+Expression * resolveReferences(Expression *e) - { - for(;;) - { - if (e->op == TOKthis) - { -+ Expression *thisval = ctfeStack.getThis(); - assert(thisval); - assert(e != thisval); - e = thisval; -@@ -1588,12 +2226,29 @@ Expression *getVarExp(Loc loc, InterStat - */ - if (v->ident == Id::ctfe) - return new IntegerExp(loc, 1, Type::tbool); -+ -+ if (!v->originalType && v->scope) // semantic() not yet run -+ { -+ v->semantic (v->scope); -+ if (v->type->ty == Terror) -+ return EXP_CANT_INTERPRET; -+ } -+ - if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) - && v->init && !v->hasValue() && !v->isCTFE()) - #else - if (v->isConst() && v->init && !v->isCTFE()) - #endif -- { e = v->init->toExpression(); -+ { -+ if(v->scope) -+ v->init = v->init->semantic(v->scope, v->type, INITinterpret); // might not be run on aggregate members -+ e = v->init->toExpression(v->type); -+ if (v->inuse) -+ { -+ error(loc, "circular initialization of %s", v->toChars()); -+ return EXP_CANT_INTERPRET; -+ } -+ - if (e && (e->op == TOKconstruct || e->op == TOKblit)) - { AssignExp *ae = (AssignExp *)e; - e = ae->e2; -@@ -1611,14 +2266,19 @@ Expression *getVarExp(Loc loc, InterStat - if (e && !e->type) - e->type = v->type; - if (e) -+ { -+ v->inuse++; - e = e->interpret(istate, ctfeNeedAnyValue); -+ v->inuse--; -+ } - if (e == EXP_CANT_INTERPRET && !global.gag && !CtfeStatus::stackTraceCallsToSuppress) - errorSupplemental(loc, "while evaluating %s.init", v->toChars()); - } - if (e && e != EXP_CANT_INTERPRET && e->op != TOKthrownexception) - { - e = copyLiteral(e); -- ctfeStack.saveGlobalConstant(v, e); -+ if (v->isDataseg() || (v->storage_class & STCmanifest )) -+ ctfeStack.saveGlobalConstant(v, e); - } - } - else if (v->isCTFE() && !v->hasValue()) -@@ -1690,16 +2350,14 @@ Expression *getVarExp(Loc loc, InterStat - } - else if (s) - { // Struct static initializers, for example -- if (s->dsym->toInitializer() == s->sym) -- { e = s->dsym->type->defaultInitLiteral(loc); -- e = e->semantic(NULL); -- if (e->op == TOKerror) -- e = EXP_CANT_INTERPRET; -- else // Convert NULL to VoidExp -- e = e->interpret(istate, goal); -- } -- else -- error(loc, "cannot interpret symbol %s at compile time", s->toChars()); -+ e = s->dsym->type->defaultInitLiteral(loc); -+ if (e->op == TOKerror) -+ error(loc, "CTFE failed because of previous errors in %s.init", s->toChars()); -+ e = e->semantic(NULL); -+ if (e->op == TOKerror) -+ e = EXP_CANT_INTERPRET; -+ else // Convert NULL to VoidExp -+ e = e->interpret(istate, goal); - } - else - error(loc, "cannot interpret declaration %s at compile time", d->toChars()); -@@ -1755,7 +2413,7 @@ Expression *DeclarationExp::interpret(In - return NULL; - for(size_t i= 0; i < td->objects->dim; ++i) - { -- Object * o = td->objects->tdata()[i]; -+ RootObject * o = (*td->objects)[i]; - Expression *ex = isExpression(o); - DsymbolExp *s = (ex && ex->op == TOKdsymbol) ? (DsymbolExp *)ex : NULL; - VarDeclaration *v2 = s ? s->s->isVarDeclaration() : NULL; -@@ -1763,8 +2421,9 @@ Expression *DeclarationExp::interpret(In - if (!v2->isDataseg() || v2->isCTFE()) - ctfeStack.push(v2); - } -+ return NULL; - } -- if (!v->isDataseg() || v->isCTFE()) -+ if (!(v->isDataseg() || v->storage_class & STCmanifest) || v->isCTFE()) - ctfeStack.push(v); - Dsymbol *s = v->toAlias(); - if (s == v && !v->isStatic() && v->init) -@@ -1815,9 +2474,15 @@ Expression *DeclarationExp::interpret(In - declaration->isTupleDeclaration()) - { // Check for static struct declarations, which aren't executable - AttribDeclaration *ad = declaration->isAttribDeclaration(); -- if (ad && ad->decl && ad->decl->dim == 1 -- && ad->decl->tdata()[0]->isAggregateDeclaration()) -- return NULL; // static struct declaration. Nothing to do. -+ if (ad && ad->decl && ad->decl->dim == 1) -+ { -+ Dsymbol *s = (*ad->decl)[0]; -+ if (s->isAggregateDeclaration() || -+ s->isTemplateDeclaration()) -+ { -+ return NULL; // static (template) struct declaration. Nothing to do. -+ } -+ } - - // These can be made to work, too lazy now - error("Declaration %s is not yet implemented in CTFE", toChars()); -@@ -1840,15 +2505,19 @@ Expression *TupleExp::interpret(InterSta - #endif - Expressions *expsx = NULL; - -+ if (e0) -+ { -+ if (e0->interpret(istate) == EXP_CANT_INTERPRET) -+ return EXP_CANT_INTERPRET; -+ } -+ - for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (*exps)[i]; - Expression *ex; - - ex = e->interpret(istate); - if (exceptionOrCantInterpret(ex)) -- { delete expsx; - return ex; -- } - - // A tuple of assignments can contain void (Bug 5676). - if (goal == ctfeNeedNothing) -@@ -1901,9 +2570,7 @@ Expression *ArrayLiteralExp::interpret(I - if (e->op == TOKindex) // segfault bug 6250 - assert( ((IndexExp*)e)->e1 != this); - ex = e->interpret(istate); -- if (ex == EXP_CANT_INTERPRET) -- goto Lerror; -- if (ex->op == TOKthrownexception) -+ if (exceptionOrCantInterpret(ex)) - return ex; - - /* If any changes, do Copy On Write -@@ -1927,7 +2594,10 @@ Expression *ArrayLiteralExp::interpret(I - { - expandTuples(expsx); - if (expsx->dim != elements->dim) -- goto Lerror; -+ { -+ error("Internal Compiler Error: Invalid array literal"); -+ return EXP_CANT_INTERPRET; -+ } - ArrayLiteralExp *ae = new ArrayLiteralExp(loc, expsx); - ae->type = type; - return copyLiteral(ae); -@@ -1939,12 +2609,6 @@ Expression *ArrayLiteralExp::interpret(I - } - #endif - return copyLiteral(this); -- --Lerror: -- if (expsx) -- delete expsx; -- error("cannot interpret array literal"); -- return EXP_CANT_INTERPRET; - } - - Expression *AssocArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal) -@@ -1957,30 +2621,26 @@ Expression *AssocArrayLiteralExp::interp - if (ownedByCtfe) // We've already interpreted all the elements - return copyLiteral(this); - for (size_t i = 0; i < keys->dim; i++) -- { Expression *ekey = keys->tdata()[i]; -- Expression *evalue = values->tdata()[i]; -+ { -+ Expression *ekey = (*keys)[i]; -+ Expression *evalue = (*values)[i]; - Expression *ex; - - ex = ekey->interpret(istate); -- if (ex == EXP_CANT_INTERPRET) -- goto Lerr; -- if (ex->op == TOKthrownexception) -+ if (exceptionOrCantInterpret(ex)) - return ex; - -- - /* If any changes, do Copy On Write - */ - if (ex != ekey) - { - if (keysx == keys) - keysx = (Expressions *)keys->copy(); -- keysx->tdata()[i] = ex; -+ (*keysx)[i] = ex; - } - - ex = evalue->interpret(istate); -- if (ex == EXP_CANT_INTERPRET) -- goto Lerr; -- if (ex->op == TOKthrownexception) -+ if (exceptionOrCantInterpret(ex)) - return ex; - - /* If any changes, do Copy On Write -@@ -1989,7 +2649,7 @@ Expression *AssocArrayLiteralExp::interp - { - if (valuesx == values) - valuesx = (Expressions *)values->copy(); -- valuesx->tdata()[i] = ex; -+ (*valuesx)[i] = ex; - } - } - if (keysx != keys) -@@ -1997,14 +2657,19 @@ Expression *AssocArrayLiteralExp::interp - if (valuesx != values) - expandTuples(valuesx); - if (keysx->dim != valuesx->dim) -- goto Lerr; -+ { -+ error("Internal Compiler Error: invalid AA"); -+ return EXP_CANT_INTERPRET; -+ } - - /* Remove duplicate keys - */ - for (size_t i = 1; i < keysx->dim; i++) -- { Expression *ekey = keysx->tdata()[i - 1]; -+ { -+ Expression *ekey = (*keysx)[i - 1]; - for (size_t j = i; j < keysx->dim; j++) -- { Expression *ekey2 = keysx->tdata()[j]; -+ { -+ Expression *ekey2 = (*keysx)[j]; - int eq = ctfeEqual(loc, TOKequal, ekey, ekey2); - if (eq) // if a match - { -@@ -2030,13 +2695,6 @@ Expression *AssocArrayLiteralExp::interp - return ae; - } - return this; -- --Lerr: -- if (keysx != keys) -- delete keysx; -- if (valuesx != values) -- delete values; -- return EXP_CANT_INTERPRET; - } - - Expression *StructLiteralExp::interpret(InterState *istate, CtfeGoal goal) -@@ -2045,50 +2703,70 @@ Expression *StructLiteralExp::interpret( - #if LOG - printf("%s StructLiteralExp::interpret() %s\n", loc.toChars(), toChars()); - #endif -- /* We don't know how to deal with overlapping fields -- */ -- if (sd->hasUnions) -- { error("Unions with overlapping fields are not yet supported in CTFE"); -- return EXP_CANT_INTERPRET; -- } - if (ownedByCtfe) - return copyLiteral(this); - -- if (elements) -- { -- for (size_t i = 0; i < elements->dim; i++) -- { Expression *e = (*elements)[i]; -- if (!e) -- continue; -- -- Expression *ex = e->interpret(istate); -- if (exceptionOrCantInterpret(ex)) -- { delete expsx; -- return ex; -- } -+ size_t elemdim = elements ? elements->dim : 0; - -- /* If any changes, do Copy On Write -+ for (size_t i = 0; i < sd->fields.dim; i++) -+ { Expression *e = NULL; -+ Expression *ex = NULL; -+ if (i >= elemdim) -+ { -+ /* If a nested struct has no initialized hidden pointer, -+ * set it to null to match the runtime behaviour. - */ -- if (ex != e) -+ if (i == sd->fields.dim - 1 && sd->isNested()) -+ { // Context field has not been filled -+ ex = new NullExp(loc); -+ ex->type = sd->fields[i]->type; -+ } -+ } -+ else -+ { -+ e = (*elements)[i]; -+ if (!e) - { -- if (!expsx) -- { expsx = new Expressions(); -- ++CtfeStatus::numArrayAllocs; -- expsx->setDim(elements->dim); -- for (size_t j = 0; j < elements->dim; j++) -- { -- (*expsx)[j] = (*elements)[j]; -- } -+ /* Ideally, we'd convert NULL members into void expressions. -+ * The problem is that the VoidExp will be removed when we -+ * leave CTFE, causing another memory allocation if we use this -+ * same struct literal again. -+ * -+ * ex = sd->fields[i]->type->voidInitLiteral(sd->fields[i]); -+ */ -+ ex = NULL; -+ } -+ else -+ { -+ ex = e->interpret(istate); -+ if (exceptionOrCantInterpret(ex)) -+ return ex; -+ } -+ } -+ -+ /* If any changes, do Copy On Write -+ */ -+ if (ex != e) -+ { -+ if (!expsx) -+ { expsx = new Expressions(); -+ ++CtfeStatus::numArrayAllocs; -+ expsx->setDim(sd->fields.dim); -+ for (size_t j = 0; j < elements->dim; j++) -+ { -+ (*expsx)[j] = (*elements)[j]; - } -- (*expsx)[i] = ex; - } -+ (*expsx)[i] = ex; - } - } -+ - if (elements && expsx) - { - expandTuples(expsx); -- if (expsx->dim != elements->dim) -- { delete expsx; -+ if (expsx->dim != sd->fields.dim) -+ { -+ error("Internal Compiler Error: invalid struct literal"); - return EXP_CANT_INTERPRET; - } - StructLiteralExp *se = new StructLiteralExp(loc, sd, expsx); -@@ -2183,10 +2861,19 @@ Expression *NewExp::interpret(InterState - Dsymbol *s = c->fields[i]; - VarDeclaration *v = s->isVarDeclaration(); - assert(v); -- Expression *m = v->init ? v->init->toExpression() : v->type->defaultInitLiteral(loc); -+ Expression *m; -+ if (v->init) -+ { -+ if (v->init->isVoidInitializer()) -+ m = v->type->voidInitLiteral(v); -+ else -+ m = v->getConstInitializer(true); -+ } -+ else -+ m = v->type->defaultInitLiteral(loc); - if (exceptionOrCantInterpret(m)) - return m; -- elems->tdata()[fieldsSoFar+i] = copyLiteral(m); -+ (*elems)[fieldsSoFar+i] = copyLiteral(m); - } - } - // Hack: we store a ClassDeclaration instead of a StructDeclaration. -@@ -2216,33 +2903,33 @@ Expression *NewExp::interpret(InterState - return EXP_CANT_INTERPRET; - } - --Expression *UnaExp::interpretCommon(InterState *istate, CtfeGoal goal, Expression *(*fp)(Type *, Expression *)) -+Expression *UnaExp::interpret(InterState *istate, CtfeGoal goal) - { Expression *e; - Expression *e1; - - #if LOG -- printf("%s UnaExp::interpretCommon() %s\n", loc.toChars(), toChars()); -+ printf("%s UnaExp::interpret() %s\n", loc.toChars(), toChars()); - #endif -+ if (op == TOKdottype) -+ { -+ error("Internal Compiler Error: CTFE DotType: %s", toChars()); -+ return EXP_CANT_INTERPRET; -+ } - e1 = this->e1->interpret(istate); - if (exceptionOrCantInterpret(e1)) - return e1; -- e = (*fp)(type, e1); -+ switch(op) -+ { -+ case TOKneg: e = Neg(type, e1); break; -+ case TOKtilde: e = Com(type, e1); break; -+ case TOKnot: e = Not(type, e1); break; -+ case TOKtobool: e = Bool(type, e1); break; -+ case TOKvector: e = this; break; // do nothing -+ default: assert(0); -+ } - return e; - } - --#define UNA_INTERPRET(op) \ --Expression *op##Exp::interpret(InterState *istate, CtfeGoal goal) \ --{ \ -- return interpretCommon(istate, goal, &op); \ --} -- --UNA_INTERPRET(Neg) --UNA_INTERPRET(Com) --UNA_INTERPRET(Not) --UNA_INTERPRET(Bool) -- -- --typedef Expression *(*fp_t)(Type *, Expression *, Expression *); - - Expression *BinExp::interpretCommon(InterState *istate, CtfeGoal goal, fp_t fp) - { Expression *e; -@@ -2291,62 +2978,49 @@ Expression *BinExp::interpretCommon(Inte - if (exceptionOrCantInterpret(e1)) - return e1; - if (e1->isConst() != 1) -- goto Lcant; -+ { -+ error("Internal Compiler Error: non-constant value %s", this->e1->toChars()); -+ return EXP_CANT_INTERPRET; -+ } - - e2 = this->e2->interpret(istate); - if (exceptionOrCantInterpret(e2)) - return e2; - if (e2->isConst() != 1) -- goto Lcant; -+ { -+ error("Internal Compiler Error: non-constant value %s", this->e2->toChars()); -+ return EXP_CANT_INTERPRET; -+ } - -+ if (op == TOKshr || op == TOKshl || op == TOKushr) -+ { -+ sinteger_t i2 = e2->toInteger(); -+ d_uns64 sz = e1->type->size() * 8; -+ if (i2 < 0 || i2 >= sz) -+ { error("shift by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1); -+ return EXP_CANT_INTERPRET; -+ } -+ } - e = (*fp)(type, e1, e2); - if (e == EXP_CANT_INTERPRET) - error("%s cannot be interpreted at compile time", toChars()); - return e; -- --Lcant: -- return EXP_CANT_INTERPRET; - } - --#define BIN_INTERPRET(op) \ --Expression *op##Exp::interpret(InterState *istate, CtfeGoal goal) \ --{ \ -- return interpretCommon(istate, goal, &op); \ --} -- --BIN_INTERPRET(Add) --BIN_INTERPRET(Min) --BIN_INTERPRET(Mul) --BIN_INTERPRET(Div) --BIN_INTERPRET(Mod) --BIN_INTERPRET(Shl) --BIN_INTERPRET(Shr) --BIN_INTERPRET(Ushr) --BIN_INTERPRET(And) --BIN_INTERPRET(Or) --BIN_INTERPRET(Xor) --#if DMDV2 --BIN_INTERPRET(Pow) --#endif -- -- --typedef int (*fp2_t)(Loc loc, enum TOK, Expression *, Expression *); -- -- - Expression *BinExp::interpretCompareCommon(InterState *istate, CtfeGoal goal, fp2_t fp) - { - Expression *e1; - Expression *e2; - - #if LOG -- printf("%s BinExp::interpretCommon2() %s\n", loc.toChars(), toChars()); -+ printf("%s BinExp::interpretCompareCommon() %s\n", loc.toChars(), toChars()); - #endif - if (this->e1->type->ty == Tpointer && this->e2->type->ty == Tpointer) - { -- e1 = this->e1->interpret(istate, ctfeNeedLvalue); -+ e1 = this->e1->interpret(istate); - if (exceptionOrCantInterpret(e1)) - return e1; -- e2 = this->e2->interpret(istate, ctfeNeedLvalue); -+ e2 = this->e2->interpret(istate); - if (exceptionOrCantInterpret(e2)) - return e2; - dinteger_t ofs1, ofs2; -@@ -2384,47 +3058,59 @@ Expression *BinExp::interpretCompareComm - return new IntegerExp(loc, cmp, type); - } - --#define BIN_INTERPRET2(op, opfunc) \ --Expression *op##Exp::interpret(InterState *istate, CtfeGoal goal) \ --{ \ -- return interpretCompareCommon(istate, goal, &opfunc); \ -+Expression *BinExp::interpret(InterState *istate, CtfeGoal goal) -+{ -+ switch(op) -+ { -+ case TOKadd: return interpretCommon(istate, goal, &Add); -+ case TOKmin: return interpretCommon(istate, goal, &Min); -+ case TOKmul: return interpretCommon(istate, goal, &Mul); -+ case TOKdiv: return interpretCommon(istate, goal, &Div); -+ case TOKmod: return interpretCommon(istate, goal, &Mod); -+ case TOKshl: return interpretCommon(istate, goal, &Shl); -+ case TOKshr: return interpretCommon(istate, goal, &Shr); -+ case TOKushr: return interpretCommon(istate, goal, &Ushr); -+ case TOKand: return interpretCommon(istate, goal, &And); -+ case TOKor: return interpretCommon(istate, goal, &Or); -+ case TOKxor: return interpretCommon(istate, goal, &Xor); -+#if DMDV2 -+ case TOKpow: return interpretCommon(istate, goal, &Pow); -+#endif -+ case TOKequal: -+ case TOKnotequal: -+ return interpretCompareCommon(istate, goal, &ctfeEqual); -+ case TOKidentity: -+ case TOKnotidentity: -+ return interpretCompareCommon(istate, goal, &ctfeIdentity); -+ case TOKlt: -+ case TOKle: -+ case TOKgt: -+ case TOKge: -+ case TOKleg: -+ case TOKlg: -+ case TOKunord: -+ case TOKue: -+ case TOKug: -+ case TOKuge: -+ case TOKul: -+ case TOKule: -+ return interpretCompareCommon(istate, goal, &ctfeCmp); -+ default: -+ assert(0); -+ return NULL; -+ } - } - --BIN_INTERPRET2(Equal, ctfeEqual) --BIN_INTERPRET2(Identity, ctfeIdentity) --BIN_INTERPRET2(Cmp, ctfeCmp) -- - /* Helper functions for BinExp::interpretAssignCommon - */ - --// Return true if e is derived from UnaryExp. --// Consider moving this function into Expression. --UnaExp *isUnaExp(Expression *e) --{ -- switch (e->op) -- { -- case TOKdotvar: -- case TOKindex: -- case TOKslice: -- case TOKcall: -- case TOKdot: -- case TOKdotti: -- case TOKdottype: -- case TOKcast: -- return (UnaExp *)e; -- default: -- break; -- } -- return NULL; --} -- - // Returns the variable which is eventually modified, or NULL if an rvalue. - // thisval is the current value of 'this'. --VarDeclaration * findParentVar(Expression *e, Expression *thisval) -+VarDeclaration * findParentVar(Expression *e) - { - for (;;) - { -- e = resolveReferences(e, thisval); -+ e = resolveReferences(e); - if (e->op == TOKvar) - break; - if (e->op == TOKindex) -@@ -2443,6 +3129,13 @@ VarDeclaration * findParentVar(Expressio - return v; - } - -+Expression *interpretAssignToSlice(InterState *istate, CtfeGoal goal, Loc loc, -+ SliceExp *sexp, Expression *newval, bool wantRef, bool isBlockAssignment, -+ BinExp *originalExpression); -+ -+bool interpretAssignToIndex(InterState *istate, Loc loc, -+ IndexExp *ie, Expression *newval, bool wantRef, -+ BinExp *originalExp); - - Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_t fp, int post) - { -@@ -2479,9 +3172,9 @@ Expression *BinExp::interpretAssignCommo - { - desttype = ((TypeArray *)desttype)->next; - #if DMDV2 -- if (srctype == desttype->castMod(0)) -+ if (srctype->equals(desttype->castMod(0))) - #else -- if (srctype == desttype) -+ if (srctype->equals(desttype)) - #endif - { - isBlockAssignment = true; -@@ -2501,7 +3194,7 @@ Expression *BinExp::interpretAssignCommo - bool wantRef = false; - bool wantLvalueRef = false; - -- if (!fp && this->e1->type->toBasetype() == this->e2->type->toBasetype() && -+ if (!fp && this->e1->type->toBasetype()->equals(this->e2->type->toBasetype()) && - (e1->type->toBasetype()->ty == Tarray || isAssocArray(e1->type) - || e1->type->toBasetype()->ty == Tclass) - // e = *x is never a reference, because *x is always a value -@@ -2519,7 +3212,7 @@ Expression *BinExp::interpretAssignCommo - * can be dealt with by making this a non-ref assign (y = x.dup). - * Otherwise it's a big mess. - */ -- VarDeclaration * targetVar = findParentVar(e2, istate->localThis); -+ VarDeclaration * targetVar = findParentVar(e2); - if (!(targetVar && targetVar->isConst())) - wantRef = true; - // slice assignment of static arrays is not reference assignment -@@ -2560,7 +3253,7 @@ Expression *BinExp::interpretAssignCommo - // First, deal with this = e; and call() = e; - if (e1->op == TOKthis) - { -- e1 = istate->localThis; -+ e1 = ctfeStack.getThis(); - } - if (e1->op == TOKcall) - { -@@ -2575,7 +3268,7 @@ Expression *BinExp::interpretAssignCommo - // f() = e2, when f returns an array, is always a slice assignment. - // Convert into arr[0..arr.length] = e2 - e1 = new SliceExp(loc, e1, -- new IntegerExp(0, 0, Type::tsize_t), -+ new IntegerExp(Loc(), 0, Type::tsize_t), - ArrayLength(Type::tsize_t, e1)); - e1->type = type; - } -@@ -2586,7 +3279,7 @@ Expression *BinExp::interpretAssignCommo - if (exceptionOrCantInterpret(e1)) - return e1; - if (!(e1->op == TOKvar || e1->op == TOKdotvar || e1->op == TOKindex -- || e1->op == TOKslice)) -+ || e1->op == TOKslice || e1->op == TOKstructliteral)) - { - error("cannot dereference invalid pointer %s", - this->e1->toChars()); -@@ -2595,7 +3288,7 @@ Expression *BinExp::interpretAssignCommo - } - - if (!(e1->op == TOKarraylength || e1->op == TOKvar || e1->op == TOKdotvar -- || e1->op == TOKindex || e1->op == TOKslice)) -+ || e1->op == TOKindex || e1->op == TOKslice || e1->op == TOKstructliteral)) - { - error("CTFE internal error: unsupported assignment %s", toChars()); - return EXP_CANT_INTERPRET; -@@ -2630,7 +3323,7 @@ Expression *BinExp::interpretAssignCommo - return oldval; - while (oldval->op == TOKvar) - { -- oldval = resolveReferences(oldval, istate->localThis); -+ oldval = resolveReferences(oldval); - oldval = oldval->interpret(istate); - if (exceptionOrCantInterpret(oldval)) - return oldval; -@@ -2699,7 +3392,7 @@ Expression *BinExp::interpretAssignCommo - { // Get the old array literal. - oldval = e1->interpret(istate); - while (oldval->op == TOKvar) -- { oldval = resolveReferences(oldval, istate->localThis); -+ { oldval = resolveReferences(oldval); - oldval = oldval->interpret(istate); - } - } -@@ -2751,14 +3444,14 @@ Expression *BinExp::interpretAssignCommo - // ------------------------------------------------- - // Make sure we're not trying to modify a global or static variable - // We do this by locating the ultimate parent variable which gets modified. -- VarDeclaration * ultimateVar = findParentVar(e1, istate->localThis); -+ VarDeclaration * ultimateVar = findParentVar(e1); - if (ultimateVar && ultimateVar->isDataseg() && !ultimateVar->isCTFE()) - { // Can't modify global or static data - error("%s cannot be modified at compile time", ultimateVar->toChars()); - return EXP_CANT_INTERPRET; - } - -- e1 = resolveReferences(e1, istate->localThis); -+ e1 = resolveReferences(e1); - - // Unless we have a simple var assignment, we're - // only modifying part of the variable. So we need to make sure -@@ -2819,7 +3512,7 @@ Expression *BinExp::interpretAssignCommo - ie = (IndexExp *)ie->e1; - ++depth; - } -- Expression *aggregate = resolveReferences(ie->e1, istate->localThis); -+ Expression *aggregate = resolveReferences(ie->e1); - Expression *oldagg = aggregate; - // Get the AA to be modified. (We do an LvalueRef interpret, unless it - // is a simple ref parameter -- in which case, we just want the value) -@@ -2907,18 +3600,17 @@ Expression *BinExp::interpretAssignCommo - // collapsed into a single assignment. - if (!wantRef && e1->op == TOKdotvar) - { -- // Strip of all of the leading dotvars, unless we started with a call -- // or a ref parameter -+ // Strip of all of the leading dotvars, unless it is a CTFE dotvar -+ // pointer or reference - // (in which case, we already have the lvalue). -- if (this->e1->op != TOKcall && !(this->e1->op==TOKvar -- && ((VarExp*)this->e1)->var->storage_class & (STCref | STCout))) -- e1 = e1->interpret(istate, isPointer(type)? ctfeNeedLvalueRef : ctfeNeedLvalue); -- if (exceptionOrCantInterpret(e1)) -- return e1; -- if (e1->op == TOKstructliteral && newval->op == TOKstructliteral) -- { -- assignInPlace(e1, newval); -- return returnValue; -+ DotVarExp *dve = (DotVarExp *)e1; -+ bool isCtfePointer = (dve->e1->op == TOKstructliteral) -+ && ((StructLiteralExp *)(dve->e1))->ownedByCtfe; -+ if (!isCtfePointer) -+ { -+ e1 = e1->interpret(istate, isPointer(type) ? ctfeNeedLvalueRef : ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(e1)) -+ return e1; - } - } - #if LOGASSIGN -@@ -2968,6 +3660,15 @@ Expression *BinExp::interpretAssignCommo - } - } - } -+ else if (e1->op == TOKstructliteral && newval->op == TOKstructliteral) -+ { -+ /* Assignment to complete struct of the form: -+ * e1 = newval -+ * (e1 was a ref parameter, or was created via TOKstar dereferencing). -+ */ -+ assignInPlace(e1, newval); -+ return returnValue; -+ } - else if (e1->op == TOKdotvar) - { - /* Assignment to member variable of the form: -@@ -3012,496 +3713,552 @@ Expression *BinExp::interpretAssignCommo - for(int i = unionStart; i < unionStart + unionSize; ++i) - { if (i == fieldi) - continue; -- Expression **el = &se->elements->tdata()[i]; -+ Expression **el = &(*se->elements)[i]; - if ((*el)->op != TOKvoid) - *el = (*el)->type->voidInitLiteral(member); - } - } - - if (newval->op == TOKstructliteral) -- assignInPlace(se->elements->tdata()[fieldi], newval); -+ assignInPlace((*se->elements)[fieldi], newval); - else -- se->elements->tdata()[fieldi] = newval; -+ (*se->elements)[fieldi] = newval; - return returnValue; - } - else if (e1->op == TOKindex) - { -- /* Assignment to array element of the form: -- * aggregate[i] = newval -- * aggregate is not AA (AAs were dealt with already). -- */ -- IndexExp *ie = (IndexExp *)e1; -- assert(ie->e1->type->toBasetype()->ty != Taarray); -- uinteger_t destarraylen = 0; -+ if ( !interpretAssignToIndex(istate, loc, (IndexExp *)e1, newval, -+ wantRef, this)) -+ return EXP_CANT_INTERPRET; -+ return returnValue; -+ } -+ else if (e1->op == TOKslice) -+ { -+ // Note that slice assignments don't support things like ++, so -+ // we don't need to remember 'returnValue'. -+ return interpretAssignToSlice(istate, goal, loc, (SliceExp *)e1, -+ newval, wantRef, isBlockAssignment, this); -+ } -+ else -+ { -+ error("%s cannot be evaluated at compile time", toChars()); -+ } -+ return returnValue; -+} -+ -+/************* -+ * Deal with assignments of the form -+ * aggregate[ie] = newval -+ * where aggregate and newval have already been interpreted -+ * -+ * Return true if OK, false if error occured -+ */ -+bool interpretAssignToIndex(InterState *istate, Loc loc, -+ IndexExp *ie, Expression *newval, bool wantRef, -+ BinExp *originalExp) -+{ -+ /* Assignment to array element of the form: -+ * aggregate[i] = newval -+ * aggregate is not AA (AAs were dealt with already). -+ */ -+ assert(ie->e1->type->toBasetype()->ty != Taarray); -+ uinteger_t destarraylen = 0; - -- // Set the $ variable, and find the array literal to modify -- if (ie->e1->type->toBasetype()->ty != Tpointer) -+ // Set the $ variable, and find the array literal to modify -+ if (ie->e1->type->toBasetype()->ty != Tpointer) -+ { -+ Expression *oldval = ie->e1->interpret(istate); -+ if (oldval->op == TOKnull) - { -- Expression *oldval = ie->e1->interpret(istate); -- if (oldval->op == TOKnull) -- { -- error("cannot index null array %s", ie->e1->toChars()); -- return EXP_CANT_INTERPRET; -- } -- if (oldval->op != TOKarrayliteral && oldval->op != TOKstring -- && oldval->op != TOKslice) -- { -- error("cannot determine length of %s at compile time", -- ie->e1->toChars()); -- return EXP_CANT_INTERPRET; -- } -- destarraylen = resolveArrayLength(oldval); -- if (ie->lengthVar) -- { -- IntegerExp *dollarExp = new IntegerExp(loc, destarraylen, Type::tsize_t); -- ctfeStack.push(ie->lengthVar); -- ie->lengthVar->setValue(dollarExp); -- } -+ originalExp->error("cannot index null array %s", ie->e1->toChars()); -+ return false; -+ } -+ if (oldval->op != TOKarrayliteral && oldval->op != TOKstring -+ && oldval->op != TOKslice) -+ { -+ originalExp->error("cannot determine length of %s at compile time", -+ ie->e1->toChars()); -+ return false; - } -- Expression *index = ie->e2->interpret(istate); -+ destarraylen = resolveArrayLength(oldval); - if (ie->lengthVar) -- ctfeStack.pop(ie->lengthVar); // $ is defined only inside [] -- if (exceptionOrCantInterpret(index)) -- return index; -+ { -+ IntegerExp *dollarExp = new IntegerExp(loc, destarraylen, Type::tsize_t); -+ ctfeStack.push(ie->lengthVar); -+ ie->lengthVar->setValue(dollarExp); -+ } -+ } -+ Expression *index = ie->e2->interpret(istate); -+ if (ie->lengthVar) -+ ctfeStack.pop(ie->lengthVar); // $ is defined only inside [] -+ if (exceptionOrCantInterpret(index)) -+ return false; - -- assert (index->op != TOKslice); // only happens with AA assignment -+ assert (index->op != TOKslice); // only happens with AA assignment - -- ArrayLiteralExp *existingAE = NULL; -- StringExp *existingSE = NULL; -+ ArrayLiteralExp *existingAE = NULL; -+ StringExp *existingSE = NULL; - -- Expression *aggregate = resolveReferences(ie->e1, istate->localThis); -+ Expression *aggregate = resolveReferences(ie->e1); - -- // Set the index to modify, and check that it is in range -- dinteger_t indexToModify = index->toInteger(); -- if (ie->e1->type->toBasetype()->ty == Tpointer) -+ // Set the index to modify, and check that it is in range -+ dinteger_t indexToModify = index->toInteger(); -+ if (ie->e1->type->toBasetype()->ty == Tpointer) -+ { -+ dinteger_t ofs; -+ aggregate = aggregate->interpret(istate, ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(aggregate)) -+ return false; -+ if (aggregate->op == TOKnull) - { -- dinteger_t ofs; -- aggregate = aggregate->interpret(istate, ctfeNeedLvalue); -- if (exceptionOrCantInterpret(aggregate)) -- return aggregate; -- if (aggregate->op == TOKnull) -- { -- error("cannot index through null pointer %s", ie->e1->toChars()); -- return EXP_CANT_INTERPRET; -- } -- if (aggregate->op == TOKint64) -- { -- error("cannot index through invalid pointer %s of value %s", -- ie->e1->toChars(), aggregate->toChars()); -- return EXP_CANT_INTERPRET; -- } -- aggregate = getAggregateFromPointer(aggregate, &ofs); -- indexToModify += ofs; -- if (aggregate->op != TOKslice && aggregate->op != TOKstring && -- aggregate->op != TOKarrayliteral && aggregate->op != TOKassocarrayliteral) -- { -- if (indexToModify != 0) -- { -- error("pointer index [%lld] lies outside memory block [0..1]", indexToModify); -- return EXP_CANT_INTERPRET; -- } -- // It is equivalent to *aggregate = newval. -- // Aggregate could be varexp, a dotvar, ... -- // TODO: we could support this -- error("indexed assignment of non-array pointers is not yet supported at compile time; use *%s = %s instead", -- ie->e1->toChars(), e2->toChars()); -- return EXP_CANT_INTERPRET; -- } -- destarraylen = resolveArrayLength(aggregate); -+ originalExp->error("cannot index through null pointer %s", ie->e1->toChars()); -+ return false; - } -- if (indexToModify >= destarraylen) -+ if (aggregate->op == TOKint64) - { -- error("array index %lld is out of bounds [0..%lld]", indexToModify, -- destarraylen); -- return EXP_CANT_INTERPRET; -+ originalExp->error("cannot index through invalid pointer %s of value %s", -+ ie->e1->toChars(), aggregate->toChars()); -+ return false; - } -- -- /* The only possible indexable LValue aggregates are array literals, and -- * slices of array literals. -- */ -- if (aggregate->op == TOKindex || aggregate->op == TOKdotvar || -- aggregate->op == TOKslice || aggregate->op == TOKcall || -- aggregate->op == TOKstar) -+ aggregate = getAggregateFromPointer(aggregate, &ofs); -+ indexToModify += ofs; -+ if (aggregate->op != TOKslice && aggregate->op != TOKstring && -+ aggregate->op != TOKarrayliteral && aggregate->op != TOKassocarrayliteral) - { -- Expression *origagg = aggregate; -- aggregate = aggregate->interpret(istate, ctfeNeedLvalue); -- if (exceptionOrCantInterpret(aggregate)) -- return aggregate; -- // The array could be an index of an AA. Resolve it if so. -- if (aggregate->op == TOKindex && -- ((IndexExp *)aggregate)->e1->op == TOKassocarrayliteral) -- { -- IndexExp *ix = (IndexExp *)aggregate; -- aggregate = findKeyInAA(loc, (AssocArrayLiteralExp *)ix->e1, ix->e2); -- if (!aggregate) -- { -- error("key %s not found in associative array %s", -- ix->e2->toChars(), ix->e1->toChars()); -- return EXP_CANT_INTERPRET; -- } -- if (exceptionOrCantInterpret(aggregate)) -- return aggregate; -+ if (aggregate->op == TOKsymoff) -+ { -+ originalExp->error("mutable variable %s cannot be modified at compile time, even through a pointer", ((SymOffExp *)aggregate)->var->toChars()); -+ return false; -+ } -+ if (indexToModify != 0) -+ { -+ originalExp->error("pointer index [%lld] lies outside memory block [0..1]", indexToModify); -+ return false; - } -+ // It is equivalent to *aggregate = newval. -+ // Aggregate could be varexp, a dotvar, ... -+ // TODO: we could support this -+ originalExp->error("indexed assignment of non-array pointers is not yet supported at compile time; use *%s = %s instead", -+ ie->e1->toChars(), originalExp->e2->toChars()); -+ return false; - } -- if (aggregate->op == TOKvar) -- { -- VarExp *ve = (VarExp *)aggregate; -- VarDeclaration *v = ve->var->isVarDeclaration(); -- aggregate = v->getValue(); -- if (aggregate->op == TOKnull) -+ destarraylen = resolveArrayLength(aggregate); -+ } -+ if (indexToModify >= destarraylen) -+ { -+ originalExp->error("array index %lld is out of bounds [0..%lld]", indexToModify, -+ destarraylen); -+ return false; -+ } -+ -+ /* The only possible indexable LValue aggregates are array literals, and -+ * slices of array literals. -+ */ -+ if (aggregate->op == TOKindex || aggregate->op == TOKdotvar || -+ aggregate->op == TOKslice || aggregate->op == TOKcall || -+ aggregate->op == TOKstar || aggregate->op == TOKcast) -+ { -+ aggregate = aggregate->interpret(istate, ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(aggregate)) -+ return false; -+ // The array could be an index of an AA. Resolve it if so. -+ if (aggregate->op == TOKindex && -+ ((IndexExp *)aggregate)->e1->op == TOKassocarrayliteral) -+ { -+ IndexExp *ix = (IndexExp *)aggregate; -+ aggregate = findKeyInAA(loc, (AssocArrayLiteralExp *)ix->e1, ix->e2); -+ if (!aggregate) - { -- // This would be a runtime segfault -- error("cannot index null array %s", v->toChars()); -- return EXP_CANT_INTERPRET; -+ originalExp->error("key %s not found in associative array %s", -+ ix->e2->toChars(), ix->e1->toChars()); -+ return false; - } -+ if (exceptionOrCantInterpret(aggregate)) -+ return false; - } -- if (aggregate->op == TOKslice) -- { -- SliceExp *sexp = (SliceExp *)aggregate; -- aggregate = sexp->e1; -- Expression *lwr = sexp->lwr->interpret(istate); -- indexToModify += lwr->toInteger(); -- } -- if (aggregate->op == TOKarrayliteral) -- existingAE = (ArrayLiteralExp *)aggregate; -- else if (aggregate->op == TOKstring) -- existingSE = (StringExp *)aggregate; -- else -+ } -+ if (aggregate->op == TOKvar) -+ { -+ VarExp *ve = (VarExp *)aggregate; -+ VarDeclaration *v = ve->var->isVarDeclaration(); -+ aggregate = v->getValue(); -+ if (aggregate->op == TOKnull) - { -- error("CTFE internal compiler error %s", aggregate->toChars()); -- return EXP_CANT_INTERPRET; -+ // This would be a runtime segfault -+ originalExp->error("cannot index null array %s", v->toChars()); -+ return false; - } -- if (!wantRef && newval->op == TOKslice) -+ } -+ if (aggregate->op == TOKslice) -+ { -+ SliceExp *sexp = (SliceExp *)aggregate; -+ aggregate = sexp->e1; -+ Expression *lwr = sexp->lwr->interpret(istate); -+ indexToModify += lwr->toInteger(); -+ } -+ if (aggregate->op == TOKarrayliteral) -+ existingAE = (ArrayLiteralExp *)aggregate; -+ else if (aggregate->op == TOKstring) -+ existingSE = (StringExp *)aggregate; -+ else -+ { -+ originalExp->error("CTFE internal compiler error %s", aggregate->toChars()); -+ return false; -+ } -+ if (!wantRef && newval->op == TOKslice) -+ { -+ newval = resolveSlice(newval); -+ if (newval == EXP_CANT_INTERPRET) - { -- newval = resolveSlice(newval); -- if (newval == EXP_CANT_INTERPRET) -- { -- error("Compiler error: CTFE index assign %s", toChars()); -- assert(0); -- } -- } -- if (wantRef && newval->op == TOKindex -- && ((IndexExp *)newval)->e1 == aggregate) -- { // It's a circular reference, resolve it now -- newval = newval->interpret(istate); -+ originalExp->error("Compiler error: CTFE index assign %s", originalExp->toChars()); -+ assert(0); - } -+ } -+ if (wantRef && newval->op == TOKindex -+ && ((IndexExp *)newval)->e1 == aggregate) -+ { // It's a circular reference, resolve it now -+ newval = newval->interpret(istate); -+ } - -- if (existingAE) -- { -- if (newval->op == TOKstructliteral) -- assignInPlace((Expression *)(existingAE->elements->tdata()[indexToModify]), newval); -- else -- existingAE->elements->tdata()[indexToModify] = newval; -- return returnValue; -- } -- if (existingSE) -+ if (existingAE) -+ { -+ if (newval->op == TOKstructliteral) -+ assignInPlace((*existingAE->elements)[indexToModify], newval); -+ else -+ (*existingAE->elements)[indexToModify] = newval; -+ return true; -+ } -+ if (existingSE) -+ { -+ utf8_t *s = (utf8_t *)existingSE->string; -+ if (!existingSE->ownedByCtfe) - { -- unsigned char *s = (unsigned char *)existingSE->string; -- if (!existingSE->ownedByCtfe) -- { -- error("cannot modify read-only string literal %s", ie->e1->toChars()); -- return EXP_CANT_INTERPRET; -- } -- unsigned value = newval->toInteger(); -- switch (existingSE->sz) -- { -- case 1: s[indexToModify] = value; break; -- case 2: ((unsigned short *)s)[indexToModify] = value; break; -- case 4: ((unsigned *)s)[indexToModify] = value; break; -- default: -- assert(0); -- break; -- } -- return returnValue; -+ originalExp->error("cannot modify read-only string literal %s", ie->e1->toChars()); -+ return false; - } -- else -+ unsigned value = newval->toInteger(); -+ switch (existingSE->sz) - { -- error("Index assignment %s is not yet supported in CTFE ", toChars()); -- return EXP_CANT_INTERPRET; -+ case 1: s[indexToModify] = value; break; -+ case 2: ((unsigned short *)s)[indexToModify] = value; break; -+ case 4: ((unsigned *)s)[indexToModify] = value; break; -+ default: -+ assert(0); -+ break; - } -- return returnValue; -+ return true; - } -- else if (e1->op == TOKslice) -+ else - { -- // ------------------------------ -- // aggregate[] = newval -- // aggregate[low..upp] = newval -- // ------------------------------ -- SliceExp * sexp = (SliceExp *)e1; -- // Set the $ variable -- Expression *oldval = sexp->e1; -- bool assignmentToSlicedPointer = false; -- if (isPointer(oldval->type)) -- { // Slicing a pointer -- oldval = oldval->interpret(istate, ctfeNeedLvalue); -- if (exceptionOrCantInterpret(oldval)) -- return oldval; -- dinteger_t ofs; -- oldval = getAggregateFromPointer(oldval, &ofs); -- assignmentToSlicedPointer = true; -- } else -- oldval = oldval->interpret(istate); -+ originalExp->error("Index assignment %s is not yet supported in CTFE ", originalExp->toChars()); -+ return false; -+ } -+ return true; -+} - -- if (oldval->op != TOKarrayliteral && oldval->op != TOKstring -- && oldval->op != TOKslice && oldval->op != TOKnull) -+/************* -+ * Deal with assignments of the form -+ * dest[] = newval -+ * dest[low..upp] = newval -+ * where newval has already been interpreted -+ * -+ * This could be a slice assignment or a block assignment, and -+ * dest could be either an array literal, or a string. -+ * -+ * Returns EXP_CANT_INTERPRET on failure. If there are no errors, -+ * it returns aggregate[low..upp], except that as an optimisation, -+ * if goal == ctfeNeedNothing, it will return NULL -+ */ -+ -+Expression *interpretAssignToSlice(InterState *istate, CtfeGoal goal, Loc loc, -+ SliceExp *sexp, Expression *newval, bool wantRef, bool isBlockAssignment, -+ BinExp *originalExp) -+{ -+ Expression *e2 = originalExp->e2; -+ -+ // ------------------------------ -+ // aggregate[] = newval -+ // aggregate[low..upp] = newval -+ // ------------------------------ -+ // Set the $ variable -+ Expression *oldval = sexp->e1; -+ bool assignmentToSlicedPointer = false; -+ if (isPointer(oldval->type)) -+ { // Slicing a pointer -+ oldval = oldval->interpret(istate, ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(oldval)) -+ return oldval; -+ dinteger_t ofs; -+ oldval = getAggregateFromPointer(oldval, &ofs); -+ assignmentToSlicedPointer = true; -+ } -+ else -+ oldval = oldval->interpret(istate); -+ -+ if (oldval->op != TOKarrayliteral && oldval->op != TOKstring -+ && oldval->op != TOKslice && oldval->op != TOKnull) -+ { -+ if (oldval->op == TOKsymoff) - { -- if (assignmentToSlicedPointer) -- { -- error("pointer %s cannot be sliced at compile time (it does not point to an array)", -- sexp->e1->toChars()); -- } -- else -- error("CTFE ICE: cannot resolve array length"); -+ originalExp->error("pointer %s cannot be sliced at compile time (it points to a static variable)", sexp->e1->toChars()); - return EXP_CANT_INTERPRET; - } -- uinteger_t dollar = resolveArrayLength(oldval); -- if (sexp->lengthVar) -+ if (assignmentToSlicedPointer) - { -- Expression *arraylen = new IntegerExp(loc, dollar, Type::tsize_t); -- ctfeStack.push(sexp->lengthVar); -- sexp->lengthVar->setValue(arraylen); -- } -- -- Expression *upper = NULL; -- Expression *lower = NULL; -- if (sexp->upr) -- upper = sexp->upr->interpret(istate); -- if (exceptionOrCantInterpret(upper)) -- { -- if (sexp->lengthVar) -- ctfeStack.pop(sexp->lengthVar); // $ is defined only in [L..U] -- return upper; -+ originalExp->error("pointer %s cannot be sliced at compile time (it does not point to an array)", -+ sexp->e1->toChars()); - } -- if (sexp->lwr) -- lower = sexp->lwr->interpret(istate); -+ else -+ originalExp->error("CTFE ICE: cannot resolve array length"); -+ return EXP_CANT_INTERPRET; -+ } -+ uinteger_t dollar = resolveArrayLength(oldval); -+ if (sexp->lengthVar) -+ { -+ Expression *arraylen = new IntegerExp(loc, dollar, Type::tsize_t); -+ ctfeStack.push(sexp->lengthVar); -+ sexp->lengthVar->setValue(arraylen); -+ } -+ -+ Expression *upper = NULL; -+ Expression *lower = NULL; -+ if (sexp->upr) -+ upper = sexp->upr->interpret(istate); -+ if (exceptionOrCantInterpret(upper)) -+ { - if (sexp->lengthVar) - ctfeStack.pop(sexp->lengthVar); // $ is defined only in [L..U] -- if (exceptionOrCantInterpret(lower)) -- return lower; -- -- size_t dim = dollar; -- size_t upperbound = upper ? upper->toInteger() : dim; -- int lowerbound = lower ? lower->toInteger() : 0; -+ return upper; -+ } -+ if (sexp->lwr) -+ lower = sexp->lwr->interpret(istate); -+ if (sexp->lengthVar) -+ ctfeStack.pop(sexp->lengthVar); // $ is defined only in [L..U] -+ if (exceptionOrCantInterpret(lower)) -+ return lower; -+ -+ size_t dim = dollar; -+ size_t upperbound = upper ? upper->toInteger() : dim; -+ int lowerbound = lower ? lower->toInteger() : 0; - -- if (!assignmentToSlicedPointer && (((int)lowerbound < 0) || (upperbound > dim))) -- { -- error("Array bounds [0..%d] exceeded in slice [%d..%d]", -- dim, lowerbound, upperbound); -- return EXP_CANT_INTERPRET; -- } -- if (upperbound == lowerbound) -- return newval; -+ if (!assignmentToSlicedPointer && (((int)lowerbound < 0) || (upperbound > dim))) -+ { -+ originalExp->error("Array bounds [0..%d] exceeded in slice [%d..%d]", -+ dim, lowerbound, upperbound); -+ return EXP_CANT_INTERPRET; -+ } -+ if (upperbound == lowerbound) -+ return newval; - -- Expression *aggregate = resolveReferences(((SliceExp *)e1)->e1, istate->localThis); -- dinteger_t firstIndex = lowerbound; -+ Expression *aggregate = resolveReferences(sexp->e1); -+ sinteger_t firstIndex = lowerbound; - -- ArrayLiteralExp *existingAE = NULL; -- StringExp *existingSE = NULL; -+ ArrayLiteralExp *existingAE = NULL; -+ StringExp *existingSE = NULL; - -- /* The only possible slicable LValue aggregates are array literals, -- * and slices of array literals. -- */ -+ /* The only possible slicable LValue aggregates are array literals, -+ * and slices of array literals. -+ */ - -- if (aggregate->op == TOKindex || aggregate->op == TOKdotvar || -- aggregate->op == TOKslice || -- aggregate->op == TOKstar || aggregate->op == TOKcall) -- { -- aggregate = aggregate->interpret(istate, ctfeNeedLvalue); -- if (exceptionOrCantInterpret(aggregate)) -- return aggregate; -- // The array could be an index of an AA. Resolve it if so. -- if (aggregate->op == TOKindex && -- ((IndexExp *)aggregate)->e1->op == TOKassocarrayliteral) -- { -- IndexExp *ix = (IndexExp *)aggregate; -- aggregate = findKeyInAA(loc, (AssocArrayLiteralExp *)ix->e1, ix->e2); -- if (!aggregate) -- { -- error("key %s not found in associative array %s", -- ix->e2->toChars(), ix->e1->toChars()); -- return EXP_CANT_INTERPRET; -- } -- if (exceptionOrCantInterpret(aggregate)) -- return aggregate; -- } -- } -- if (aggregate->op == TOKvar) -- { -- VarExp *ve = (VarExp *)(aggregate); -- VarDeclaration *v = ve->var->isVarDeclaration(); -- aggregate = v->getValue(); -- } -- if (aggregate->op == TOKslice) -- { // Slice of a slice --> change the bounds -- SliceExp *sexpold = (SliceExp *)aggregate; -- sinteger_t hi = upperbound + sexpold->lwr->toInteger(); -- firstIndex = lowerbound + sexpold->lwr->toInteger(); -- if (hi > sexpold->upr->toInteger()) -- { -- error("slice [%d..%d] exceeds array bounds [0..%lld]", -- lowerbound, upperbound, -- sexpold->upr->toInteger() - sexpold->lwr->toInteger()); -- return EXP_CANT_INTERPRET; -- } -- aggregate = sexpold->e1; -- } -- if ( isPointer(aggregate->type) ) -- { // Slicing a pointer --> change the bounds -- aggregate = sexp->e1->interpret(istate, ctfeNeedLvalue); -- dinteger_t ofs; -- aggregate = getAggregateFromPointer(aggregate, &ofs); -- if (aggregate->op == TOKnull) -- { -- error("cannot slice null pointer %s", sexp->e1->toChars()); -- return EXP_CANT_INTERPRET; -- } -- sinteger_t hi = upperbound + ofs; -- firstIndex = lowerbound + ofs; -- if (firstIndex < 0 || hi > dim) -+ if (aggregate->op == TOKindex || aggregate->op == TOKdotvar || -+ aggregate->op == TOKslice || aggregate->op == TOKcast || -+ aggregate->op == TOKstar || aggregate->op == TOKcall) -+ { -+ aggregate = aggregate->interpret(istate, ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(aggregate)) -+ return aggregate; -+ // The array could be an index of an AA. Resolve it if so. -+ if (aggregate->op == TOKindex && -+ ((IndexExp *)aggregate)->e1->op == TOKassocarrayliteral) -+ { -+ IndexExp *ix = (IndexExp *)aggregate; -+ aggregate = findKeyInAA(loc, (AssocArrayLiteralExp *)ix->e1, ix->e2); -+ if (!aggregate) - { -- error("slice [lld..%lld] exceeds memory block bounds [0..%lld]", -- firstIndex, hi, dim); -+ originalExp->error("key %s not found in associative array %s", -+ ix->e2->toChars(), ix->e1->toChars()); - return EXP_CANT_INTERPRET; - } -+ if (exceptionOrCantInterpret(aggregate)) -+ return aggregate; - } -- if (aggregate->op == TOKarrayliteral) -- existingAE = (ArrayLiteralExp *)aggregate; -- else if (aggregate->op == TOKstring) -- existingSE = (StringExp *)aggregate; -- if (existingSE && !existingSE->ownedByCtfe) -- { error("cannot modify read-only string literal %s", sexp->e1->toChars()); -+ } -+ if (aggregate->op == TOKvar) -+ { -+ VarExp *ve = (VarExp *)(aggregate); -+ VarDeclaration *v = ve->var->isVarDeclaration(); -+ aggregate = v->getValue(); -+ } -+ if (aggregate->op == TOKslice) -+ { // Slice of a slice --> change the bounds -+ SliceExp *sexpold = (SliceExp *)aggregate; -+ sinteger_t hi = upperbound + sexpold->lwr->toInteger(); -+ firstIndex = lowerbound + sexpold->lwr->toInteger(); -+ if (hi > sexpold->upr->toInteger()) -+ { -+ originalExp->error("slice [%d..%d] exceeds array bounds [0..%lld]", -+ lowerbound, upperbound, -+ sexpold->upr->toInteger() - sexpold->lwr->toInteger()); - return EXP_CANT_INTERPRET; - } -- -- if (!wantRef && newval->op == TOKslice) -+ aggregate = sexpold->e1; -+ } -+ if ( isPointer(aggregate->type) ) -+ { // Slicing a pointer --> change the bounds -+ aggregate = sexp->e1->interpret(istate, ctfeNeedLvalue); -+ dinteger_t ofs; -+ aggregate = getAggregateFromPointer(aggregate, &ofs); -+ if (aggregate->op == TOKnull) - { -- newval = resolveSlice(newval); -- if (newval == EXP_CANT_INTERPRET) -- { -- error("Compiler error: CTFE slice %s", toChars()); -- assert(0); -- } -- } -- if (wantRef && newval->op == TOKindex -- && ((IndexExp *)newval)->e1 == aggregate) -- { // It's a circular reference, resolve it now -- newval = newval->interpret(istate); -+ originalExp->error("cannot slice null pointer %s", sexp->e1->toChars()); -+ return EXP_CANT_INTERPRET; - } -- -- // For slice assignment, we check that the lengths match. -- size_t srclen = 0; -- if (newval->op == TOKarrayliteral) -- srclen = ((ArrayLiteralExp *)newval)->elements->dim; -- else if (newval->op == TOKstring) -- srclen = ((StringExp *)newval)->len; -- if (!isBlockAssignment && srclen != (upperbound - lowerbound)) -+ sinteger_t hi = upperbound + ofs; -+ firstIndex = lowerbound + ofs; -+ if (firstIndex < 0 || hi > dim) - { -- error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound); -+ originalExp->error("slice [lld..%lld] exceeds memory block bounds [0..%lld]", -+ firstIndex, hi, dim); - return EXP_CANT_INTERPRET; - } -+ } -+ if (aggregate->op == TOKarrayliteral) -+ existingAE = (ArrayLiteralExp *)aggregate; -+ else if (aggregate->op == TOKstring) -+ existingSE = (StringExp *)aggregate; -+ if (existingSE && !existingSE->ownedByCtfe) -+ { originalExp->error("cannot modify read-only string literal %s", sexp->e1->toChars()); -+ return EXP_CANT_INTERPRET; -+ } - -- if (!isBlockAssignment && newval->op == TOKarrayliteral && existingAE) -+ if (!wantRef && newval->op == TOKslice) -+ { -+ Expression *orignewval = newval; -+ newval = resolveSlice(newval); -+ if (newval == EXP_CANT_INTERPRET) - { -- Expressions *oldelems = existingAE->elements; -- Expressions *newelems = ((ArrayLiteralExp *)newval)->elements; -- for (size_t j = 0; j < newelems->dim; j++) -- { -- oldelems->tdata()[j + firstIndex] = newelems->tdata()[j]; -- } -- return newval; -+ originalExp->error("Compiler error: CTFE slice %s", orignewval->toChars()); -+ assert(0); - } -- else if (newval->op == TOKstring && existingSE) -+ } -+ if (wantRef && newval->op == TOKindex -+ && ((IndexExp *)newval)->e1 == aggregate) -+ { // It's a circular reference, resolve it now -+ newval = newval->interpret(istate); -+ } -+ -+ // For slice assignment, we check that the lengths match. -+ size_t srclen = 0; -+ if (newval->op == TOKarrayliteral) -+ srclen = ((ArrayLiteralExp *)newval)->elements->dim; -+ else if (newval->op == TOKstring) -+ srclen = ((StringExp *)newval)->len; -+ if (!isBlockAssignment && srclen != (upperbound - lowerbound)) -+ { -+ originalExp->error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound); -+ return EXP_CANT_INTERPRET; -+ } -+ -+ if (!isBlockAssignment && newval->op == TOKarrayliteral && existingAE) -+ { -+ Expressions *oldelems = existingAE->elements; -+ Expressions *newelems = ((ArrayLiteralExp *)newval)->elements; -+ Type *elemtype = existingAE->type->nextOf(); -+ for (size_t j = 0; j < newelems->dim; j++) - { -- sliceAssignStringFromString((StringExp *)existingSE, (StringExp *)newval, firstIndex); -- return newval; -- } -- else if (newval->op == TOKstring && existingAE -- && existingAE->type->isString()) -- { /* Mixed slice: it was initialized as an array literal of chars. -- * Now a slice of it is being set with a string. -- */ -- sliceAssignArrayLiteralFromString(existingAE, (StringExp *)newval, firstIndex); -- return newval; -- } -- else if (newval->op == TOKarrayliteral && existingSE) -- { /* Mixed slice: it was initialized as a string literal. -- * Now a slice of it is being set with an array literal. -- */ -- sliceAssignStringFromArrayLiteral(existingSE, (ArrayLiteralExp *)newval, firstIndex); -- return newval; -+ (*oldelems)[j + firstIndex] = paintTypeOntoLiteral(elemtype, (*newelems)[j]); - } -- else if (existingSE) -- { // String literal block slice assign -- unsigned value = newval->toInteger(); -- unsigned char *s = (unsigned char *)existingSE->string; -- for (size_t j = 0; j < upperbound-lowerbound; j++) -+ return newval; -+ } -+ else if (newval->op == TOKstring && existingSE) -+ { -+ sliceAssignStringFromString((StringExp *)existingSE, (StringExp *)newval, firstIndex); -+ return newval; -+ } -+ else if (newval->op == TOKstring && existingAE -+ && existingAE->type->isString()) -+ { /* Mixed slice: it was initialized as an array literal of chars. -+ * Now a slice of it is being set with a string. -+ */ -+ sliceAssignArrayLiteralFromString(existingAE, (StringExp *)newval, firstIndex); -+ return newval; -+ } -+ else if (newval->op == TOKarrayliteral && existingSE) -+ { /* Mixed slice: it was initialized as a string literal. -+ * Now a slice of it is being set with an array literal. -+ */ -+ sliceAssignStringFromArrayLiteral(existingSE, (ArrayLiteralExp *)newval, firstIndex); -+ return newval; -+ } -+ else if (existingSE) -+ { // String literal block slice assign -+ unsigned value = newval->toInteger(); -+ utf8_t *s = (utf8_t *)existingSE->string; -+ for (size_t j = 0; j < upperbound-lowerbound; j++) -+ { -+ switch (existingSE->sz) - { -- switch (existingSE->sz) -- { -- case 1: s[j+firstIndex] = value; break; -- case 2: ((unsigned short *)s)[j+firstIndex] = value; break; -- case 4: ((unsigned *)s)[j+firstIndex] = value; break; -- default: -- assert(0); -- break; -- } -+ case 1: s[j+firstIndex] = value; break; -+ case 2: ((unsigned short *)s)[j+firstIndex] = value; break; -+ case 4: ((unsigned *)s)[j+firstIndex] = value; break; -+ default: -+ assert(0); -+ break; - } -- if (goal == ctfeNeedNothing) -- return NULL; // avoid creating an unused literal -- SliceExp *retslice = new SliceExp(loc, existingSE, -- new IntegerExp(loc, firstIndex, Type::tsize_t), -- new IntegerExp(loc, firstIndex + upperbound-lowerbound, Type::tsize_t)); -- retslice->type = this->type; -- return retslice->interpret(istate); -- } -- else if (existingAE) -- { -- /* Block assignment, initialization of static arrays -- * x[] = e -- * x may be a multidimensional static array. (Note that this -- * only happens with array literals, never with strings). -- */ -- Expressions * w = existingAE->elements; -- assert( existingAE->type->ty == Tsarray || -- existingAE->type->ty == Tarray); -+ } -+ if (goal == ctfeNeedNothing) -+ return NULL; // avoid creating an unused literal -+ SliceExp *retslice = new SliceExp(loc, existingSE, -+ new IntegerExp(loc, firstIndex, Type::tsize_t), -+ new IntegerExp(loc, firstIndex + upperbound-lowerbound, Type::tsize_t)); -+ retslice->type = originalExp->type; -+ return retslice->interpret(istate); -+ } -+ else if (existingAE) -+ { -+ /* Block assignment, initialization of static arrays -+ * x[] = e -+ * x may be a multidimensional static array. (Note that this -+ * only happens with array literals, never with strings). -+ */ -+ Expressions * w = existingAE->elements; -+ assert( existingAE->type->ty == Tsarray || -+ existingAE->type->ty == Tarray); - #if DMDV2 -- Type *desttype = ((TypeArray *)existingAE->type)->next->castMod(0); -- bool directblk = (e2->type->toBasetype()->castMod(0)) == desttype; -+ Type *desttype = ((TypeArray *)existingAE->type)->next->castMod(0); -+ bool directblk = (e2->type->toBasetype()->castMod(0))->equals(desttype); - #else -- Type *desttype = ((TypeArray *)existingAE->type)->next; -- bool directblk = (e2->type->toBasetype()) == desttype; -+ Type *desttype = ((TypeArray *)existingAE->type)->next; -+ bool directblk = (e2->type->toBasetype())->equals(desttype); - #endif -- bool cow = !(newval->op == TOKstructliteral || newval->op == TOKarrayliteral -- || newval->op == TOKstring); -- for (size_t j = 0; j < upperbound-lowerbound; j++) -- { -- if (!directblk) -- // Multidimensional array block assign -- recursiveBlockAssign((ArrayLiteralExp *)w->tdata()[j+firstIndex], newval, wantRef); -+ bool cow = !(newval->op == TOKstructliteral || newval->op == TOKarrayliteral -+ || newval->op == TOKstring); -+ for (size_t j = 0; j < upperbound-lowerbound; j++) -+ { -+ if (!directblk) -+ // Multidimensional array block assign -+ recursiveBlockAssign((ArrayLiteralExp *)(*w)[j+firstIndex], newval, wantRef); -+ else -+ { -+ if (wantRef || cow) -+ (*existingAE->elements)[j+firstIndex] = newval; - else -- { -- if (wantRef || cow) -- existingAE->elements->tdata()[j+firstIndex] = newval; -- else -- assignInPlace(existingAE->elements->tdata()[j+firstIndex], newval); -- } -+ assignInPlace((*existingAE->elements)[j+firstIndex], newval); - } -- if (goal == ctfeNeedNothing) -- return NULL; // avoid creating an unused literal -- SliceExp *retslice = new SliceExp(loc, existingAE, -- new IntegerExp(loc, firstIndex, Type::tsize_t), -- new IntegerExp(loc, firstIndex + upperbound-lowerbound, Type::tsize_t)); -- retslice->type = this->type; -- return retslice->interpret(istate); - } -- else -- error("Slice operation %s cannot be evaluated at compile time", toChars()); -+ if (goal == ctfeNeedNothing) -+ return NULL; // avoid creating an unused literal -+ SliceExp *retslice = new SliceExp(loc, existingAE, -+ new IntegerExp(loc, firstIndex, Type::tsize_t), -+ new IntegerExp(loc, firstIndex + upperbound-lowerbound, Type::tsize_t)); -+ retslice->type = originalExp->type; -+ return retslice->interpret(istate); - } - else - { -- error("%s cannot be evaluated at compile time", toChars()); -+ originalExp->error("Slice operation %s = %s cannot be evaluated at compile time", sexp->toChars(), newval->toChars()); -+ return EXP_CANT_INTERPRET; - } -- return returnValue; - } - - Expression *AssignExp::interpret(InterState *istate, CtfeGoal goal) -@@ -3509,29 +4266,30 @@ Expression *AssignExp::interpret(InterSt - return interpretAssignCommon(istate, goal, NULL); - } - --#define BIN_ASSIGN_INTERPRET_CTFE(op, ctfeOp) \ --Expression *op##AssignExp::interpret(InterState *istate, CtfeGoal goal) \ --{ \ -- return interpretAssignCommon(istate, goal, &ctfeOp); \ --} -- --#define BIN_ASSIGN_INTERPRET(op) BIN_ASSIGN_INTERPRET_CTFE(op, op) -- --BIN_ASSIGN_INTERPRET(Add) --BIN_ASSIGN_INTERPRET(Min) --BIN_ASSIGN_INTERPRET_CTFE(Cat, ctfeCat) --BIN_ASSIGN_INTERPRET(Mul) --BIN_ASSIGN_INTERPRET(Div) --BIN_ASSIGN_INTERPRET(Mod) --BIN_ASSIGN_INTERPRET(Shl) --BIN_ASSIGN_INTERPRET(Shr) --BIN_ASSIGN_INTERPRET(Ushr) --BIN_ASSIGN_INTERPRET(And) --BIN_ASSIGN_INTERPRET(Or) --BIN_ASSIGN_INTERPRET(Xor) -+Expression *BinAssignExp::interpret(InterState *istate, CtfeGoal goal) -+{ -+ switch(op) -+ { -+ case TOKaddass: return interpretAssignCommon(istate, goal, &Add); -+ case TOKminass: return interpretAssignCommon(istate, goal, &Min); -+ case TOKcatass: return interpretAssignCommon(istate, goal, &ctfeCat); -+ case TOKmulass: return interpretAssignCommon(istate, goal, &Mul); -+ case TOKdivass: return interpretAssignCommon(istate, goal, &Div); -+ case TOKmodass: return interpretAssignCommon(istate, goal, &Mod); -+ case TOKshlass: return interpretAssignCommon(istate, goal, &Shl); -+ case TOKshrass: return interpretAssignCommon(istate, goal, &Shr); -+ case TOKushrass: return interpretAssignCommon(istate, goal, &Ushr); -+ case TOKandass: return interpretAssignCommon(istate, goal, &And); -+ case TOKorass: return interpretAssignCommon(istate, goal, &Or); -+ case TOKxorass: return interpretAssignCommon(istate, goal, &Xor); - #if DMDV2 --BIN_ASSIGN_INTERPRET(Pow) -+ case TOKpowass: return interpretAssignCommon(istate, goal, &Pow); - #endif -+ default: -+ assert(0); -+ return NULL; -+ } -+} - - Expression *PostExp::interpret(InterState *istate, CtfeGoal goal) - { -@@ -3891,7 +4649,7 @@ Expression *CallExp::interpret(InterStat - Expression * pe = ((PtrExp*)ecall)->e1; - if (pe->op == TOKvar) { - VarDeclaration *vd = ((VarExp *)((PtrExp*)ecall)->e1)->var->isVarDeclaration(); -- if (vd && vd->getValue() && vd->getValue()->op == TOKsymoff) -+ if (vd && vd->hasValue() && vd->getValue()->op == TOKsymoff) - fd = ((SymOffExp *)vd->getValue())->var->isFuncDeclaration(); - else - { -@@ -3932,7 +4690,7 @@ Expression *CallExp::interpret(InterStat - else if (ecall->op == TOKvar) - { - VarDeclaration *vd = ((VarExp *)ecall)->var->isVarDeclaration(); -- if (vd && vd->getValue()) -+ if (vd && vd->hasValue()) - ecall = vd->getValue(); - else // Calling a function - fd = ((VarExp *)e1)->var->isFuncDeclaration(); -@@ -3953,7 +4711,7 @@ Expression *CallExp::interpret(InterStat - - TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL; - if (!tf) -- { // DAC: This should never happen, it's an internal compiler error. -+ { // This should never happen, it's an internal compiler error. - //printf("ecall=%s %d %d\n", ecall->toChars(), ecall->op, TOKcall); - if (ecall->op == TOKidentifier) - error("cannot evaluate %s at compile time. Circular reference?", toChars()); -@@ -3982,12 +4740,25 @@ Expression *CallExp::interpret(InterStat - { // Make a virtual function call. - Expression *thisval = pthis; - if (pthis->op == TOKvar) -- { assert(((VarExp*)thisval)->var->isVarDeclaration()); -- thisval = ((VarExp*)thisval)->var->isVarDeclaration()->getValue(); -+ { -+ VarDeclaration *vthis = ((VarExp*)thisval)->var->isVarDeclaration(); -+ assert(vthis); -+ thisval = getVarExp(loc, istate, vthis, ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(thisval)) -+ return thisval; - // If it is a reference, resolve it - if (thisval->op != TOKnull && thisval->op != TOKclassreference) - thisval = pthis->interpret(istate); - } -+ else if (pthis->op == TOKsymoff) -+ { -+ VarDeclaration *vthis = ((SymOffExp*)thisval)->var->isVarDeclaration(); -+ assert(vthis); -+ thisval = getVarExp(loc, istate, vthis, ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(thisval)) -+ return thisval; -+ } -+ - // Get the function from the vtable of the original class - ClassDeclaration *cd; - if (thisval && thisval->op == TOKnull) -@@ -4036,6 +4807,8 @@ Expression *CallExp::interpret(InterStat - } - return e; - } -+ if (fd->dArrayOp) -+ return fd->dArrayOp->interpret(istate, arguments, pthis); - if (!fd->fbody) - { - error("%s cannot be interpreted at compile time," -@@ -4070,7 +4843,7 @@ Expression *CommaExp::interpret(InterSta - InterState istateComma; - if (!istate && firstComma->e1->op == TOKdeclaration) - { -- ctfeStack.startFrame(); -+ ctfeStack.startFrame(NULL); - istate = &istateComma; - } - -@@ -4098,7 +4871,7 @@ Expression *CommaExp::interpret(InterSta - if (exceptionOrCantInterpret(newval)) - { - if (istate == &istateComma) -- ctfeStack.endFrame(0); -+ ctfeStack.endFrame(); - return newval; - } - if (newval != EXP_VOID_INTERPRET) -@@ -4120,7 +4893,7 @@ Expression *CommaExp::interpret(InterSta - } - // If we created a temporary stack frame, end it now. - if (istate == &istateComma) -- ctfeStack.endFrame(0); -+ ctfeStack.endFrame(); - return e; - } - -@@ -4132,7 +4905,7 @@ Expression *CondExp::interpret(InterStat - Expression *e; - if ( isPointer(econd->type) ) - { -- e = econd->interpret(istate, ctfeNeedLvalue); -+ e = econd->interpret(istate); - if (exceptionOrCantInterpret(e)) - return e; - if (e->op != TOKnull) -@@ -4211,22 +4984,40 @@ Expression *IndexExp::interpret(InterSta - { - dinteger_t len = ArrayLength(Type::tsize_t, agg)->toInteger(); - //Type *pointee = ((TypePointer *)agg->type)->next; -- if ((indx + ofs) < 0 || (indx+ofs) > len) -+ if ((sinteger_t)(indx + ofs) < 0 || (indx+ofs) > len) - { - error("pointer index [%lld] exceeds allocated memory block [0..%lld]", - indx+ofs, len); - return EXP_CANT_INTERPRET; - } -+ if (goal == ctfeNeedLvalueRef) -+ { -+ // if we need a reference, IndexExp shouldn't be interpreting -+ // the expression to a value, it should stay as a reference -+ Expression *e = new IndexExp(loc, agg, -+ ofs ? new IntegerExp(loc,indx + ofs, e2->type) : e2); -+ e->type = type; -+ return e; -+ } - return ctfeIndex(loc, type, agg, indx+ofs); - } - else - { // Pointer to a non-array variable -+ if (agg->op == TOKsymoff) -+ { -+ error("mutable variable %s cannot be read at compile time, even through a pointer", ((SymOffExp *)agg)->var->toChars()); -+ return EXP_CANT_INTERPRET; -+ } - if ((indx + ofs) != 0) - { - error("pointer index [%lld] lies outside memory block [0..1]", - indx+ofs); - return EXP_CANT_INTERPRET; - } -+ if (goal == ctfeNeedLvalueRef) -+ { -+ return paintTypeOntoLiteral(type, agg); -+ } - return agg->interpret(istate); - } - } -@@ -4239,7 +5030,7 @@ Expression *IndexExp::interpret(InterSta - - if (e1->op == TOKnull) - { -- if (goal == ctfeNeedLvalue && e1->type->ty == Taarray) -+ if (goal == ctfeNeedLvalue && e1->type->ty == Taarray && modifiable) - return paintTypeOntoLiteral(type, e1); - error("cannot index null array %s", this->e1->toChars()); - return EXP_CANT_INTERPRET; -@@ -4374,6 +5165,11 @@ Expression *SliceExp::interpret(InterSta - error("cannot slice null pointer %s", this->e1->toChars()); - return EXP_CANT_INTERPRET; - } -+ if (agg->op == TOKsymoff) -+ { -+ error("slicing pointers to static variables is not supported in CTFE"); -+ return EXP_CANT_INTERPRET; -+ } - if (agg->op != TOKarrayliteral && agg->op != TOKstring) - { - error("pointer %s cannot be sliced at compile time (it does not point to an array)", -@@ -4633,7 +5429,7 @@ Expression *CastExp::interpret(InterStat - e->type = type; - return e; - } -- if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type != e1->type) -+ if (e1->op == TOKindex && !((IndexExp *)e1)->e1->type->equals(e1->type)) - { // type painting operation - IndexExp *ie = (IndexExp *)e1; - e = new IndexExp(e1->loc, ie->e1, ie->e2); -@@ -4647,7 +5443,7 @@ Expression *CastExp::interpret(InterStat - { ArrayLiteralExp *ale = (ArrayLiteralExp *)ie->e1; - uinteger_t indx = ie->e2->toInteger(); - if (indx < ale->elements->dim) -- xx = ale->elements->tdata()[indx]; -+ xx = (*ale->elements)[indx]; - } - if (xx && xx->op == TOKindex) - origType = ((IndexExp *)xx)->e1->type->nextOf(); -@@ -4667,7 +5463,7 @@ Expression *CastExp::interpret(InterStat - } - if (e1->op == TOKaddress) - { -- Type *origType = ((AddrExp *)e1)->type; -+ Type *origType = ((AddrExp *)e1)->e1->type; - if (isSafePointerCast(origType, pointee)) - { - e = new AddrExp(loc, ((AddrExp *)e1)->e1); -@@ -4675,17 +5471,21 @@ Expression *CastExp::interpret(InterStat - return e; - } - } -- if (e1->op == TOKvar) -+ if (e1->op == TOKvar || e1->op == TOKsymoff) - { // type painting operation -- Type *origType = ((VarExp *)e1)->var->type; -+ Type *origType = (e1->op == TOKvar) ? ((VarExp *)e1)->var->type : -+ ((SymOffExp *)e1)->var->type; - if (castBackFromVoid && !isSafePointerCast(origType, pointee)) - { - error("using void* to reinterpret cast from %s* to %s* is not supported in CTFE", - origType->toChars(), pointee->toChars()); - return EXP_CANT_INTERPRET; - } -- e = new VarExp(loc, ((VarExp *)e1)->var); -- e->type = type; -+ if (e1->op == TOKvar) -+ e = new VarExp(loc, ((VarExp *)e1)->var); -+ else -+ e = new SymOffExp(loc, ((SymOffExp *)e1)->var, ((SymOffExp *)e1)->offset); -+ e->type = to; - return e; - } - -@@ -4768,17 +5568,14 @@ Expression *AssertExp::interpret(InterSt - } - else - error("%s failed", toChars()); -- goto Lcant; -+ return EXP_CANT_INTERPRET; - } - else - { - error("%s is not a compile-time boolean expression", e1->toChars()); -- goto Lcant; -+ return EXP_CANT_INTERPRET; - } - return e1; -- --Lcant: -- return EXP_CANT_INTERPRET; - } - - Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal) -@@ -4827,12 +5624,39 @@ Expression *PtrExp::interpret(InterState - #else // this is required for D1, where structs return *this instead of 'this'. - else if (e1->op == TOKthis) - { -- if(istate->localThis) -- return istate->localThis->interpret(istate); -+ if (ctfeStack.getThis()) -+ return ctfeStack.getThis()->interpret(istate); - } - #endif - else -- { // It's possible we have an array bounds error. We need to make sure it -+ { -+ // Check for .classinfo, which is lowered in the semantic pass into **(class). -+ if (e1->op == TOKstar && e1->type->ty == Tpointer && isTypeInfo_Class(e1->type->nextOf())) -+ { -+ e = (((PtrExp *)e1)->e1)->interpret(istate, ctfeNeedLvalue); -+ if (exceptionOrCantInterpret(e)) -+ return e; -+ if (e->op == TOKnull) -+ { -+ error("Null pointer dereference evaluating typeid. '%s' is null", ((PtrExp *)e1)->e1->toChars()); -+ return EXP_CANT_INTERPRET; -+ } -+ if (e->op != TOKclassreference) -+ { error("CTFE internal error determining classinfo"); -+ return EXP_CANT_INTERPRET; -+ } -+ ClassDeclaration *cd = ((ClassReferenceExp *)e)->originalClass(); -+ assert(cd); -+ -+ // Create the classinfo, if it doesn't yet exist. -+ // TODO: This belongs in semantic, CTFE should not have to do this. -+ if (!cd->vclassinfo) -+ cd->vclassinfo = new TypeInfoClassDeclaration(cd->type); -+ e = new SymOffExp(loc, cd->vclassinfo, 0); -+ e->type = type; -+ return e; -+ } -+ // It's possible we have an array bounds error. We need to make sure it - // errors with this line number, not the one where the pointer was set. - e = e1->interpret(istate, ctfeNeedLvalue); - if (exceptionOrCantInterpret(e)) -@@ -4840,10 +5664,13 @@ Expression *PtrExp::interpret(InterState - if (!(e->op == TOKvar || e->op == TOKdotvar || e->op == TOKindex - || e->op == TOKslice || e->op == TOKaddress)) - { -- error("dereference of invalid pointer '%s'", e->toChars()); -+ if (e->op == TOKsymoff) -+ error("cannot dereference pointer to static variable %s at compile time", ((SymOffExp *)e)->var->toChars()); -+ else -+ error("dereference of invalid pointer '%s'", e->toChars()); - return EXP_CANT_INTERPRET; - } -- if (goal != ctfeNeedLvalue) -+ if (goal != ctfeNeedLvalue && goal != ctfeNeedLvalueRef) - { - if (e->op == TOKindex && e->type->ty == Tpointer) - { -@@ -4902,8 +5729,26 @@ Expression *PtrExp::interpret(InterState - if (e->op == TOKaddress) - { - e = ((AddrExp*)e)->e1; -- if (e->op == TOKdotvar || e->op == TOKindex) -+ // We're changing *&e to e. -+ // We needed the AddrExp to deal with type painting expressions -+ // we couldn't otherwise express. Now that the type painting is -+ // undone, we must simplify them. This applies to references -+ // (which will be a DotVarExp or IndexExp) and to local structs -+ // (which will be a VarExp). -+ -+ // We sometimes use DotVarExp and IndexExp to represent pointers, -+ // so in that case, they shouldn't be simplified. -+ -+ bool isCtfePtr = (e->op == TOKdotvar || e->op == TOKindex) -+ && isPointer(e->type); -+ -+ // We also must not simplify if it is already a struct Literal -+ // or array literal, because it has already been interpreted. -+ if ( !isCtfePtr && e->op != TOKstructliteral && -+ e->op != TOKassocarrayliteral && e->op != TOKarrayliteral) -+ { - e = e->interpret(istate, goal); -+ } - } - else if (e->op == TOKvar) - { -@@ -4919,7 +5764,7 @@ Expression *PtrExp::interpret(InterState - error("dereference of null pointer '%s'", e1->toChars()); - return EXP_CANT_INTERPRET; - } -- e->type = type; -+ e = paintTypeOntoLiteral(type, e); - } - - #if LOG -@@ -4952,14 +5797,27 @@ Expression *DotVarExp::interpret(InterSt - ex = ((AddrExp *)ex)->e1; - VarDeclaration *v = var->isVarDeclaration(); - if (!v) -+ { - error("CTFE internal error: %s", toChars()); -+ return EXP_CANT_INTERPRET; -+ } - if (ex->op == TOKnull && ex->type->toBasetype()->ty == Tclass) - { error("class '%s' is null and cannot be dereferenced", e1->toChars()); - return EXP_CANT_INTERPRET; - } -+ if (ex->op == TOKnull) -+ { error("dereference of null pointer '%s'", e1->toChars()); -+ return EXP_CANT_INTERPRET; -+ } - if (ex->op == TOKstructliteral || ex->op == TOKclassreference) - { - StructLiteralExp *se = ex->op == TOKclassreference ? ((ClassReferenceExp *)ex)->value : (StructLiteralExp *)ex; -+ /* We don't know how to deal with overlapping fields -+ */ -+ if (se->sd->hasUnions) -+ { error("Unions with overlapping fields are not yet supported in CTFE"); -+ return EXP_CANT_INTERPRET; -+ } - // We can't use getField, because it makes a copy - int i = -1; - if (ex->op == TOKclassreference) -@@ -4971,7 +5829,7 @@ Expression *DotVarExp::interpret(InterSt - error("couldn't find field %s of type %s in %s", v->toChars(), type->toChars(), se->toChars()); - return EXP_CANT_INTERPRET; - } -- e = se->elements->tdata()[i]; -+ e = (*se->elements)[i]; - if (goal == ctfeNeedLvalue || goal == ctfeNeedLvalueRef) - { - // If it is an lvalue literal, return it... -@@ -4986,7 +5844,7 @@ Expression *DotVarExp::interpret(InterSt - * CastExp. - */ - if (goal == ctfeNeedLvalue && e->op == TOKindex && -- e->type == type && -+ e->type->equals(type) && - isPointer(type) ) - return e; - // ...Otherwise, just return the (simplified) dotvar expression -@@ -4996,8 +5854,8 @@ Expression *DotVarExp::interpret(InterSt - } - if (!e) - { -- error("couldn't find field %s in %s", v->toChars(), type->toChars()); -- e = EXP_CANT_INTERPRET; -+ error("Internal Compiler Error: Null field %s", v->toChars()); -+ return EXP_CANT_INTERPRET; - } - // If it is an rvalue literal, return it... - if (e->op == TOKstructliteral || e->op == TOKarrayliteral || -@@ -5006,8 +5864,7 @@ Expression *DotVarExp::interpret(InterSt - if (e->op == TOKvoid) - { - VoidInitExp *ve = (VoidInitExp *)e; -- error("cannot read uninitialized variable %s in ctfe", toChars()); -- ve->var->error("was uninitialized and used before set"); -+ error("cannot read uninitialized variable %s in CTFE", ve->var->toChars()); - return EXP_CANT_INTERPRET; - } - if ( isPointer(type) ) -@@ -5053,13 +5910,15 @@ Expression *RemoveExp::interpret(InterSt - Expressions *valuesx = aae->values; - size_t removed = 0; - for (size_t j = 0; j < valuesx->dim; ++j) -- { Expression *ekey = keysx->tdata()[j]; -+ { -+ Expression *ekey = (*keysx)[j]; - int eq = ctfeEqual(loc, TOKequal, ekey, index); - if (eq) - ++removed; - else if (removed != 0) -- { keysx->tdata()[j - removed] = ekey; -- valuesx->tdata()[j - removed] = valuesx->tdata()[j]; -+ { -+ (*keysx)[j - removed] = ekey; -+ (*valuesx)[j - removed] = (*valuesx)[j]; - } - } - valuesx->dim = valuesx->dim - removed; -@@ -5146,11 +6005,7 @@ Expression *interpret_aaApply(InterState - assert(fd && fd->fbody); - assert(fd->parameters); - int numParams = fd->parameters->dim; -- assert(numParams == 1 || numParams==2); -- -- Type *valueType = fd->parameters->tdata()[numParams-1]->type; -- Type *keyType = numParams == 2 ? fd->parameters->tdata()[0]->type -- : Type::tsize_t; -+ assert(numParams == 1 || numParams == 2); - - Parameter *valueArg = Parameter::getNth(((TypeFunction *)fd->type)->parameters, numParams - 1); - bool wantRefValue = 0 != (valueArg->storageClass & (STCout | STCref)); -@@ -5165,8 +6020,8 @@ Expression *interpret_aaApply(InterState - - for (size_t i = 0; i < ae->keys->dim; ++i) - { -- Expression *ekey = ae->keys->tdata()[i]; -- Expression *evalue = ae->values->tdata()[i]; -+ Expression *ekey = (*ae->keys)[i]; -+ Expression *evalue = (*ae->values)[i]; - if (wantRefValue) - { Type *t = evalue->type; - evalue = new IndexExp(deleg->loc, ae, ekey); -@@ -5217,8 +6072,8 @@ Expression *foreachApplyUtf(InterState * - assert(fd->parameters); - int numParams = fd->parameters->dim; - assert(numParams == 1 || numParams==2); -- Type *charType = fd->parameters->tdata()[numParams-1]->type; -- Type *indexType = numParams == 2 ? fd->parameters->tdata()[0]->type -+ Type *charType = (*fd->parameters)[numParams-1]->type; -+ Type *indexType = numParams == 2 ? (*fd->parameters)[0]->type - : Type::tsize_t; - uinteger_t len = resolveArrayLength(str); - if (len == 0) -@@ -5243,7 +6098,7 @@ Expression *foreachApplyUtf(InterState * - Expression *eresult; - - // Buffers for encoding; also used for decoding array literals -- unsigned char utf8buf[4]; -+ utf8_t utf8buf[4]; - unsigned short utf16buf[2]; - - size_t start = rvs ? len : 0; -@@ -5270,9 +6125,10 @@ Expression *foreachApplyUtf(InterState * - --indx; - buflen = 1; - while (indx > 0 && buflen < 4) -- { Expression * r = ale->elements->tdata()[indx]; -+ { -+ Expression * r = (*ale->elements)[indx]; - assert(r->op == TOKint64); -- unsigned char x = (unsigned char)(((IntegerExp *)r)->value); -+ utf8_t x = (utf8_t)(((IntegerExp *)r)->value); - if ( (x & 0xC0) != 0x80) - break; - ++buflen; -@@ -5282,9 +6138,9 @@ Expression *foreachApplyUtf(InterState * - buflen = (indx + 4 > len) ? len - indx : 4; - for (int i = 0; i < buflen; ++i) - { -- Expression * r = ale->elements->tdata()[indx + i]; -+ Expression * r = (*ale->elements)[indx + i]; - assert(r->op == TOKint64); -- utf8buf[i] = (unsigned char)(((IntegerExp *)r)->value); -+ utf8buf[i] = (utf8_t)(((IntegerExp *)r)->value); - } - n = 0; - errmsg = utf_decodeChar(&utf8buf[0], buflen, &n, &rawvalue); -@@ -5294,7 +6150,7 @@ Expression *foreachApplyUtf(InterState * - { // find the start of the string - --indx; - buflen = 1; -- Expression * r = ale->elements->tdata()[indx]; -+ Expression * r = (*ale->elements)[indx]; - assert(r->op == TOKint64); - unsigned short x = (unsigned short)(((IntegerExp *)r)->value); - if (indx > 0 && x >= 0xDC00 && x <= 0xDFFF) -@@ -5307,7 +6163,7 @@ Expression *foreachApplyUtf(InterState * - buflen = (indx + 2 > len) ? len - indx : 2; - for (int i=0; i < buflen; ++i) - { -- Expression * r = ale->elements->tdata()[indx + i]; -+ Expression * r = (*ale->elements)[indx + i]; - assert(r->op == TOKint64); - utf16buf[i] = (unsigned short)(((IntegerExp *)r)->value); - } -@@ -5319,7 +6175,7 @@ Expression *foreachApplyUtf(InterState * - if (rvs) - --indx; - -- Expression * r = ale->elements->tdata()[indx]; -+ Expression * r = (*ale->elements)[indx]; - assert(r->op == TOKint64); - rawvalue = ((IntegerExp *)r)->value; - n = 1; -@@ -5340,13 +6196,13 @@ Expression *foreachApplyUtf(InterState * - case 1: - if (rvs) - { // find the start of the string -- unsigned char *s = (unsigned char *)se->string; -+ utf8_t *s = (utf8_t *)se->string; - --indx; - while (indx > 0 && ((s[indx]&0xC0)==0x80)) - --indx; - saveindx = indx; - } -- errmsg = utf_decodeChar((unsigned char *)se->string, se->len, &indx, &rawvalue); -+ errmsg = utf_decodeChar((utf8_t *)se->string, se->len, &indx, &rawvalue); - if (rvs) - indx = saveindx; - break; -@@ -5462,7 +6318,7 @@ Expression *evaluateIfBuiltin(InterState - } - if (!pthis) - { -- enum BUILTIN b = fd->isBuiltin(); -+ BUILTIN b = fd->isBuiltin(); - if (b) - { Expressions args; - args.setDim(nargs); -@@ -5525,10 +6381,10 @@ Expression *evaluateIfBuiltin(InterState - assert(arguments->dim <= se->elements->dim); - for (int i = 0; i < arguments->dim; ++i) - { -- Expression *e = (*arguments)[i]->interpret(istate); -+ e = (*arguments)[i]->interpret(istate); - if (exceptionOrCantInterpret(e)) - return e; -- se->elements->tdata()[i] = e; -+ (*se->elements)[i] = e; - } - return EXP_VOID_INTERPRET; - } ---- a/src/gcc/d/dfrontend/intrange.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/intrange.h 2014-04-01 16:32:51.000000000 +0100 -@@ -12,9 +12,9 @@ - #ifndef DMD_SXNUM_H - #define DMD_SXNUM_H - --#include "port.h" // for uinteger_t --struct Type; --struct Expression; -+#include "mars.h" // for uinteger_t -+class Type; -+class Expression; - - /** - This class represents a "sign-extended number", i.e. a 65-bit number, which can ---- a/src/gcc/d/dfrontend/json.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/json.c 2014-04-01 16:32:51.000000000 +0100 -@@ -68,10 +68,9 @@ struct JsonOut - void property(const char *name, Type* type); - void property(const char *name, const char *deconame, Type* type); - void property(const char *name, Parameters* parameters); -- void property(const char *name, Expressions* expressions); -- void property(const char *name, enum TRUST trust); -- void property(const char *name, enum PURE purity); -- void property(const char *name, enum LINK linkage); -+ void property(const char *name, TRUST trust); -+ void property(const char *name, PURE purity); -+ void property(const char *name, LINK linkage); - }; - - -@@ -83,7 +82,7 @@ void json_generate(OutBuffer *buf, Modul - for (size_t i = 0; i < modules->dim; i++) - { Module *m = (*modules)[i]; - if (global.params.verbose) -- fprintf(stdmsg, "json gen %s\n", m->toChars()); -+ fprintf(global.stdmsg, "json gen %s\n", m->toChars()); - m->toJson(&json); - } - json.arrayEnd(); -@@ -129,7 +128,7 @@ void JsonOut::stringPart(const char *s) - { - for (; *s; s++) - { -- unsigned char c = (unsigned char) *s; -+ utf8_t c = (utf8_t) *s; - switch (c) - { - case '\n': -@@ -308,7 +307,7 @@ void JsonOut::propertyBool(const char *n - } - - --void JsonOut::property(const char *name, enum TRUST trust) -+void JsonOut::property(const char *name, TRUST trust) - { - switch (trust) - { -@@ -330,7 +329,7 @@ void JsonOut::property(const char *name, - } - } - --void JsonOut::property(const char *name, enum PURE purity) -+void JsonOut::property(const char *name, PURE purity) - { - switch (purity) - { -@@ -355,7 +354,7 @@ void JsonOut::property(const char *name, - } - } - --void JsonOut::property(const char *name, enum LINK linkage) -+void JsonOut::property(const char *name, LINK linkage) - { - switch (linkage) - { -@@ -396,7 +395,7 @@ void JsonOut::propertyStorageClass(const - { char tmp[20]; - const char *p = StorageClassDeclaration::stcToChars(tmp, stc); - assert(p); -- assert(strlen(p) < sizeof(tmp)); -+ assert(strlen(p) < sizeof(tmp) / sizeof(tmp[0])); - if (p[0] == '@') - { - indent(); -@@ -545,7 +544,7 @@ void TypeQualified::toJson(JsonOut *json - json->arrayStart(); - - for (size_t i = 0; i < idents.dim; i++) -- { Identifier *ident = idents[i]; -+ { RootObject *ident = idents[i]; - json->item(ident->toChars()); - } - -@@ -629,9 +628,11 @@ void Dsymbol::toJson(JsonOut *json) - - void Dsymbol::jsonProperties(JsonOut *json) - { -- json->property("name", toChars()); - if (!isTemplateDeclaration()) // TemplateDeclaration::kind() acts weird sometimes -+ { -+ json->property("name", toChars()); - json->property("kind", kind()); -+ } - - if (prot() != PROTpublic) - json->property("protection", Pprotectionnames[prot()]); -@@ -805,7 +806,6 @@ void ConditionalDeclaration::toJson(Json - - - void ClassInfoDeclaration::toJson(JsonOut *json) { } --void ModuleInfoDeclaration::toJson(JsonOut *json) { } - void TypeInfoDeclaration::toJson(JsonOut *json) { } - #if DMDV2 - void PostBlitDeclaration::toJson(JsonOut *json) { } -@@ -848,6 +848,16 @@ void Declaration::jsonProperties(JsonOut - } - } - -+void TemplateDeclaration::jsonProperties(JsonOut *json) -+{ -+ Dsymbol::jsonProperties(json); -+ -+ if (onemember && onemember->isCtorDeclaration()) -+ json->property("name", "this"); // __ctor -> this -+ else -+ json->property("name", ident->toChars()); // Foo(T) -> Foo -+} -+ - void TypedefDeclaration::toJson(JsonOut *json) - { - json->objectStart(); -@@ -960,9 +970,10 @@ void TemplateDeclaration::toJson(JsonOut - if (s->isTemplateThisParameter()) - json->property("kind", "this"); - else --#endif - json->property("kind", "type"); -- -+#else -+ json->property("kind", "type"); -+#endif - json->property("type", "deco", type->specType); - - json->property("default", "defaultDeco", type->defaultType); -@@ -1071,7 +1082,7 @@ void VarDeclaration::toJson(JsonOut *jso - if (init) - json->property("init", init->toChars()); - -- if (storage_class & STCfield) -+ if (isField()) - json->property("offset", offset); - - if (alignment && alignment != STRUCTALIGN_DEFAULT) ---- a/src/gcc/d/dfrontend/lexer.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/lexer.c 2014-04-01 16:32:51.000000000 +0100 -@@ -30,12 +30,7 @@ - #include "id.h" - #include "module.h" - --#if _WIN32 && __DMC__ --// from \dm\src\include\setlocal.h --extern "C" char * __cdecl __locale_decpoint; --#endif -- --extern int HtmlNamedEntity(unsigned char *p, size_t length); -+extern int HtmlNamedEntity(utf8_t *p, size_t length); - - #define LS 0x2028 // UTF line separator - #define PS 0x2029 // UTF paragraph separator -@@ -52,9 +47,9 @@ const int CMoctal = 0x1; - const int CMhex = 0x2; - const int CMidchar = 0x4; - --inline unsigned char isoctal (unsigned char c) { return cmtable[c] & CMoctal; } --inline unsigned char ishex (unsigned char c) { return cmtable[c] & CMhex; } --inline unsigned char isidchar(unsigned char c) { return cmtable[c] & CMidchar; } -+inline bool isoctal (utf8_t c) { return cmtable[c] & CMoctal; } -+inline bool ishex (utf8_t c) { return cmtable[c] & CMhex; } -+inline bool isidchar(utf8_t c) { return cmtable[c] & CMidchar; } - - static void cmtable_init() - { -@@ -90,7 +85,7 @@ void *Token::operator new(size_t size) - #ifdef DEBUG - void Token::print() - { -- fprintf(stdmsg, "%s\n", toChars()); -+ fprintf(stderr, "%s\n", toChars()); - } - #endif - -@@ -102,22 +97,14 @@ const char *Token::toChars() - switch (value) - { - case TOKint32v: --#ifdef IN_GCC -- sprintf(buffer,"%d",(d_int32)int64value); --#else - sprintf(buffer,"%d",int32value); --#endif - break; - - case TOKuns32v: - case TOKcharv: - case TOKwcharv: - case TOKdcharv: --#ifdef IN_GCC -- sprintf(buffer,"%uU",(d_uns32)uns64value); --#else - sprintf(buffer,"%uU",uns32value); --#endif - break; - - case TOKint64v: -@@ -128,20 +115,6 @@ const char *Token::toChars() - sprintf(buffer,"%lluUL",(ulonglong)uns64value); - break; - --#ifdef IN_GCC -- case TOKfloat32v: -- case TOKfloat64v: -- case TOKfloat80v: -- float80value.format(buffer, sizeof(buffer)); -- break; -- case TOKimaginary32v: -- case TOKimaginary64v: -- case TOKimaginary80v: -- float80value.format(buffer, sizeof(buffer)); -- // %% buffer -- strcat(buffer, "i"); -- break; --#else - case TOKfloat32v: - ld_sprint(buffer, 'g', float80value); - strcat(buffer, "f"); -@@ -170,7 +143,6 @@ const char *Token::toChars() - ld_sprint(buffer, 'g', float80value); - strcat(buffer, "Li"); - break; --#endif - - case TOKstring: - { OutBuffer buf; -@@ -179,7 +151,7 @@ const char *Token::toChars() - for (size_t i = 0; i < len; ) - { unsigned c; - -- utf_decodeChar((unsigned char *)ustring, len, &i, &c); -+ utf_decodeChar((utf8_t *)ustring, len, &i, &c); - switch (c) - { - case 0: -@@ -224,7 +196,7 @@ const char *Token::toChars() - return p; - } - --const char *Token::toChars(enum TOK value) -+const char *Token::toChars(TOK value) - { const char *p; - static char buffer[3 + 3 * sizeof(value) + 1]; - -@@ -243,10 +215,10 @@ StringTable Lexer::stringtable; - OutBuffer Lexer::stringbuffer; - - Lexer::Lexer(Module *mod, -- unsigned char *base, size_t begoffset, size_t endoffset, -+ utf8_t *base, size_t begoffset, size_t endoffset, - int doDocComment, int commentToken) -- : loc(mod, 1) - { -+ scanloc = Loc(mod, 1); - //printf("Lexer::Lexer(%p,%d)\n",base,length); - //printf("lexer.mod = %p, %p\n", mod, this->loc.mod); - memset(&token,0,sizeof(token)); -@@ -266,7 +238,7 @@ Lexer::Lexer(Module *mod, - { - p += 2; - while (1) -- { unsigned char c = *p; -+ { utf8_t c = *p; - switch (c) - { - case '\n': -@@ -294,7 +266,7 @@ Lexer::Lexer(Module *mod, - } - break; - } -- loc.linnum = 2; -+ scanloc.linnum = 2; - } - } - -@@ -303,7 +275,7 @@ void Lexer::error(const char *format, .. - { - va_list ap; - va_start(ap, format); -- ::verror(tokenLoc(), format, ap); -+ ::verror(token.loc, format, ap); - va_end(ap); - } - -@@ -319,16 +291,15 @@ void Lexer::deprecation(const char *form - { - va_list ap; - va_start(ap, format); -- ::vdeprecation(tokenLoc(), format, ap); -+ ::vdeprecation(token.loc, format, ap); - va_end(ap); - } - - TOK Lexer::nextToken() --{ Token *t; -- -+{ - if (token.next) - { -- t = token.next; -+ Token *t = token.next; - memcpy(&token,t,sizeof(Token)); - t->next = freelist; - freelist = t; -@@ -342,8 +313,8 @@ TOK Lexer::nextToken() - } - - Token *Lexer::peek(Token *ct) --{ Token *t; -- -+{ -+ Token *t; - if (ct->next) - t = ct->next; - else -@@ -448,7 +419,7 @@ int Lexer::isValidIdentifier(char *p) - while (p[idx]) - { dchar_t dc; - -- const char *q = utf_decodeChar((unsigned char *)p, len, &idx, &dc); -+ const char *q = utf_decodeChar((utf8_t *)p, len, &idx, &dc); - if (q) - goto Linvalid; - -@@ -467,7 +438,7 @@ Linvalid: - - void Lexer::scan(Token *t) - { -- unsigned lastLine = loc.linnum; -+ unsigned lastLine = scanloc.linnum; - unsigned linnum; - - t->blockComment = NULL; -@@ -476,6 +447,7 @@ void Lexer::scan(Token *t) - { - t->ptr = p; - //printf("p = %p, *p = '%c'\n",p,*p); -+ t->loc = scanloc; - switch (*p) - { - case 0: -@@ -493,12 +465,12 @@ void Lexer::scan(Token *t) - case '\r': - p++; - if (*p != '\n') // if CR stands by itself -- loc.linnum++; -+ scanloc.linnum++; - continue; // skip white space - - case '\n': - p++; -- loc.linnum++; -+ scanloc.linnum++; - continue; // skip white space - - case '0': case '1': case '2': case '3': case '4': -@@ -550,7 +522,7 @@ void Lexer::scan(Token *t) - #if ! TEXTUAL_ASSEMBLY_OUT - case '\\': // escaped string literal - { unsigned c; -- unsigned char *pstart = p; -+ utf8_t *pstart = p; - - stringbuffer.reset(); - do -@@ -573,7 +545,7 @@ void Lexer::scan(Token *t) - } while (*p == '\\'); - t->len = stringbuffer.offset; - stringbuffer.writeByte(0); -- t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); -+ t->ustring = (utf8_t *)mem.malloc(stringbuffer.offset); - memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); - t->postfix = 0; - t->value = TOKstring; -@@ -602,7 +574,7 @@ void Lexer::scan(Token *t) - case 'Z': - case '_': - case_ident: -- { unsigned char c; -+ { utf8_t c; - - while (1) - { -@@ -610,7 +582,7 @@ void Lexer::scan(Token *t) - if (isidchar(c)) - continue; - else if (c & 0x80) -- { unsigned char *s = p; -+ { utf8_t *s = p; - unsigned u = decodeUTF(); - if (isUniAlpha(u)) - continue; -@@ -624,23 +596,24 @@ void Lexer::scan(Token *t) - Identifier *id = (Identifier *) sv->ptrvalue; - if (!id) - { id = new Identifier(sv->toDchars(),TOKidentifier); -- sv->ptrvalue = id; -+ sv->ptrvalue = (char *)id; - } - t->ident = id; -- t->value = (enum TOK) id->value; -+ t->value = (TOK) id->value; - anyToken = 1; - if (*t->ptr == '_') // if special identifier token - { -+ static bool initdone = false; - static char date[11+1]; - static char time[8+1]; - static char timestamp[24+1]; - -- if (!date[0]) // lazy evaluation -- { time_t t; -- char *p; -- -+ if (!initdone) // lazy evaluation -+ { -+ initdone = true; -+ time_t t; - ::time(&t); -- p = ctime(&t); -+ char *p = ctime(&t); - assert(p); - sprintf(date, "%.6s %.4s", p + 4, p + 20); - sprintf(time, "%.8s", p + 11); -@@ -650,38 +623,34 @@ void Lexer::scan(Token *t) - #if DMDV1 - if (mod && id == Id::FILE) - { -- t->ustring = (unsigned char *)(loc.filename ? loc.filename : mod->ident->toChars()); -+ t->ustring = (utf8_t *)(loc.filename ? loc.filename : mod->ident->toChars()); - goto Lstr; - } - else if (mod && id == Id::LINE) - { - t->value = TOKint64v; -- t->uns64value = loc.linnum; -+ t->uns64value = scanloc.linnum; - } - else - #endif - if (id == Id::DATE) - { -- t->ustring = (unsigned char *)date; -+ t->ustring = (utf8_t *)date; - goto Lstr; - } - else if (id == Id::TIME) - { -- t->ustring = (unsigned char *)time; -+ t->ustring = (utf8_t *)time; - goto Lstr; - } - else if (id == Id::VENDOR) - { --#ifdef IN_GCC -- t->ustring = (unsigned char *)"GDC"; --#else -- t->ustring = (unsigned char *)"Digital Mars D"; --#endif -+ t->ustring = (utf8_t *)global.compiler.vendor; - goto Lstr; - } - else if (id == Id::TIMESTAMP) - { -- t->ustring = (unsigned char *)timestamp; -+ t->ustring = (utf8_t *)timestamp; - Lstr: - t->value = TOKstring; - t->postfix = 0; -@@ -690,14 +659,19 @@ void Lexer::scan(Token *t) - else if (id == Id::VERSIONX) - { unsigned major = 0; - unsigned minor = 0; -+ bool point = false; - - for (const char *p = global.version + 1; 1; p++) - { - char c = *p; -- if (isdigit((unsigned char)c)) -+ if (isdigit((utf8_t)c)) - minor = minor * 10 + c - '0'; - else if (c == '.') -- { major = minor; -+ { -+ if (point) -+ break; // ignore everything after second '.' -+ point = true; -+ major = minor; - minor = 0; - } - else -@@ -731,31 +705,32 @@ void Lexer::scan(Token *t) - - case '*': - p++; -- linnum = loc.linnum; -+ linnum = scanloc.linnum; - while (1) - { - while (1) -- { unsigned char c = *p; -+ { utf8_t c = *p; - switch (c) - { - case '/': - break; - - case '\n': -- loc.linnum++; -+ scanloc.linnum++; - p++; - continue; - - case '\r': - p++; - if (*p != '\n') -- loc.linnum++; -+ scanloc.linnum++; - continue; - - case 0: - case 0x1A: - error("unterminated /* */ comment"); - p = end; -+ t->loc = scanloc; - t->value = TOKeof; - return; - -@@ -763,7 +738,7 @@ void Lexer::scan(Token *t) - if (c & 0x80) - { unsigned u = decodeUTF(); - if (u == PS || u == LS) -- loc.linnum++; -+ scanloc.linnum++; - } - p++; - continue; -@@ -776,6 +751,8 @@ void Lexer::scan(Token *t) - } - if (commentToken) - { -+ t->loc.filename = scanloc.filename; -+ t->loc.linnum = linnum; - t->value = TOKcomment; - return; - } -@@ -786,9 +763,9 @@ void Lexer::scan(Token *t) - continue; - - case '/': // do // style comments -- linnum = loc.linnum; -+ linnum = scanloc.linnum; - while (1) -- { unsigned char c = *++p; -+ { utf8_t c = *++p; - switch (c) - { - case '\n': -@@ -804,12 +781,15 @@ void Lexer::scan(Token *t) - if (commentToken) - { - p = end; -+ t->loc.filename = scanloc.filename; -+ t->loc.linnum = linnum; - t->value = TOKcomment; - return; - } - if (doDocComment && t->ptr[2] == '/') - getDocComment(t, lastLine == linnum); - p = end; -+ t->loc = scanloc; - t->value = TOKeof; - return; - -@@ -827,7 +807,9 @@ void Lexer::scan(Token *t) - if (commentToken) - { - p++; -- loc.linnum++; -+ scanloc.linnum++; -+ t->loc.filename = scanloc.filename; -+ t->loc.linnum = linnum; - t->value = TOKcomment; - return; - } -@@ -835,17 +817,17 @@ void Lexer::scan(Token *t) - getDocComment(t, lastLine == linnum); - - p++; -- loc.linnum++; -+ scanloc.linnum++; - continue; - - case '+': - { int nest; - -- linnum = loc.linnum; -+ linnum = scanloc.linnum; - p++; - nest = 1; - while (1) -- { unsigned char c = *p; -+ { utf8_t c = *p; - switch (c) - { - case '/': -@@ -870,11 +852,11 @@ void Lexer::scan(Token *t) - case '\r': - p++; - if (*p != '\n') -- loc.linnum++; -+ scanloc.linnum++; - continue; - - case '\n': -- loc.linnum++; -+ scanloc.linnum++; - p++; - continue; - -@@ -882,6 +864,7 @@ void Lexer::scan(Token *t) - case 0x1A: - error("unterminated /+ +/ comment"); - p = end; -+ t->loc = scanloc; - t->value = TOKeof; - return; - -@@ -889,7 +872,7 @@ void Lexer::scan(Token *t) - if (c & 0x80) - { unsigned u = decodeUTF(); - if (u == PS || u == LS) -- loc.linnum++; -+ scanloc.linnum++; - } - p++; - continue; -@@ -898,6 +881,8 @@ void Lexer::scan(Token *t) - } - if (commentToken) - { -+ t->loc.filename = scanloc.filename; -+ t->loc.linnum = linnum; - t->value = TOKcomment; - return; - } -@@ -907,6 +892,8 @@ void Lexer::scan(Token *t) - } - continue; - } -+ default: -+ break; - } - t->value = TOKdiv; - return; -@@ -1057,12 +1044,7 @@ void Lexer::scan(Token *t) - p++; - if (*p == '=') - { p++; -- if (*p == '=' && global.params.Dversion == 1) -- { p++; -- t->value = TOKnotidentity; // !== -- } -- else -- t->value = TOKnotequal; // != -+ t->value = TOKnotequal; // != - } - else if (*p == '<') - { p++; -@@ -1099,12 +1081,7 @@ void Lexer::scan(Token *t) - p++; - if (*p == '=') - { p++; -- if (*p == '=' && global.params.Dversion == 1) -- { p++; -- t->value = TOKidentity; // === -- } -- else -- t->value = TOKequal; // == -+ t->value = TOKequal; // == - } - #if DMDV2 - else if (*p == '>') -@@ -1212,7 +1189,7 @@ void Lexer::scan(Token *t) - - if (c == PS || c == LS) - { -- loc.linnum++; -+ scanloc.linnum++; - p++; - continue; - } -@@ -1303,7 +1280,7 @@ unsigned Lexer::escapeSequence() - break; - - case '&': // named character entity -- for (unsigned char *idstart = ++p; 1; p++) -+ for (utf8_t *idstart = ++p; 1; p++) - { - switch (*p) - { -@@ -1358,8 +1335,9 @@ unsigned Lexer::escapeSequence() - */ - - TOK Lexer::wysiwygStringConstant(Token *t, int tc) --{ unsigned c; -- Loc start = loc; -+{ -+ unsigned c; -+ Loc start = scanloc; - - p++; - stringbuffer.reset(); -@@ -1369,20 +1347,20 @@ TOK Lexer::wysiwygStringConstant(Token * - switch (c) - { - case '\n': -- loc.linnum++; -+ scanloc.linnum++; - break; - - case '\r': - if (*p == '\n') - continue; // ignore - c = '\n'; // treat EndOfLine as \n character -- loc.linnum++; -+ scanloc.linnum++; - break; - - case 0: - case 0x1A: - error("unterminated string constant starting at %s", start.toChars()); -- t->ustring = (unsigned char *)""; -+ t->ustring = (utf8_t *)""; - t->len = 0; - t->postfix = 0; - return TOKstring; -@@ -1393,7 +1371,7 @@ TOK Lexer::wysiwygStringConstant(Token * - { - t->len = stringbuffer.offset; - stringbuffer.writeByte(0); -- t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); -+ t->ustring = (utf8_t *)mem.malloc(stringbuffer.offset); - memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); - stringPostfix(t); - return TOKstring; -@@ -1406,7 +1384,7 @@ TOK Lexer::wysiwygStringConstant(Token * - unsigned u = decodeUTF(); - p++; - if (u == PS || u == LS) -- loc.linnum++; -+ scanloc.linnum++; - stringbuffer.writeUTF8(u); - continue; - } -@@ -1422,8 +1400,9 @@ TOK Lexer::wysiwygStringConstant(Token * - */ - - TOK Lexer::hexStringConstant(Token *t) --{ unsigned c; -- Loc start = loc; -+{ -+ unsigned c; -+ Loc start = scanloc; - unsigned n = 0; - unsigned v; - -@@ -1445,13 +1424,13 @@ TOK Lexer::hexStringConstant(Token *t) - continue; // ignore - // Treat isolated '\r' as if it were a '\n' - case '\n': -- loc.linnum++; -+ scanloc.linnum++; - continue; - - case 0: - case 0x1A: - error("unterminated string constant starting at %s", start.toChars()); -- t->ustring = (unsigned char *)""; -+ t->ustring = (utf8_t *)""; - t->len = 0; - t->postfix = 0; - return TOKstring; -@@ -1463,7 +1442,7 @@ TOK Lexer::hexStringConstant(Token *t) - } - t->len = stringbuffer.offset; - stringbuffer.writeByte(0); -- t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); -+ t->ustring = (utf8_t *)mem.malloc(stringbuffer.offset); - memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); - stringPostfix(t); - return TOKstring; -@@ -1480,7 +1459,7 @@ TOK Lexer::hexStringConstant(Token *t) - unsigned u = decodeUTF(); - p++; - if (u == PS || u == LS) -- loc.linnum++; -+ scanloc.linnum++; - else - error("non-hex character \\u%04x", u); - } -@@ -1513,8 +1492,9 @@ TOK Lexer::hexStringConstant(Token *t) - */ - - TOK Lexer::delimitedStringConstant(Token *t) --{ unsigned c; -- Loc start = loc; -+{ -+ unsigned c; -+ Loc start = scanloc; - unsigned delimleft = 0; - unsigned delimright = 0; - unsigned nest = 1; -@@ -1533,7 +1513,7 @@ TOK Lexer::delimitedStringConstant(Token - { - case '\n': - Lnextline: -- loc.linnum++; -+ scanloc.linnum++; - startline = 1; - if (blankrol) - { blankrol = 0; -@@ -1628,7 +1608,7 @@ TOK Lexer::delimitedStringConstant(Token - #endif - ) - { Token t; -- unsigned char *psave = p; -+ utf8_t *psave = p; - p--; - scan(&t); // read in possible heredoc identifier - //printf("endid = '%s'\n", t.ident->toChars()); -@@ -1651,14 +1631,14 @@ Ldone: - error("delimited string must end in %c\"", delimright); - t->len = stringbuffer.offset; - stringbuffer.writeByte(0); -- t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); -+ t->ustring = (utf8_t *)mem.malloc(stringbuffer.offset); - memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); - stringPostfix(t); - return TOKstring; - - Lerror: - error("unterminated string constant starting at %s", start.toChars()); -- t->ustring = (unsigned char *)""; -+ t->ustring = (utf8_t *)""; - t->len = 0; - t->postfix = 0; - return TOKstring; -@@ -1676,8 +1656,8 @@ Lerror: - TOK Lexer::tokenStringConstant(Token *t) - { - unsigned nest = 1; -- Loc start = loc; -- unsigned char *pstart = ++p; -+ Loc start = scanloc; -+ utf8_t *pstart = ++p; - - while (1) - { Token tok; -@@ -1704,7 +1684,7 @@ TOK Lexer::tokenStringConstant(Token *t) - - Ldone: - t->len = p - 1 - pstart; -- t->ustring = (unsigned char *)mem.malloc(t->len + 1); -+ t->ustring = (utf8_t *)mem.malloc(t->len + 1); - memcpy(t->ustring, pstart, t->len); - t->ustring[t->len] = 0; - stringPostfix(t); -@@ -1712,7 +1692,7 @@ Ldone: - - Lerror: - error("unterminated token string constant starting at %s", start.toChars()); -- t->ustring = (unsigned char *)""; -+ t->ustring = (utf8_t *)""; - t->len = 0; - t->postfix = 0; - return TOKstring; -@@ -1725,8 +1705,9 @@ Lerror: - */ - - TOK Lexer::escapeStringConstant(Token *t, int wide) --{ unsigned c; -- Loc start = loc; -+{ -+ unsigned c; -+ Loc start = scanloc; - - p++; - stringbuffer.reset(); -@@ -1753,20 +1734,20 @@ TOK Lexer::escapeStringConstant(Token *t - break; - #endif - case '\n': -- loc.linnum++; -+ scanloc.linnum++; - break; - - case '\r': - if (*p == '\n') - continue; // ignore - c = '\n'; // treat EndOfLine as \n character -- loc.linnum++; -+ scanloc.linnum++; - break; - - case '"': - t->len = stringbuffer.offset; - stringbuffer.writeByte(0); -- t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); -+ t->ustring = (utf8_t *)mem.malloc(stringbuffer.offset); - memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); - stringPostfix(t); - return TOKstring; -@@ -1775,7 +1756,7 @@ TOK Lexer::escapeStringConstant(Token *t - case 0x1A: - p--; - error("unterminated string constant starting at %s", start.toChars()); -- t->ustring = (unsigned char *)""; -+ t->ustring = (utf8_t *)""; - t->len = 0; - t->postfix = 0; - return TOKstring; -@@ -1787,7 +1768,7 @@ TOK Lexer::escapeStringConstant(Token *t - c = decodeUTF(); - if (c == LS || c == PS) - { c = '\n'; -- loc.linnum++; -+ scanloc.linnum++; - } - p++; - stringbuffer.writeUTF8(c); -@@ -1835,7 +1816,7 @@ TOK Lexer::charConstant(Token *t, int wi - #endif - case '\n': - L1: -- loc.linnum++; -+ scanloc.linnum++; - case '\r': - case 0: - case 0x1A: -@@ -1906,17 +1887,19 @@ TOK Lexer::number(Token *t) - enum STATE { STATE_initial, STATE_0, STATE_decimal, STATE_octal, STATE_octale, - STATE_hex, STATE_binary, STATE_hex0, STATE_binary0, - STATE_hexh, STATE_error }; -- enum STATE state; -+ STATE state; - - enum FLAGS -- { FLAGS_decimal = 1, // decimal -+ { -+ FLAGS_none = 0, -+ FLAGS_decimal = 1, // decimal - FLAGS_unsigned = 2, // u or U suffix - FLAGS_long = 4, // l or L suffix - }; -- enum FLAGS flags = FLAGS_decimal; -+ FLAGS flags = FLAGS_decimal; - - unsigned c; -- unsigned char *start; -+ utf8_t *start; - TOK result; - - //printf("Lexer::number()\n"); -@@ -2106,7 +2089,7 @@ done: - p += 2, r = 16; - else if (p[1] == 'b' || p[1] == 'B') - p += 2, r = 2; -- else if (isdigit((unsigned char)p[1])) -+ else if (isdigit((utf8_t)p[1])) - p += 1, r = 8; - } - -@@ -2141,9 +2124,9 @@ done: - } - - // Parse trailing 'u', 'U', 'l' or 'L' in any combination -- const unsigned char *psuffix = p; -+ const utf8_t *psuffix = p; - while (1) -- { unsigned char f; -+ { utf8_t f; - - switch (*p) - { case 'U': -@@ -2173,7 +2156,7 @@ done: - - switch (flags) - { -- case 0: -+ case FLAGS_none: - /* Octal or Hexadecimal constant. - * First that fits: int, uint, long, ulong - */ -@@ -2356,47 +2339,25 @@ done: - - stringbuffer.writeByte(0); - --#if _WIN32 && __DMC__ -- char *save = __locale_decpoint; -- __locale_decpoint = "."; --#endif --#ifdef IN_GCC -- t->float80value = real_t::parse((char *)stringbuffer.data, real_t::LongDouble); --#else -- t->float80value = strtold((char *)stringbuffer.data, NULL); --#endif -+ t->float80value = Port::strtold((char *)stringbuffer.data, NULL); - errno = 0; - switch (*p) - { - case 'F': - case 'f': --#ifdef IN_GCC -- real_t::parse((char *)stringbuffer.data, real_t::Float); --#else -- { // Only interested in errno return -- double d = strtof((char *)stringbuffer.data, NULL); -- // Assign to d to keep gcc warnings at bay, -- // but then CppCheck complains that d is never used. -- } --#endif -+ // Only interested in errno return -+ (void)Port::strtof((char *)stringbuffer.data, NULL); - result = TOKfloat32v; - p++; - break; - - default: --#ifdef IN_GCC -- real_t::parse((char *)stringbuffer.data, real_t::Double); --#else - /* Should do our own strtod(), since dmc and linux gcc - * accept 2.22507e-308, while apple gcc will only take - * 2.22508e-308. Not sure who is right. - */ -- { // Only interested in errno return -- double d = strtod((char *)stringbuffer.data, NULL); -- // Assign to d to keep gcc warnings at bay -- // but then CppCheck complains that d is never used. -- } --#endif -+ // Only interested in errno return -+ (void)Port::strtod((char *)stringbuffer.data, NULL); - result = TOKfloat64v; - break; - -@@ -2426,9 +2387,6 @@ done: - default: break; - } - } --#if _WIN32 && __DMC__ -- __locale_decpoint = save; --#endif - if (errno == ERANGE) - error("number is not representable"); - return result; -@@ -2437,6 +2395,7 @@ done: - /********************************************* - * parse: - * #line linnum [filespec] -+ * also allow __LINE__ for linnum, and __FILE__ for filespec - */ - - void Lexer::poundLine() -@@ -2444,7 +2403,7 @@ void Lexer::poundLine() - Token tok; - int linnum; - char *filespec = NULL; -- Loc loc = this->loc; -+ Loc loc = this->scanloc; - - scan(&tok); - if (tok.value == TOKint32v || tok.value == TOKint64v) -@@ -2452,6 +2411,10 @@ void Lexer::poundLine() - if (linnum != tok.uns64value - 1) - error("line number out of range"); - } -+ else if (tok.value == TOKline) -+ { -+ linnum = this->scanloc.linnum; -+ } - else - goto Lerr; - -@@ -2463,9 +2426,9 @@ void Lexer::poundLine() - case 0x1A: - case '\n': - Lnewline: -- this->loc.linnum = linnum; -+ this->scanloc.linnum = linnum; - if (filespec) -- this->loc.filename = filespec; -+ this->scanloc.filename = filespec; - return; - - case '\r': -@@ -2487,7 +2450,7 @@ void Lexer::poundLine() - if (mod && memcmp(p, "__FILE__", 8) == 0) - { - p += 8; -- filespec = mem.strdup(loc.filename ? loc.filename : mod->ident->toChars()); -+ filespec = mem.strdup(scanloc.filename ? scanloc.filename : mod->ident->toChars()); - continue; - } - goto Lerr; -@@ -2553,8 +2516,8 @@ Lerr: - unsigned Lexer::decodeUTF() - { - dchar_t u; -- unsigned char c; -- unsigned char *s = p; -+ utf8_t c; -+ utf8_t *s = p; - size_t len; - size_t idx; - const char *msg; -@@ -2590,13 +2553,13 @@ void Lexer::getDocComment(Token *t, unsi - { - /* ct tells us which kind of comment it is: '/', '*', or '+' - */ -- unsigned char ct = t->ptr[2]; -+ utf8_t ct = t->ptr[2]; - - /* Start of comment text skips over / * *, / + +, or / / / - */ -- unsigned char *q = t->ptr + 3; // start of comment text -+ utf8_t *q = t->ptr + 3; // start of comment text - -- unsigned char *qend = p; -+ utf8_t *qend = p; - if (ct == '*' || ct == '+') - qend -= 2; - -@@ -2627,7 +2590,7 @@ void Lexer::getDocComment(Token *t, unsi - - for (; q < qend; q++) - { -- unsigned char c = *q; -+ utf8_t c = *q; - - switch (c) - { -@@ -2689,15 +2652,15 @@ void Lexer::getDocComment(Token *t, unsi - - // It's a line comment if the start of the doc comment comes - // after other non-whitespace on the same line. -- unsigned char** dc = (lineComment && anyToken) -+ utf8_t** dc = (lineComment && anyToken) - ? &t->lineComment - : &t->blockComment; - - // Combine with previous doc comment, if any - if (*dc) -- *dc = combineComments(*dc, (unsigned char *)buf.data); -+ *dc = combineComments(*dc, (utf8_t *)buf.data); - else -- *dc = (unsigned char *)buf.extractData(); -+ *dc = (utf8_t *)buf.extractData(); - } - - /******************************************** -@@ -2705,11 +2668,11 @@ void Lexer::getDocComment(Token *t, unsi - * separated by a newline. - */ - --unsigned char *Lexer::combineComments(unsigned char *c1, unsigned char *c2) -+utf8_t *Lexer::combineComments(utf8_t *c1, utf8_t *c2) - { - //printf("Lexer::combineComments('%s', '%s')\n", c1, c2); - -- unsigned char *c = c2; -+ utf8_t *c = c2; - - if (c1) - { c = c1; -@@ -2717,7 +2680,7 @@ unsigned char *Lexer::combineComments(un - { size_t len1 = strlen((char *)c1); - size_t len2 = strlen((char *)c2); - -- c = (unsigned char *)mem.malloc(len1 + 1 + len2 + 1); -+ c = (utf8_t *)mem.malloc(len1 + 1 + len2 + 1); - memcpy(c, c1, len1); - if (len1 && c1[len1 - 1] != '\n') - { c[len1] = '\n'; -@@ -2730,38 +2693,6 @@ unsigned char *Lexer::combineComments(un - return c; - } - --/******************************************* -- * Search actual location of current token -- * even when infinite look-ahead was done. -- */ --Loc Lexer::tokenLoc() --{ -- Loc result = this->loc; -- Token* last = &token; -- while (last->next) -- last = last->next; -- -- unsigned char* start = token.ptr; -- unsigned char* stop = last->ptr; -- -- for (unsigned char* p = start; p < stop; ++p) -- { -- switch (*p) -- { -- case '\n': -- result.linnum--; -- break; -- case '\r': -- if (p[1] != '\n') -- result.linnum--; -- break; -- default: -- break; -- } -- } -- return result; --} -- - /******************************************** - * Create an identifier in the string table. - */ -@@ -2774,7 +2705,7 @@ Identifier *Lexer::idPool(const char *s) - if (!id) - { - id = new Identifier(sv->toDchars(), TOKidentifier); -- sv->ptrvalue = id; -+ sv->ptrvalue = (char *)id; - } - return id; - } -@@ -2787,7 +2718,7 @@ Identifier *Lexer::uniqueId(const char * - { char buffer[32]; - size_t slen = strlen(s); - -- assert(slen + sizeof(num) * 3 + 1 <= sizeof(buffer)); -+ assert(slen + sizeof(num) * 3 + 1 <= sizeof(buffer) / sizeof(buffer[0])); - sprintf(buffer, "%s%d", s, num); - return idPool(buffer); - } -@@ -2803,7 +2734,7 @@ Identifier *Lexer::uniqueId(const char * - - struct Keyword - { const char *name; -- enum TOK value; -+ TOK value; - }; - - static Keyword keywords[] = -@@ -2926,13 +2857,15 @@ static Keyword keywords[] = - #if DMDV2 - { "pure", TOKpure }, - { "nothrow", TOKnothrow }, -- { "__thread", TOKtls }, - { "__gshared", TOKgshared }, - { "__traits", TOKtraits }, - { "__vector", TOKvector }, - { "__overloadset", TOKoverloadset }, - { "__FILE__", TOKfile }, - { "__LINE__", TOKline }, -+ { "__MODULE__", TOKmodulestring }, -+ { "__FUNCTION__", TOKfuncstring }, -+ { "__PRETTY_FUNCTION__", TOKprettyfunc }, - { "shared", TOKshared }, - { "immutable", TOKimmutable }, - #endif -@@ -2952,10 +2885,7 @@ void Lexer::initKeywords() - { - size_t nkeywords = sizeof(keywords) / sizeof(keywords[0]); - -- stringtable.init(6151); -- -- if (global.params.Dversion == 1) -- nkeywords -= 2; -+ stringtable._init(6151); - - cmtable_init(); - -@@ -2963,9 +2893,9 @@ void Lexer::initKeywords() - { - //printf("keyword[%d] = '%s'\n",u, keywords[u].name); - const char *s = keywords[u].name; -- enum TOK v = keywords[u].value; -+ TOK v = keywords[u].value; - StringValue *sv = stringtable.insert(s, strlen(s)); -- sv->ptrvalue = (void *) new Identifier(sv->toDchars(),v); -+ sv->ptrvalue = (char *)new Identifier(sv->toDchars(),v); - - //printf("tochars[%d] = '%s'\n",v, s); - Token::tochars[v] = s; -@@ -3098,8 +3028,8 @@ void unittest_lexer() - - /* Not much here, just trying things out. - */ -- const unsigned char text[] = "int"; -- Lexer lex1(NULL, (unsigned char *)text, 0, sizeof(text), 0, 0); -+ const utf8_t text[] = "int"; -+ Lexer lex1(NULL, (utf8_t *)text, 0, sizeof(text), 0, 0); - TOK tok; - tok = lex1.nextToken(); - //printf("tok == %s, %d, %d\n", Token::toChars(tok), tok, TOKint32); ---- a/src/gcc/d/dfrontend/lexer.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/lexer.h 2014-04-01 16:32:51.000000000 +0100 -@@ -19,8 +19,8 @@ - #include "mars.h" - - struct StringTable; --struct Identifier; --struct Module; -+class Identifier; -+class Module; - - /* Tokens: - ( ) -@@ -69,6 +69,8 @@ enum TOK - TOKnewanonclass, TOKcomment, - TOKarrayliteral, TOKassocarrayliteral, - TOKstructliteral, -+ TOKclassreference, -+ TOKthrownexception, - - // Operators - TOKlt, TOKgt, -@@ -161,10 +163,12 @@ enum TOK - TOKoverloadset, - TOKpure, - TOKnothrow, -- TOKtls, - TOKgshared, - TOKline, - TOKfile, -+ TOKmodulestring, -+ TOKfuncstring, -+ TOKprettyfunc, - TOKshared, - TOKat, - TOKpow, -@@ -222,10 +226,11 @@ enum TOK - struct Token - { - Token *next; -- unsigned char *ptr; // pointer to first character of this token within buffer -- enum TOK value; -- unsigned char *blockComment; // doc comment string prior to this token -- unsigned char *lineComment; // doc comment for previous token -+ Loc loc; -+ utf8_t *ptr; // pointer to first character of this token within buffer -+ TOK value; -+ utf8_t *blockComment; // doc comment string prior to this token -+ utf8_t *lineComment; // doc comment for previous token - union - { - // Integers -@@ -235,45 +240,41 @@ struct Token - d_uns64 uns64value; - - // Floats --#ifdef IN_GCC -- // real_t float80value; // can't use this in a union! --#else - d_float80 float80value; --#endif - - struct -- { unsigned char *ustring; // UTF8 string -+ { utf8_t *ustring; // UTF8 string - unsigned len; - unsigned char postfix; // 'c', 'w', 'd' - }; - - Identifier *ident; - }; --#ifdef IN_GCC -- real_t float80value; // can't use this in a union! --#endif - - static const char *tochars[TOKMAX]; - static void *operator new(size_t sz); - - Token() : next(NULL) {} - int isKeyword(); -+#ifdef DEBUG - void print(); -+#endif - const char *toChars(); -- static const char *toChars(enum TOK); -+ static const char *toChars(TOK); - }; - --struct Lexer -+class Lexer - { -+public: - static StringTable stringtable; - static OutBuffer stringbuffer; - static Token *freelist; - -- Loc loc; // for error messages -+ Loc scanloc; // for error messages - -- unsigned char *base; // pointer to start of buffer -- unsigned char *end; // past end of buffer -- unsigned char *p; // current character -+ utf8_t *base; // pointer to start of buffer -+ utf8_t *end; // past end of buffer -+ utf8_t *p; // current character - Token token; - Module *mod; - int doDocComment; // collect doc comment information -@@ -281,7 +282,7 @@ struct Lexer - int commentToken; // !=0 means comments are TOKcomment's - - Lexer(Module *mod, -- unsigned char *base, size_t begoffset, size_t endoffset, -+ utf8_t *base, size_t begoffset, size_t endoffset, - int doDocComment, int commentToken); - - static void initKeywords(); -@@ -305,7 +306,6 @@ struct Lexer - TOK escapeStringConstant(Token *t, int wide); - TOK charConstant(Token *t, int wide); - void stringPostfix(Token *t); -- unsigned wchar(unsigned u); - TOK number(Token *t); - TOK inreal(Token *t); - void error(const char *format, ...); -@@ -316,9 +316,7 @@ struct Lexer - void getDocComment(Token *t, unsigned lineComment); - - static int isValidIdentifier(char *p); -- static unsigned char *combineComments(unsigned char *c1, unsigned char *c2); -- -- Loc tokenLoc(); -+ static utf8_t *combineComments(utf8_t *c1, utf8_t *c2); - }; - - #endif /* DMD_LEXER_H */ ---- a/src/gcc/d/dfrontend/macro.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/macro.c 2014-04-01 16:32:51.000000000 +0100 -@@ -21,16 +21,16 @@ - - #include "macro.h" - --int isIdStart(unsigned char *p); --int isIdTail(unsigned char *p); --int utfStride(unsigned char *p); -+int isIdStart(utf8_t *p); -+int isIdTail(utf8_t *p); -+int utfStride(utf8_t *p); - --unsigned char *memdup(unsigned char *p, size_t len) -+utf8_t *memdup(utf8_t *p, size_t len) - { -- return (unsigned char *)memcpy(mem.malloc(len), p, len); -+ return (utf8_t *)memcpy(mem.malloc(len), p, len); - } - --Macro::Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen) -+Macro::Macro(utf8_t *name, size_t namelen, utf8_t *text, size_t textlen) - { - next = NULL; - -@@ -51,7 +51,7 @@ Macro::Macro(unsigned char *name, size_t - } - - --Macro *Macro::search(unsigned char *name, size_t namelen) -+Macro *Macro::search(utf8_t *name, size_t namelen) - { Macro *table; - - //printf("Macro::search(%.*s)\n", namelen, name); -@@ -67,7 +67,7 @@ Macro *Macro::search(unsigned char *name - return table; - } - --Macro *Macro::define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen) -+Macro *Macro::define(Macro **ptable, utf8_t *name, size_t namelen, utf8_t *text, size_t textlen) - { - //printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text); - -@@ -98,7 +98,7 @@ Macro *Macro::define(Macro **ptable, uns - * -1: get 2nd through end - */ - --size_t extractArgN(unsigned char *p, size_t end, unsigned char **pmarg, size_t *pmarglen, int n) -+size_t extractArgN(utf8_t *p, size_t end, utf8_t **pmarg, size_t *pmarglen, int n) - { - /* Scan forward for matching right parenthesis. - * Nest parentheses. -@@ -130,7 +130,7 @@ size_t extractArgN(unsigned char *p, siz - *pmarg = p + v; - - for (; v < end; v++) -- { unsigned char c = p[v]; -+ { utf8_t c = p[v]; - - switch (c) - { -@@ -238,7 +238,7 @@ size_t extractArgN(unsigned char *p, siz - */ - - void Macro::expand(OutBuffer *buf, size_t start, size_t *pend, -- unsigned char *arg, size_t arglen) -+ utf8_t *arg, size_t arglen) - { - #if 0 - printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg); -@@ -259,7 +259,7 @@ void Macro::expand(OutBuffer *buf, size_ - arg = memdup(arg, arglen); - for (size_t u = start; u + 1 < end; ) - { -- unsigned char *p = buf->data; // buf->data is not loop invariant -+ utf8_t *p = buf->data; // buf->data is not loop invariant - - /* Look for $0, but not $$0, and replace it with arg. - */ -@@ -273,10 +273,10 @@ void Macro::expand(OutBuffer *buf, size_ - continue; - } - -- unsigned char c = p[u + 1]; -+ utf8_t c = p[u + 1]; - int n = (c == '+') ? -1 : c - '0'; - -- unsigned char *marg; -+ utf8_t *marg; - size_t marglen; - extractArgN(arg, arglen, &marg, &marglen, n); - if (marglen == 0) -@@ -327,7 +327,7 @@ void Macro::expand(OutBuffer *buf, size_ - */ - for (size_t u = start; u + 4 < end; ) - { -- unsigned char *p = buf->data; // buf->data is not loop invariant -+ utf8_t *p = buf->data; // buf->data is not loop invariant - - /* A valid start of macro expansion is $(c, where c is - * an id start character, and not $$(c. -@@ -335,10 +335,10 @@ void Macro::expand(OutBuffer *buf, size_ - if (p[u] == '$' && p[u + 1] == '(' && isIdStart(p+u+2)) - { - //printf("\tfound macro start '%c'\n", p[u + 2]); -- unsigned char *name = p + u + 2; -+ utf8_t *name = p + u + 2; - size_t namelen = 0; - -- unsigned char *marg; -+ utf8_t *marg; - size_t marglen; - - size_t v; -@@ -346,7 +346,7 @@ void Macro::expand(OutBuffer *buf, size_ - * beginning of macro argument (marg). - */ - for (v = u + 2; v < end; v+=utfStride(p+v)) -- { unsigned char c = p[v]; -+ { utf8_t c = p[v]; - - if (!isIdTail(p+v)) - { // We've gone past the end of the macro name. ---- a/src/gcc/d/dfrontend/macro.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/macro.h 2014-04-01 16:32:51.000000000 +0100 -@@ -24,22 +24,22 @@ struct Macro - private: - Macro *next; // next in list - -- unsigned char *name; // macro name -+ utf8_t *name; // macro name - size_t namelen; // length of macro name - -- unsigned char *text; // macro replacement text -+ utf8_t *text; // macro replacement text - size_t textlen; // length of replacement text - - int inuse; // macro is in use (don't expand) - -- Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen); -- Macro *search(unsigned char *name, size_t namelen); -+ Macro(utf8_t *name, size_t namelen, utf8_t *text, size_t textlen); -+ Macro *search(utf8_t *name, size_t namelen); - - public: -- static Macro *define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen); -+ static Macro *define(Macro **ptable, utf8_t *name, size_t namelen, utf8_t *text, size_t textlen); - - void expand(OutBuffer *buf, size_t start, size_t *pend, -- unsigned char *arg, size_t arglen); -+ utf8_t *arg, size_t arglen); - }; - - #endif ---- a/src/gcc/d/dfrontend/mangle.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/mangle.c 2014-04-01 16:32:51.000000000 +0100 -@@ -46,7 +46,7 @@ char *mangle(Declaration *sthis, bool is - do - { - //printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent); -- if (s->ident) -+ if (s->getIdent()) - { - FuncDeclaration *fd = s->isFuncDeclaration(); - if (s != sthis && fd) -@@ -79,6 +79,17 @@ L1: - buf.writeByte(Type::needThisPrefix()); - if (isv && fd && (fd->inferRetType || getFuncTemplateDecl(fd))) - { -+#if DDMD -+ TypeFunction *tfn = (TypeFunction *)sthis->type->copy(); -+ TypeFunction *tfo = (TypeFunction *)sthis->originalType; -+ tfn->purity = tfo->purity; -+ tfn->isnothrow = tfo->isnothrow; -+ tfn->isproperty = tfo->isproperty; -+ tfn->isref = fd->storage_class & STCauto ? false : tfo->isref; -+ tfn->trust = tfo->trust; -+ tfn->next = NULL; // do not mangle return type -+ tfn->toDecoBuffer(&buf, 0); -+#else - TypeFunction tfn = *(TypeFunction *)sthis->type; - TypeFunction *tfo = (TypeFunction *)sthis->originalType; - tfn.purity = tfo->purity; -@@ -88,6 +99,7 @@ L1: - tfn.trust = tfo->trust; - tfn.next = NULL; // do not mangle return type - tfn.toDecoBuffer(&buf, 0); -+#endif - } - else if (sthis->type->deco) - buf.writestring(sthis->type->deco); -@@ -105,7 +117,7 @@ L1: - return id; - } - --char *Declaration::mangle(bool isv) -+const char *Declaration::mangle(bool isv) - #if __DMC__ - __out(result) - { -@@ -150,7 +162,7 @@ char *Declaration::mangle(bool isv) - return ident->toChars(); - - default: -- fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage); -+ fprintf(stderr, "'%s', linkage = %d\n", toChars(), linkage); - assert(0); - } - } -@@ -164,7 +176,49 @@ char *Declaration::mangle(bool isv) - return p; - } - --char *FuncDeclaration::mangle(bool isv) -+/****************************************************************************** -+ * Normally FuncDeclaration and FuncAliasDeclaration have overloads. -+ * If and only if there is no overloads, mangle() could return -+ * exact mangled name. -+ * -+ * module test; -+ * void foo(long) {} // _D4test3fooFlZv -+ * void foo(string) {} // _D4test3fooFAyaZv -+ * -+ * // from FuncDeclaration::mangle(). -+ * pragma(msg, foo.mangleof); // prints unexact mangled name "4test3foo" -+ * // by calling Dsymbol::mangle() -+ * -+ * // from FuncAliasDeclaration::mangle() -+ * pragma(msg, __traits(getOverloads, test, "foo")[0].mangleof); // "_D4test3fooFlZv" -+ * pragma(msg, __traits(getOverloads, test, "foo")[1].mangleof); // "_D4test3fooFAyaZv" -+ * -+ * If a function has no overloads, .mangleof property still returns exact mangled name. -+ * -+ * void bar() {} -+ * pragma(msg, bar.mangleof); // still prints "_D4test3barFZv" -+ * // by calling FuncDeclaration::mangleExact(). -+ */ -+const char *FuncDeclaration::mangle(bool isv) -+{ -+ return isUnique() ? mangleExact(isv) : Dsymbol::mangle(isv); -+} -+// ditto -+const char *FuncAliasDeclaration::mangle(bool isv) -+{ -+ FuncDeclaration *f = toAliasFunc(); -+ FuncAliasDeclaration *fa = f->isFuncAliasDeclaration(); -+ if (!hasOverloads && !fa) -+ return f->mangleExact(isv); -+ if (fa) -+ return fa->mangle(isv); -+ return Dsymbol::mangle(isv); -+} -+ -+/****************************************************************************** -+ * Returns exact mangled name of function. -+ */ -+const char *FuncDeclaration::mangleExact(bool isv) - #if __DMC__ - __out(result) - { -@@ -173,6 +227,11 @@ char *FuncDeclaration::mangle(bool isv) - __body - #endif - { -+ assert(!isFuncAliasDeclaration()); -+ -+ if (mangleOverride) -+ return mangleOverride; -+ - if (isMain()) - return (char *)"_Dmain"; - -@@ -183,22 +242,36 @@ char *FuncDeclaration::mangle(bool isv) - return Declaration::mangle(isv); - } - -+const char *VarDeclaration::mangle(bool isv) -+#if __DMC__ -+ __out(result) -+ { -+ assert(strlen(result) > 0); -+ } -+ __body -+#endif -+ { -+ if (mangleOverride) -+ return mangleOverride; -+ -+ return Declaration::mangle(); -+ } - --char *TypedefDeclaration::mangle(bool isv) -+const char *TypedefDeclaration::mangle(bool isv) - { - //printf("TypedefDeclaration::mangle() '%s'\n", toChars()); - return Dsymbol::mangle(isv); - } - - --char *AggregateDeclaration::mangle(bool isv) -+const char *AggregateDeclaration::mangle(bool isv) - { - #if 1 - //printf("AggregateDeclaration::mangle() '%s'\n", toChars()); - if (Dsymbol *p = toParent2()) - { if (FuncDeclaration *fd = p->isFuncDeclaration()) - { // This might be the Voldemort Type -- char *id = Dsymbol::mangle(fd->inferRetType || getFuncTemplateDecl(fd)); -+ const char *id = Dsymbol::mangle(fd->inferRetType || getFuncTemplateDecl(fd)); - //printf("isv ad %s, %s\n", toChars(), id); - return id; - } -@@ -207,13 +280,13 @@ char *AggregateDeclaration::mangle(bool - return Dsymbol::mangle(isv); - } - --char *StructDeclaration::mangle(bool isv) -+const char *StructDeclaration::mangle(bool isv) - { - //printf("StructDeclaration::mangle() '%s'\n", toChars()); - return AggregateDeclaration::mangle(isv); - } - --char *ClassDeclaration::mangle(bool isv) -+const char *ClassDeclaration::mangle(bool isv) - { - Dsymbol *parentsave = parent; - -@@ -233,19 +306,19 @@ char *ClassDeclaration::mangle(bool isv) - ident == Id::TypeInfo_Typedef || - ident == Id::TypeInfo_Tuple || - this == object || -- this == classinfo || -+ this == Type::typeinfoclass || - this == Module::moduleinfo || - memcmp(ident->toChars(), "TypeInfo_", 9) == 0 - ) - parent = NULL; - -- char *id = AggregateDeclaration::mangle(isv); -+ const char *id = AggregateDeclaration::mangle(isv); - parent = parentsave; - return id; - } - - --char *TemplateInstance::mangle(bool isv) -+const char *TemplateInstance::mangle(bool isv) - { - OutBuffer buf; - -@@ -255,15 +328,16 @@ char *TemplateInstance::mangle(bool isv) - printf(" parent = %s %s", parent->kind(), parent->toChars()); - printf("\n"); - #endif -- char *id = ident ? ident->toChars() : toChars(); -+ getIdent(); -+ const char *id = ident ? ident->toChars() : toChars(); - if (!tempdecl) - error("is not defined"); - else - { -- Dsymbol *par = isnested || isTemplateMixin() ? parent : tempdecl->parent; -+ Dsymbol *par = enclosing || isTemplateMixin() ? parent : tempdecl->parent; - if (par) - { -- char *p = par->mangle(); -+ const char *p = par->mangle(isv); - if (p[0] == '_' && p[1] == 'D') - p += 2; - buf.writestring(p); -@@ -278,7 +352,7 @@ char *TemplateInstance::mangle(bool isv) - - - --char *Dsymbol::mangle(bool isv) -+const char *Dsymbol::mangle(bool isv) - { - OutBuffer buf; - char *id; -@@ -292,7 +366,8 @@ char *Dsymbol::mangle(bool isv) - id = ident ? ident->toChars() : toChars(); - if (parent) - { -- char *p = parent->mangle(isv); -+ FuncDeclaration *f = parent->isFuncDeclaration(); -+ const char *p = f ? f->mangleExact(isv) : parent->mangle(isv); - if (p[0] == '_' && p[1] == 'D') - p += 2; - buf.writestring(p); ---- a/src/gcc/d/dfrontend/mars.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/mars.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,1744 +0,0 @@ -- --// Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars --// All Rights Reserved --// written by Walter Bright --// http://www.digitalmars.com --// https://github.com/D-Programming-Language/dmd/blob/master/src/mars.c --// License for redistribution is by either the Artistic License --// in artistic.txt, or the GNU General Public License in gnu.txt. --// See the included readme.txt for details. -- --#include --#include --#include --#include --#include --#include -- --#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun --#include --#endif -- --#include "rmem.h" --#include "root.h" --#include "async.h" -- --#include "mars.h" --#include "module.h" --#include "mtype.h" --#include "id.h" --#include "cond.h" --#include "expression.h" --#include "lexer.h" --#ifndef IN_GCC --#include "lib.h" --#include "json.h" -- --#if WINDOWS_SEH --#include --long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); --#endif --#endif -- -- --int response_expand(size_t *pargc, char ***pargv); --void browse(const char *url); --void getenv_setargv(const char *envvar, size_t *pargc, char** *pargv); -- --void obj_start(char *srcfile); --void obj_end(Library *library, File *objfile); -- --void printCtfePerformanceStats(); -- --static bool parse_arch(size_t argc, char** argv, bool is64bit); -- --Global global; -- --Global::Global() --{ -- mars_ext = "d"; -- sym_ext = "d"; -- hdr_ext = "di"; -- doc_ext = "html"; -- ddoc_ext = "ddoc"; -- json_ext = "json"; -- map_ext = "map"; -- --#ifndef IN_GCC --#if TARGET_WINDOS -- obj_ext = "obj"; --#elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS -- obj_ext = "o"; --#else --#error "fix this" --#endif --#else -- obj_ext = "o"; --#endif -- --#ifndef IN_GCC --#if TARGET_WINDOS -- lib_ext = "lib"; --#elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS -- lib_ext = "a"; --#else --#error "fix this" --#endif --#else -- lib_ext = "a"; --#endif -- --#ifndef IN_GCC --#if TARGET_WINDOS -- dll_ext = "dll"; --#elif TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS -- dll_ext = "so"; --#elif TARGET_OSX -- dll_ext = "dylib"; --#else --#error "fix this" --#endif --#else -- dll_ext = "so"; --#endif -- -- copyright = "Copyright (c) 1999-2012 by Digital Mars"; -- written = "written by Walter Bright"; -- version = "v" --#include "verstr.h" -- ; -- -- global.structalign = STRUCTALIGN_DEFAULT; -- -- memset(¶ms, 0, sizeof(Param)); --} -- --unsigned Global::startGagging() --{ -- ++gag; -- return gaggedErrors; --} -- --bool Global::endGagging(unsigned oldGagged) --{ -- bool anyErrs = (gaggedErrors != oldGagged); -- --gag; -- // Restore the original state of gagged errors; set total errors -- // to be original errors + new ungagged errors. -- errors -= (gaggedErrors - oldGagged); -- gaggedErrors = oldGagged; -- return anyErrs; --} -- --bool Global::isSpeculativeGagging() --{ -- return gag && gag == speculativeGag; --} -- -- --char *Loc::toChars() --{ -- OutBuffer buf; -- -- if (filename) -- { -- buf.printf("%s", filename); -- } -- -- if (linnum) --#ifndef IN_GCC -- buf.printf("(%d)", linnum); --#else -- buf.printf(":%u", linnum); --#endif -- buf.writeByte(0); -- return (char *)buf.extractData(); --} -- --Loc::Loc(Module *mod, unsigned linnum) --{ -- this->linnum = linnum; -- this->filename = mod ? mod->srcfile->toChars() : NULL; --} -- --bool Loc::equals(const Loc& loc) --{ -- return linnum == loc.linnum && FileName::equals(filename, loc.filename); --} -- --/************************************** -- * Print error message -- */ -- --void error(Loc loc, const char *format, ...) --{ -- va_list ap; -- va_start(ap, format); -- verror(loc, format, ap); -- va_end( ap ); --} -- --void error(const char *filename, unsigned linnum, const char *format, ...) --{ Loc loc; -- loc.filename = (char *)filename; -- loc.linnum = linnum; -- va_list ap; -- va_start(ap, format); -- verror(loc, format, ap); -- va_end( ap ); --} -- --void warning(Loc loc, const char *format, ...) --{ -- va_list ap; -- va_start(ap, format); -- vwarning(loc, format, ap); -- va_end( ap ); --} -- --/************************************** -- * Print supplementary message about the last error -- * Used for backtraces, etc -- */ --void errorSupplemental(Loc loc, const char *format, ...) --{ -- va_list ap; -- va_start(ap, format); -- verrorSupplemental(loc, format, ap); -- va_end( ap ); --} -- --void deprecation(Loc loc, const char *format, ...) --{ -- va_list ap; -- va_start(ap, format); -- vdeprecation(loc, format, ap); -- -- va_end( ap ); --} -- --// Just print, doesn't care about gagging --void verrorPrint(Loc loc, const char *header, const char *format, va_list ap, -- const char *p1, const char *p2) --{ -- char *p = loc.toChars(); -- -- if (*p) -- fprintf(stdmsg, "%s: ", p); -- mem.free(p); -- -- fputs(header, stdmsg); -- if (p1) -- fprintf(stdmsg, "%s ", p1); -- if (p2) -- fprintf(stdmsg, "%s ", p2); --#if _MSC_VER -- // MS doesn't recognize %zu format -- OutBuffer tmp; -- tmp.vprintf(format, ap); -- fprintf(stdmsg, "%s", tmp.toChars()); --#else -- vfprintf(stdmsg, format, ap); --#endif -- fprintf(stdmsg, "\n"); -- fflush(stdmsg); --} -- --// header is "Error: " by default (see mars.h) --void verror(Loc loc, const char *format, va_list ap, -- const char *p1, const char *p2, const char *header) --{ -- if (!global.gag) -- { -- verrorPrint(loc, header, format, ap, p1, p2); -- if (global.errors >= 20) // moderate blizzard of cascading messages -- fatal(); --//halt(); -- } -- else -- { -- global.gaggedErrors++; -- } -- global.errors++; --} -- --// Doesn't increase error count, doesn't print "Error:". --void verrorSupplemental(Loc loc, const char *format, va_list ap) --{ -- if (!global.gag) -- verrorPrint(loc, " ", format, ap); --} -- --void vwarning(Loc loc, const char *format, va_list ap) --{ -- if (global.params.warnings && !global.gag) -- { -- verrorPrint(loc, "Warning: ", format, ap); --//halt(); -- if (global.params.warnings == 1) -- global.warnings++; // warnings don't count if gagged -- } --} -- --void vdeprecation(Loc loc, const char *format, va_list ap, -- const char *p1, const char *p2) --{ -- static const char *header = "Deprecation: "; -- if (global.params.useDeprecated == 0) -- verror(loc, format, ap, p1, p2, header); -- else if (global.params.useDeprecated == 2 && !global.gag) -- verrorPrint(loc, header, format, ap, p1, p2); --} -- --/*************************************** -- * Call this after printing out fatal error messages to clean up and exit -- * the compiler. -- */ -- --void fatal() --{ --#if 0 -- halt(); --#endif -- exit(EXIT_FAILURE); --} -- --/************************************** -- * Try to stop forgetting to remove the breakpoints from -- * release builds. -- */ --void halt() --{ --#ifdef DEBUG -- *(volatile char*)0=0; --#endif --} -- --#ifndef IN_GCC -- --extern void backend_init(); --extern void backend_term(); -- --void usage() --{ --#if TARGET_LINUX -- const char fpic[] ="\ -- -fPIC generate position independent code\n\ --"; --#else -- const char fpic[] = ""; --#endif -- printf("DMD%d D Compiler %s\n%s %s\n", -- sizeof(size_t) * 8, -- global.version, global.copyright, global.written); -- printf("\ --Documentation: http://dlang.org/\n\ --Usage:\n\ -- dmd files.d ... { -switch }\n\ --\n\ -- files.d D source files\n\ -- @cmdfile read arguments from cmdfile\n\ -- -c do not link\n\ -- -cov do code coverage analysis\n\ -- -D generate documentation\n\ -- -Dddocdir write documentation file to docdir directory\n\ -- -Dffilename write documentation file to filename\n\ -- -d silently allow deprecated features\n\ -- -dw show use of deprecated features as warnings (default)\n\ -- -de show use of deprecated features as errors (halt compilation)\n\ -- -debug compile in debug code\n\ -- -debug=level compile in debug code <= level\n\ -- -debug=ident compile in debug code identified by ident\n\ -- -debuglib=name set symbolic debug library to name\n\ -- -defaultlib=name set default library to name\n\ -- -deps=filename write module dependencies to filename\n%s" --" -g add symbolic debug info\n\ -- -gc add symbolic debug info, pretend to be C\n\ -- -gs always emit stack frame\n\ -- -gx add stack stomp code\n\ -- -H generate 'header' file\n\ -- -Hddirectory write 'header' file to directory\n\ -- -Hffilename write 'header' file to filename\n\ -- --help print help\n\ -- -Ipath where to look for imports\n\ -- -ignore ignore unsupported pragmas\n\ -- -inline do function inlining\n\ -- -Jpath where to look for string imports\n\ -- -Llinkerflag pass linkerflag to link\n\ -- -lib generate library rather than object files\n" --#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS --" -m32 generate 32 bit code\n\ -- -m64 generate 64 bit code\n" --#endif --" -man open web browser on manual page\n\ -- -map generate linker .map file\n\ -- -noboundscheck turns off array bounds checking for all functions\n\ -- -O optimize\n\ -- -o- do not write object file\n\ -- -odobjdir write object & library files to directory objdir\n\ -- -offilename name output file to filename\n\ -- -op do not strip paths from source file\n\ -- -profile profile runtime performance of generated code\n\ -- -property enforce property syntax\n\ -- -quiet suppress unnecessary messages\n\ -- -release compile release version\n\ -- -run srcfile args... run resulting program, passing args\n" --#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS --" -shared generate shared library\n" --#endif --" -unittest compile in unit tests\n\ -- -v verbose\n\ -- -version=level compile in version code >= level\n\ -- -version=ident compile in version code identified by ident\n\ -- -vtls list all variables going into thread local storage\n\ -- -w warnings as errors (compilation will halt)\n\ -- -wi warnings as messages (compilation will continue)\n\ -- -X generate JSON file\n\ -- -Xffilename write JSON file to filename\n\ --", fpic); --} -- --extern signed char tyalignsize[]; -- --#if _WIN32 && __DMC__ --extern "C" --{ -- extern int _xi_a; -- extern int _end; --} --#endif -- --int tryMain(size_t argc, char *argv[]) --{ -- mem.init(); // initialize storage allocator -- mem.setStackBottom(&argv); --#if _WIN32 && __DMC__ -- mem.addroots((char *)&_xi_a, (char *)&_end); --#endif -- -- Strings files; -- Strings libmodules; -- char *p; -- Module *m; -- size_t argcstart = argc; -- int setdebuglib = 0; -- char noboundscheck = 0; -- int setdefaultlib = 0; -- const char *inifilename = NULL; -- --#ifdef DEBUG -- printf("DMD %s DEBUG\n", global.version); --#endif -- -- unittests(); -- -- // Check for malformed input -- if (argc < 1 || !argv) -- { -- Largs: -- error(0, "missing or null command line arguments"); -- fatal(); -- } -- for (size_t i = 0; i < argc; i++) -- { -- if (!argv[i]) -- goto Largs; -- } -- -- if (response_expand(&argc,&argv)) // expand response files -- error(0, "can't open response file"); -- -- files.reserve(argc - 1); -- -- // Set default values -- global.params.argv0 = argv[0]; -- global.params.link = 1; -- global.params.useAssert = 1; -- global.params.useInvariants = 1; -- global.params.useIn = 1; -- global.params.useOut = 1; -- global.params.useArrayBounds = 2; // default to all functions -- global.params.useSwitchError = 1; -- global.params.useInline = 0; -- global.params.obj = 1; -- global.params.Dversion = 2; -- global.params.quiet = 1; -- global.params.useDeprecated = 2; -- -- global.params.linkswitches = new Strings(); -- global.params.libfiles = new Strings(); -- global.params.objfiles = new Strings(); -- global.params.ddocfiles = new Strings(); -- -- // Default to -m32 for 32 bit dmd, -m64 for 64 bit dmd -- global.params.is64bit = (sizeof(size_t) == 8); -- --#if TARGET_WINDOS -- global.params.is64bit = 0; -- global.params.defaultlibname = "phobos"; --#elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS -- global.params.defaultlibname = "phobos2"; --#else --#error "fix this" --#endif -- -- // Predefine version identifiers -- VersionCondition::addPredefinedGlobalIdent("DigitalMars"); -- --#if TARGET_WINDOS -- VersionCondition::addPredefinedGlobalIdent("Windows"); -- global.params.isWindows = 1; --#elif TARGET_LINUX -- VersionCondition::addPredefinedGlobalIdent("Posix"); -- VersionCondition::addPredefinedGlobalIdent("linux"); -- global.params.isLinux = 1; --#elif TARGET_OSX -- VersionCondition::addPredefinedGlobalIdent("Posix"); -- VersionCondition::addPredefinedGlobalIdent("OSX"); -- global.params.isOSX = 1; -- -- // For legacy compatibility -- VersionCondition::addPredefinedGlobalIdent("darwin"); --#elif TARGET_FREEBSD -- VersionCondition::addPredefinedGlobalIdent("Posix"); -- VersionCondition::addPredefinedGlobalIdent("FreeBSD"); -- global.params.isFreeBSD = 1; --#elif TARGET_OPENBSD -- VersionCondition::addPredefinedGlobalIdent("Posix"); -- VersionCondition::addPredefinedGlobalIdent("OpenBSD"); -- global.params.isFreeBSD = 1; --#elif TARGET_SOLARIS -- VersionCondition::addPredefinedGlobalIdent("Posix"); -- VersionCondition::addPredefinedGlobalIdent("Solaris"); -- global.params.isSolaris = 1; --#else --#error "fix this" --#endif -- -- VersionCondition::addPredefinedGlobalIdent("LittleEndian"); -- //VersionCondition::addPredefinedGlobalIdent("D_Bits"); --#if DMDV2 -- VersionCondition::addPredefinedGlobalIdent("D_Version2"); --#endif -- VersionCondition::addPredefinedGlobalIdent("all"); -- --#if _WIN32 -- inifilename = inifile(argv[0], "sc.ini", "Environment"); --#elif linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun -- inifilename = inifile(argv[0], "dmd.conf", "Environment"); --#else --#error "fix this" --#endif -- -- size_t dflags_argc = 0; -- char** dflags_argv = NULL; -- getenv_setargv("DFLAGS", &dflags_argc, &dflags_argv); -- -- bool is64bit = global.params.is64bit; // use default -- is64bit = parse_arch(argc, argv, is64bit); -- is64bit = parse_arch(dflags_argc, dflags_argv, is64bit); -- global.params.is64bit = is64bit; -- -- inifile(argv[0], inifilename, is64bit ? "Environment64" : "Environment32"); -- -- getenv_setargv("DFLAGS", &argc, &argv); -- --#if 0 -- for (size_t i = 0; i < argc; i++) -- { -- printf("argv[%d] = '%s'\n", i, argv[i]); -- } --#endif -- -- for (size_t i = 1; i < argc; i++) -- { -- p = argv[i]; -- if (*p == '-') -- { -- if (strcmp(p + 1, "de") == 0) -- global.params.useDeprecated = 0; -- else if (strcmp(p + 1, "d") == 0) -- global.params.useDeprecated = 1; -- else if (strcmp(p + 1, "dw") == 0) -- global.params.useDeprecated = 2; -- else if (strcmp(p + 1, "c") == 0) -- global.params.link = 0; -- else if (strcmp(p + 1, "cov") == 0) -- global.params.cov = 1; --#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS -- else if (strcmp(p + 1, "shared") == 0 --#if TARGET_OSX -- // backwards compatibility with old switch -- || strcmp(p + 1, "dylib") == 0 --#endif -- ) -- global.params.dll = 1; -- else if (strcmp(p + 1, "fPIC") == 0) -- global.params.pic = 1; --#endif -- else if (strcmp(p + 1, "map") == 0) -- global.params.map = 1; -- else if (strcmp(p + 1, "multiobj") == 0) -- global.params.multiobj = 1; -- else if (strcmp(p + 1, "g") == 0) -- global.params.symdebug = 1; -- else if (strcmp(p + 1, "gc") == 0) -- global.params.symdebug = 2; -- else if (strcmp(p + 1, "gs") == 0) -- global.params.alwaysframe = 1; -- else if (strcmp(p + 1, "gx") == 0) -- global.params.stackstomp = true; -- else if (strcmp(p + 1, "gt") == 0) -- { error(0, "use -profile instead of -gt"); -- global.params.trace = 1; -- } -- else if (strcmp(p + 1, "m32") == 0) -- global.params.is64bit = 0; -- else if (strcmp(p + 1, "m64") == 0) -- global.params.is64bit = 1; -- else if (strcmp(p + 1, "profile") == 0) -- global.params.trace = 1; -- else if (strcmp(p + 1, "v") == 0) -- global.params.verbose = 1; --#if DMDV2 -- else if (strcmp(p + 1, "vtls") == 0) -- global.params.vtls = 1; --#endif -- else if (strcmp(p + 1, "v1") == 0) -- { --#if DMDV1 -- global.params.Dversion = 1; --#else -- error(0, "use DMD 1.0 series compilers for -v1 switch"); -- break; --#endif -- } -- else if (strcmp(p + 1, "w") == 0) -- global.params.warnings = 1; -- else if (strcmp(p + 1, "wi") == 0) -- global.params.warnings = 2; -- else if (strcmp(p + 1, "O") == 0) -- global.params.optimize = 1; -- else if (p[1] == 'o') -- { -- switch (p[2]) -- { -- case '-': -- global.params.obj = 0; -- break; -- -- case 'd': -- if (!p[3]) -- goto Lnoarg; -- global.params.objdir = p + 3; -- break; -- -- case 'f': -- if (!p[3]) -- goto Lnoarg; -- global.params.objname = p + 3; -- break; -- -- case 'p': -- if (p[3]) -- goto Lerror; -- global.params.preservePaths = 1; -- break; -- -- case 0: -- error(0, "-o no longer supported, use -of or -od"); -- break; -- -- default: -- goto Lerror; -- } -- } -- else if (p[1] == 'D') -- { global.params.doDocComments = 1; -- switch (p[2]) -- { -- case 'd': -- if (!p[3]) -- goto Lnoarg; -- global.params.docdir = p + 3; -- break; -- case 'f': -- if (!p[3]) -- goto Lnoarg; -- global.params.docname = p + 3; -- break; -- -- case 0: -- break; -- -- default: -- goto Lerror; -- } -- } -- else if (p[1] == 'H') -- { global.params.doHdrGeneration = 1; -- switch (p[2]) -- { -- case 'd': -- if (!p[3]) -- goto Lnoarg; -- global.params.hdrdir = p + 3; -- break; -- -- case 'f': -- if (!p[3]) -- goto Lnoarg; -- global.params.hdrname = p + 3; -- break; -- -- case 0: -- break; -- -- default: -- goto Lerror; -- } -- } -- else if (p[1] == 'X') -- { global.params.doXGeneration = 1; -- switch (p[2]) -- { -- case 'f': -- if (!p[3]) -- goto Lnoarg; -- global.params.xfilename = p + 3; -- break; -- -- case 0: -- break; -- -- default: -- goto Lerror; -- } -- } -- else if (strcmp(p + 1, "ignore") == 0) -- global.params.ignoreUnsupportedPragmas = 1; -- else if (strcmp(p + 1, "property") == 0) -- global.params.enforcePropertySyntax = 1; -- else if (strcmp(p + 1, "inline") == 0) -- global.params.useInline = 1; -- else if (strcmp(p + 1, "lib") == 0) -- global.params.lib = 1; -- else if (strcmp(p + 1, "nofloat") == 0) -- global.params.nofloat = 1; -- else if (strcmp(p + 1, "quiet") == 0) -- global.params.quiet = 1; -- else if (strcmp(p + 1, "release") == 0) -- global.params.release = 1; -- else if (strcmp(p + 1, "betterC") == 0) -- global.params.betterC = 1; --#if DMDV2 -- else if (strcmp(p + 1, "noboundscheck") == 0) -- noboundscheck = 1; --#endif -- else if (strcmp(p + 1, "unittest") == 0) -- global.params.useUnitTests = 1; -- else if (p[1] == 'I') -- { -- if (!global.params.imppath) -- global.params.imppath = new Strings(); -- global.params.imppath->push(p + 2); -- } -- else if (p[1] == 'J') -- { -- if (!global.params.fileImppath) -- global.params.fileImppath = new Strings(); -- global.params.fileImppath->push(p + 2); -- } -- else if (memcmp(p + 1, "debug", 5) == 0 && p[6] != 'l') -- { -- // Parse: -- // -debug -- // -debug=number -- // -debug=identifier -- if (p[6] == '=') -- { -- if (isdigit((unsigned char)p[7])) -- { long level; -- -- errno = 0; -- level = strtol(p + 7, &p, 10); -- if (*p || errno || level > INT_MAX) -- goto Lerror; -- DebugCondition::setGlobalLevel((int)level); -- } -- else if (Lexer::isValidIdentifier(p + 7)) -- DebugCondition::addGlobalIdent(p + 7); -- else -- goto Lerror; -- } -- else if (p[6]) -- goto Lerror; -- else -- global.params.debuglevel = 1; -- } -- else if (memcmp(p + 1, "version", 7) == 0) -- { -- // Parse: -- // -version=number -- // -version=identifier -- if (p[8] == '=') -- { -- if (isdigit((unsigned char)p[9])) -- { long level; -- -- errno = 0; -- level = strtol(p + 9, &p, 10); -- if (*p || errno || level > INT_MAX) -- goto Lerror; -- VersionCondition::setGlobalLevel((int)level); -- } -- else if (Lexer::isValidIdentifier(p + 9)) -- VersionCondition::addGlobalIdent(p + 9); -- else -- goto Lerror; -- } -- else -- goto Lerror; -- } -- else if (strcmp(p + 1, "-b") == 0) -- global.params.debugb = 1; -- else if (strcmp(p + 1, "-c") == 0) -- global.params.debugc = 1; -- else if (strcmp(p + 1, "-f") == 0) -- global.params.debugf = 1; -- else if (strcmp(p + 1, "-help") == 0) -- { usage(); -- exit(EXIT_SUCCESS); -- } -- else if (strcmp(p + 1, "-r") == 0) -- global.params.debugr = 1; -- else if (strcmp(p + 1, "-x") == 0) -- global.params.debugx = 1; -- else if (strcmp(p + 1, "-y") == 0) -- global.params.debugy = 1; -- else if (p[1] == 'L') -- { -- global.params.linkswitches->push(p + 2); -- } -- else if (memcmp(p + 1, "defaultlib=", 11) == 0) -- { -- setdefaultlib = 1; -- global.params.defaultlibname = p + 1 + 11; -- } -- else if (memcmp(p + 1, "debuglib=", 9) == 0) -- { -- setdebuglib = 1; -- global.params.debuglibname = p + 1 + 9; -- } -- else if (memcmp(p + 1, "deps=", 5) == 0) -- { -- global.params.moduleDepsFile = p + 1 + 5; -- if (!global.params.moduleDepsFile[0]) -- goto Lnoarg; -- global.params.moduleDeps = new OutBuffer; -- } -- else if (memcmp(p + 1, "man", 3) == 0) -- { --#if _WIN32 --#if DMDV1 -- browse("http://www.digitalmars.com/d/1.0/dmd-windows.html"); --#else -- browse("http://dlang.org/dmd-windows.html"); --#endif --#endif --#if linux --#if DMDV1 -- browse("http://www.digitalmars.com/d/1.0/dmd-linux.html"); --#else -- browse("http://dlang.org/dmd-linux.html"); --#endif --#endif --#if __APPLE__ --#if DMDV1 -- browse("http://www.digitalmars.com/d/1.0/dmd-osx.html"); --#else -- browse("http://dlang.org/dmd-osx.html"); --#endif --#endif --#if __FreeBSD__ --#if DMDV1 -- browse("http://www.digitalmars.com/d/1.0/dmd-freebsd.html"); --#else -- browse("http://dlang.org/dmd-freebsd.html"); --#endif --#endif --#if __OpenBSD__ --#if DMDV1 -- browse("http://www.digitalmars.com/d/1.0/dmd-openbsd.html"); --#else -- browse("http://dlang.org/dmd-openbsd.html"); --#endif --#endif -- exit(EXIT_SUCCESS); -- } -- else if (strcmp(p + 1, "run") == 0) -- { global.params.run = 1; -- global.params.runargs_length = ((i >= argcstart) ? argc : argcstart) - i - 1; -- if (global.params.runargs_length) -- { -- const char *ext = FileName::ext(argv[i + 1]); -- if (ext && FileName::equals(ext, "d") == 0 -- && FileName::equals(ext, "di") == 0) -- { -- error(0, "-run must be followed by a source file, not '%s'", argv[i + 1]); -- break; -- } -- -- files.push(argv[i + 1]); -- global.params.runargs = &argv[i + 2]; -- i += global.params.runargs_length; -- global.params.runargs_length--; -- } -- else -- { global.params.run = 0; -- goto Lnoarg; -- } -- } -- else -- { -- Lerror: -- error(0, "unrecognized switch '%s'", argv[i]); -- continue; -- -- Lnoarg: -- error(0, "argument expected for switch '%s'", argv[i]); -- continue; -- } -- } -- else -- { --#if TARGET_WINDOS -- const char *ext = FileName::ext(p); -- if (ext && FileName::compare(ext, "exe") == 0) -- { -- global.params.objname = p; -- continue; -- } --#endif -- files.push(p); -- } -- } -- -- if(global.params.is64bit != is64bit) -- error(0, "the architecture must not be changed in the %s section of %s", -- is64bit ? "Environment64" : "Environment32", inifilename); -- -- if (global.errors) -- { -- fatal(); -- } -- if (files.dim == 0) -- { usage(); -- return EXIT_FAILURE; -- } -- -- if (!setdebuglib) -- global.params.debuglibname = global.params.defaultlibname; -- --#if TARGET_OSX -- global.params.pic = 1; --#endif -- --#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS -- if (global.params.lib && global.params.dll) -- error(0, "cannot mix -lib and -shared"); --#endif -- -- if (global.params.release) -- { global.params.useInvariants = 0; -- global.params.useIn = 0; -- global.params.useOut = 0; -- global.params.useAssert = 0; -- global.params.useArrayBounds = 1; -- global.params.useSwitchError = 0; -- } -- if (noboundscheck) -- global.params.useArrayBounds = 0; -- -- if (global.params.run) -- global.params.quiet = 1; -- -- if (global.params.useUnitTests) -- global.params.useAssert = 1; -- -- if (!global.params.obj || global.params.lib) -- global.params.link = 0; -- -- if (global.params.link) -- { -- global.params.exefile = global.params.objname; -- global.params.oneobj = 1; -- if (global.params.objname) -- { -- /* Use this to name the one object file with the same -- * name as the exe file. -- */ -- global.params.objname = const_cast(FileName::forceExt(global.params.objname, global.obj_ext)); -- -- /* If output directory is given, use that path rather than -- * the exe file path. -- */ -- if (global.params.objdir) -- { const char *name = FileName::name(global.params.objname); -- global.params.objname = (char *)FileName::combine(global.params.objdir, name); -- } -- } -- } -- else if (global.params.lib) -- { -- global.params.libname = global.params.objname; -- global.params.objname = NULL; -- -- // Haven't investigated handling these options with multiobj -- if (!global.params.cov && !global.params.trace --#if 0 && TARGET_WINDOS -- /* multiobj causes class/struct debug info to be attached to init-data, -- * but this will not be linked into the executable, so this info is lost. -- * Bugzilla 4014 -- */ -- && !global.params.symdebug --#endif -- ) -- global.params.multiobj = 1; -- } -- else if (global.params.run) -- { -- error(0, "flags conflict with -run"); -- fatal(); -- } -- else -- { -- if (global.params.objname && files.dim > 1) -- { -- global.params.oneobj = 1; -- //error("multiple source files, but only one .obj name"); -- //fatal(); -- } -- } -- if (global.params.is64bit) -- { -- VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86_64"); -- VersionCondition::addPredefinedGlobalIdent("X86_64"); -- VersionCondition::addPredefinedGlobalIdent("D_LP64"); -- VersionCondition::addPredefinedGlobalIdent("D_SIMD"); --#if TARGET_WINDOS -- VersionCondition::addPredefinedGlobalIdent("Win64"); -- if (!setdefaultlib) -- { global.params.defaultlibname = "phobos64"; -- if (!setdebuglib) -- global.params.debuglibname = global.params.defaultlibname; -- } --#endif -- } -- else -- { -- VersionCondition::addPredefinedGlobalIdent("D_InlineAsm"); -- VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86"); -- VersionCondition::addPredefinedGlobalIdent("X86"); --#if TARGET_OSX -- VersionCondition::addPredefinedGlobalIdent("D_SIMD"); --#endif --#if TARGET_WINDOS -- VersionCondition::addPredefinedGlobalIdent("Win32"); --#endif -- } -- if (global.params.doDocComments) -- VersionCondition::addPredefinedGlobalIdent("D_Ddoc"); -- if (global.params.cov) -- VersionCondition::addPredefinedGlobalIdent("D_Coverage"); -- if (global.params.pic) -- VersionCondition::addPredefinedGlobalIdent("D_PIC"); --#if DMDV2 -- if (global.params.useUnitTests) -- VersionCondition::addPredefinedGlobalIdent("unittest"); -- if (global.params.useAssert) -- VersionCondition::addPredefinedGlobalIdent("assert"); -- if (noboundscheck) -- VersionCondition::addPredefinedGlobalIdent("D_NoBoundsChecks"); --#endif -- -- VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); -- -- // Initialization -- Type::init(); -- Id::initialize(); -- Module::init(); -- initPrecedence(); -- -- if (global.params.verbose) -- { printf("binary %s\n", argv[0]); -- printf("version %s\n", global.version); -- printf("config %s\n", inifilename ? inifilename : "(none)"); -- } -- -- //printf("%d source files\n",files.dim); -- -- // Build import search path -- if (global.params.imppath) -- { -- for (size_t i = 0; i < global.params.imppath->dim; i++) -- { -- char *path = (*global.params.imppath)[i]; -- Strings *a = FileName::splitPath(path); -- -- if (a) -- { -- if (!global.path) -- global.path = new Strings(); -- global.path->append(a); -- } -- } -- } -- -- // Build string import search path -- if (global.params.fileImppath) -- { -- for (size_t i = 0; i < global.params.fileImppath->dim; i++) -- { -- char *path = (*global.params.fileImppath)[i]; -- Strings *a = FileName::splitPath(path); -- -- if (a) -- { -- if (!global.filePath) -- global.filePath = new Strings(); -- global.filePath->append(a); -- } -- } -- } -- -- // Create Modules -- Modules modules; -- modules.reserve(files.dim); -- int firstmodule = 1; -- for (size_t i = 0; i < files.dim; i++) -- { -- const char *ext; -- char *name; -- -- p = files[i]; -- --#if _WIN32 -- // Convert / to \ so linker will work -- for (size_t j = 0; p[j]; j++) -- { -- if (p[j] == '/') -- p[j] = '\\'; -- } --#endif -- -- p = (char *)FileName::name(p); // strip path -- ext = FileName::ext(p); -- if (ext) -- { /* Deduce what to do with a file based on its extension -- */ -- if (FileName::equals(ext, global.obj_ext)) -- { -- global.params.objfiles->push(files[i]); -- libmodules.push(files[i]); -- continue; -- } -- -- if (FileName::equals(ext, global.lib_ext)) -- { -- global.params.libfiles->push(files[i]); -- libmodules.push(files[i]); -- continue; -- } -- -- if (strcmp(ext, global.ddoc_ext) == 0) -- { -- global.params.ddocfiles->push(files[i]); -- continue; -- } -- -- if (FileName::equals(ext, global.json_ext)) -- { -- global.params.doXGeneration = 1; -- global.params.xfilename = files[i]; -- continue; -- } -- -- if (FileName::equals(ext, global.map_ext)) -- { -- global.params.mapfile = files[i]; -- continue; -- } -- --#if TARGET_WINDOS -- if (FileName::equals(ext, "res")) -- { -- global.params.resfile = files[i]; -- continue; -- } -- -- if (FileName::equals(ext, "def")) -- { -- global.params.deffile = files[i]; -- continue; -- } -- -- if (FileName::equals(ext, "exe")) -- { -- assert(0); // should have already been handled -- } --#endif -- -- /* Examine extension to see if it is a valid -- * D source file extension -- */ -- if (FileName::equals(ext, global.mars_ext) || -- FileName::equals(ext, global.hdr_ext) || -- FileName::equals(ext, "dd")) -- { -- ext--; // skip onto '.' -- assert(*ext == '.'); -- name = (char *)mem.malloc((ext - p) + 1); -- memcpy(name, p, ext - p); -- name[ext - p] = 0; // strip extension -- -- if (name[0] == 0 || -- strcmp(name, "..") == 0 || -- strcmp(name, ".") == 0) -- { -- Linvalid: -- error(0, "invalid file name '%s'", files[i]); -- fatal(); -- } -- } -- else -- { error(0, "unrecognized file extension %s", ext); -- fatal(); -- } -- } -- else -- { name = p; -- if (!*name) -- goto Linvalid; -- } -- -- /* At this point, name is the D source file name stripped of -- * its path and extension. -- */ -- -- Identifier *id = Lexer::idPool(name); -- m = new Module(files[i], id, global.params.doDocComments, global.params.doHdrGeneration); -- modules.push(m); -- -- if (firstmodule) -- { global.params.objfiles->push((char *)m->objfile->name->str); -- firstmodule = 0; -- } -- } -- -- // Read files --#define ASYNCREAD 1 --#if ASYNCREAD -- // Multi threaded -- AsyncRead *aw = AsyncRead::create(modules.dim); -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- aw->addFile(m->srcfile); -- } -- aw->start(); --#else -- // Single threaded -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- m->read(0); -- } --#endif -- -- // Parse files -- bool anydocfiles = false; -- size_t filecount = modules.dim; -- for (size_t filei = 0, modi = 0; filei < filecount; filei++, modi++) -- { -- m = modules[modi]; -- if (global.params.verbose) -- printf("parse %s\n", m->toChars()); -- if (!Module::rootModule) -- Module::rootModule = m; -- m->importedFrom = m; -- if (!global.params.oneobj || modi == 0 || m->isDocFile) -- m->deleteObjFile(); --#if ASYNCREAD -- if (aw->read(filei)) -- { -- error(0, "cannot read file %s", m->srcfile->name->toChars()); -- fatal(); -- } --#endif -- m->parse(); -- if (m->isDocFile) -- { -- anydocfiles = true; -- m->gendocfile(); -- -- // Remove m from list of modules -- modules.remove(modi); -- modi--; -- -- // Remove m's object file from list of object files -- for (size_t j = 0; j < global.params.objfiles->dim; j++) -- { -- if (m->objfile->name->str == (*global.params.objfiles)[j]) -- { -- global.params.objfiles->remove(j); -- break; -- } -- } -- -- if (global.params.objfiles->dim == 0) -- global.params.link = 0; -- } -- } --#if ASYNCREAD -- AsyncRead::dispose(aw); --#endif -- -- if (anydocfiles && modules.dim && -- (global.params.oneobj || global.params.objname)) -- { -- error(0, "conflicting Ddoc and obj generation options"); -- fatal(); -- } -- if (global.errors) -- fatal(); -- if (global.params.doHdrGeneration) -- { -- /* Generate 'header' import files. -- * Since 'header' import files must be independent of command -- * line switches and what else is imported, they are generated -- * before any semantic analysis. -- */ -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("import %s\n", m->toChars()); -- m->genhdrfile(); -- } -- } -- if (global.errors) -- fatal(); -- -- // load all unconditional imports for better symbol resolving -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("importall %s\n", m->toChars()); -- m->importAll(0); -- } -- if (global.errors) -- fatal(); -- -- backend_init(); -- -- // Do semantic analysis -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("semantic %s\n", m->toChars()); -- m->semantic(); -- } -- if (global.errors) -- fatal(); -- -- Module::dprogress = 1; -- Module::runDeferredSemantic(); -- -- // Do pass 2 semantic analysis -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("semantic2 %s\n", m->toChars()); -- m->semantic2(); -- } -- if (global.errors) -- fatal(); -- -- // Do pass 3 semantic analysis -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("semantic3 %s\n", m->toChars()); -- m->semantic3(); -- } -- if (global.errors) -- fatal(); -- -- if (global.params.useInline) -- { -- /* The problem with useArrayBounds and useAssert is that the -- * module being linked to may not have generated them, so if -- * we inline functions from those modules, the symbols for them will -- * not be found at link time. -- * We must do this BEFORE generating the .deps file! -- */ -- if (!global.params.useArrayBounds && !global.params.useAssert) -- { -- // Do pass 3 semantic analysis on all imported modules, -- // since otherwise functions in them cannot be inlined -- for (size_t i = 0; i < Module::amodules.dim; i++) -- { -- m = Module::amodules[i]; -- if (global.params.verbose) -- printf("semantic3 %s\n", m->toChars()); -- m->semantic3(); -- } -- if (global.errors) -- fatal(); -- } -- } -- -- if (global.params.moduleDeps != NULL) -- { -- assert(global.params.moduleDepsFile != NULL); -- -- File deps(global.params.moduleDepsFile); -- OutBuffer* ob = global.params.moduleDeps; -- deps.setbuffer((void*)ob->data, ob->offset); -- deps.writev(); -- } -- -- // Scan for functions to inline -- if (global.params.useInline) -- { -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("inline scan %s\n", m->toChars()); -- m->inlineScan(); -- } -- } -- -- // Do not attempt to generate output files if errors or warnings occurred -- if (global.errors || global.warnings) -- fatal(); -- -- printCtfePerformanceStats(); -- -- Library *library = NULL; -- if (global.params.lib) -- { -- library = Library::factory(); -- library->setFilename(global.params.objdir, global.params.libname); -- -- // Add input object and input library files to output library -- for (size_t i = 0; i < libmodules.dim; i++) -- { -- char *p = libmodules[i]; -- library->addObject(p, NULL, 0); -- } -- } -- -- // Generate output files -- -- if (global.params.doXGeneration) -- { -- OutBuffer buf; -- json_generate(&buf, &modules); -- -- // Write buf to file -- const char *name = global.params.xfilename; -- -- if (name && name[0] == '-' && name[1] == 0) -- { // Write to stdout; assume it succeeds -- int n = fwrite(buf.data, 1, buf.offset, stdout); -- assert(n == buf.offset); // keep gcc happy about return values -- } -- else -- { -- /* The filename generation code here should be harmonized with Module::setOutfile() -- */ -- -- const char *jsonfilename; -- -- if (name && *name) -- { -- jsonfilename = FileName::defaultExt(name, global.json_ext); -- } -- else -- { -- // Generate json file name from first obj name -- const char *n = (*global.params.objfiles)[0]; -- n = FileName::name(n); -- -- //if (!FileName::absolute(name)) -- //name = FileName::combine(dir, name); -- -- jsonfilename = FileName::forceExt(n, global.json_ext); -- } -- -- FileName::ensurePathToNameExists(jsonfilename); -- -- File *jsonfile = new File(jsonfilename); -- -- jsonfile->setbuffer(buf.data, buf.offset); -- jsonfile->ref = 1; -- jsonfile->writev(); -- } -- } -- -- if (global.params.oneobj) -- { -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("code %s\n", m->toChars()); -- if (i == 0) -- obj_start(m->srcfile->toChars()); -- m->genobjfile(0); -- if (!global.errors && global.params.doDocComments) -- m->gendocfile(); -- } -- if (!global.errors && modules.dim) -- { -- obj_end(library, modules[0]->objfile); -- } -- } -- else -- { -- for (size_t i = 0; i < modules.dim; i++) -- { -- m = modules[i]; -- if (global.params.verbose) -- printf("code %s\n", m->toChars()); -- if (global.params.obj) -- { obj_start(m->srcfile->toChars()); -- m->genobjfile(global.params.multiobj); -- obj_end(library, m->objfile); -- obj_write_deferred(library); -- } -- if (global.errors) -- { -- if (!global.params.lib) -- m->deleteObjFile(); -- } -- else -- { -- if (global.params.doDocComments) -- m->gendocfile(); -- } -- } -- } -- -- if (global.params.lib && !global.errors) -- library->write(); -- -- backend_term(); -- if (global.errors) -- fatal(); -- -- int status = EXIT_SUCCESS; -- if (!global.params.objfiles->dim) -- { -- if (global.params.link) -- error(0, "no object files to link"); -- } -- else -- { -- if (global.params.link) -- status = runLINK(); -- -- if (global.params.run) -- { -- if (!status) -- { -- status = runProgram(); -- -- /* Delete .obj files and .exe file -- */ -- for (size_t i = 0; i < modules.dim; i++) -- { -- Module *m = modules[i]; -- m->deleteObjFile(); -- if (global.params.oneobj) -- break; -- } -- deleteExeFile(); -- } -- } -- } -- -- return status; --} -- --int main(int argc, char *argv[]) --{ -- int status = -1; --#if WINDOWS_SEH -- __try -- { --#endif -- status = tryMain(argc, argv); --#if WINDOWS_SEH -- } -- __except (__ehfilter(GetExceptionInformation())) -- { -- printf("Stack overflow\n"); -- fatal(); -- } --#endif -- return status; --} -- -- --/*********************************** -- * Parse and append contents of environment variable envvar -- * to argc and argv[]. -- * The string is separated into arguments, processing \ and ". -- */ -- --void getenv_setargv(const char *envvar, size_t *pargc, char** *pargv) --{ -- char *p; -- -- int instring; -- int slash; -- char c; -- -- char *env = getenv(envvar); -- if (!env) -- return; -- -- env = mem.strdup(env); // create our own writable copy -- -- size_t argc = *pargc; -- Strings *argv = new Strings(); -- argv->setDim(argc); -- -- for (size_t i = 0; i < argc; i++) -- (*argv)[i] = (*pargv)[i]; -- -- size_t j = 1; // leave argv[0] alone -- while (1) -- { -- int wildcard = 1; // do wildcard expansion -- switch (*env) -- { -- case ' ': -- case '\t': -- env++; -- break; -- -- case 0: -- goto Ldone; -- -- case '"': -- wildcard = 0; -- default: -- argv->push(env); // append -- //argv->insert(j, env); // insert at position j -- j++; -- argc++; -- p = env; -- slash = 0; -- instring = 0; -- c = 0; -- -- while (1) -- { -- c = *env++; -- switch (c) -- { -- case '"': -- p -= (slash >> 1); -- if (slash & 1) -- { p--; -- goto Laddc; -- } -- instring ^= 1; -- slash = 0; -- continue; -- -- case ' ': -- case '\t': -- if (instring) -- goto Laddc; -- *p = 0; -- //if (wildcard) -- //wildcardexpand(); // not implemented -- break; -- -- case '\\': -- slash++; -- *p++ = c; -- continue; -- -- case 0: -- *p = 0; -- //if (wildcard) -- //wildcardexpand(); // not implemented -- goto Ldone; -- -- default: -- Laddc: -- slash = 0; -- *p++ = c; -- continue; -- } -- break; -- } -- } -- } -- --Ldone: -- *pargc = argc; -- *pargv = argv->tdata(); --} -- --/*********************************** -- * Parse command line arguments for -m32 or -m64 -- * to detect the desired architecture. -- */ -- --static bool parse_arch(size_t argc, char** argv, bool is64bit) --{ -- for (size_t i = 0; i < argc; ++i) -- { char* p = argv[i]; -- if (p[0] == '-') -- { -- if (strcmp(p + 1, "m32") == 0) -- is64bit = 0; -- else if (strcmp(p + 1, "m64") == 0) -- is64bit = 1; -- else if (strcmp(p + 1, "run") == 0) -- break; -- } -- } -- return is64bit; --} -- --#if WINDOWS_SEH -- --long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep) --{ -- //printf("%x\n", ep->ExceptionRecord->ExceptionCode); -- if (ep->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW) -- { --#if 1 //ndef DEBUG -- return EXCEPTION_EXECUTE_HANDLER; --#endif -- } -- return EXCEPTION_CONTINUE_SEARCH; --} -- --#endif -- --#endif ---- a/src/gcc/d/dfrontend/mars.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/mars.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -80,17 +80,11 @@ the target object file format: - #endif - void unittests(); - --#ifdef IN_GCC --/* Changes for the GDC compiler by David Friedman */ --#endif -- - #define DMDV1 0 - #define DMDV2 1 // Version 2.0 features - #define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN - #define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class --#define BUG6652 2 // Making foreach range statement parameter non-ref in default -- // 1: Modifying iteratee in body is warned with -w switch -- // 2: Modifying iteratee in body is error without -d switch -+#define PULL93 0 // controversial pull #93 for bugzilla 3449 - - // Set if C++ mangling is done by the front end - #define CPP_MANGLE (IN_GCC || (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS))) -@@ -125,9 +119,9 @@ void unittests(); - struct OutBuffer; - - // Can't include arraytypes.h here, need to declare these directly. --template struct ArrayBase; --typedef ArrayBase Identifiers; --typedef ArrayBase Strings; -+template struct Array; -+typedef Array Identifiers; -+typedef Array Strings; - - // Put command line switches in here - struct Param -@@ -142,11 +136,11 @@ struct Param - char quiet; // suppress non-error messages - char verbose; // verbose compile - char vtls; // identify thread local variables -+ char vfield; // identify non-mutable field variables - char symdebug; // insert debug symbolic information - bool alwaysframe; // always emit standard stack frame - bool optimize; // run optimizer - char map; // generate linker .map file -- char cpu; // target CPU - char is64bit; // generate 64 bit code - char isLP64; // generate code for LP64 - char isLinux; // generate code for linux -@@ -177,12 +171,14 @@ struct Param - // 1: warnings as errors - // 2: informational warnings (no errors) - bool pic; // generate position-independent-code for shared libs -- char cov; // generate code coverage data -+ bool cov; // generate code coverage data -+ unsigned char covPercent; // 0..100 code coverage percentage required - bool nofloat; // code should not pull in floating point support -- char Dversion; // D version number - char ignoreUnsupportedPragmas; // rather than error on them - char enforcePropertySyntax; - char betterC; // be a "better C" compiler; no dependency on D runtime -+ bool addMain; // add a default main() function -+ bool allInst; // generate code for all template instantiations - - char *argv0; // program name - Strings *imppath; // array of char*'s of where to look for import modules -@@ -246,10 +242,23 @@ struct Param - char *mapfile; - }; - -+struct Compiler -+{ -+ const char *vendor; // Compiler backend name -+}; -+ - typedef unsigned structalign_t; - #define STRUCTALIGN_DEFAULT ~0 // magic value means "match whatever the underlying C compiler does" - // other values are all powers of 2 - -+struct Ungag -+{ -+ unsigned oldgag; -+ -+ Ungag(unsigned old) : oldgag(old) {} -+ ~Ungag(); -+}; -+ - struct Global - { - const char *mars_ext; -@@ -264,16 +273,17 @@ struct Global - const char *map_ext; // for .map files - const char *copyright; - const char *written; -+ const char *main_d; // dummy filename for dummy main() - Strings *path; // Array of char*'s which form the import lookup path - Strings *filePath; // Array of char*'s which form the file import lookup path - -- structalign_t structalign; // default alignment for struct fields -- - const char *version; - -+ Compiler compiler; - Param params; - unsigned errors; // number of errors reported so far - unsigned warnings; // number of warnings reported so far -+ FILE *stdmsg; // where to send verbose messages - unsigned gag; // !=0 means gag reporting of errors & warnings - unsigned gaggedErrors; // number of errors reported while gagged - -@@ -291,16 +301,17 @@ struct Global - */ - bool endGagging(unsigned oldGagged); - -- Global(); -+ /* Increment the error count to record that an error -+ * has occured in the current context. An error message -+ * may or may not have been printed. -+ */ -+ void increaseErrorCount(); -+ -+ void init(); - }; - - extern Global global; - --/* Set if Windows Structured Exception Handling C extensions are supported. -- * Apparently, VC has dropped support for these? -- */ --#define WINDOWS_SEH _WIN32 -- - #include "longdouble.h" - - #ifdef __DMC__ -@@ -310,17 +321,36 @@ extern Global global; - #include "complex_t.h" - #endif - -+// Be careful not to care about sign when using dinteger_t -+//typedef uint64_t integer_t; -+typedef uint64_t dinteger_t; // use this instead of integer_t to -+ // avoid conflicts with system #include's -+ -+// Signed and unsigned variants -+typedef int64_t sinteger_t; -+typedef uint64_t uinteger_t; -+ -+typedef int8_t d_int8; -+typedef uint8_t d_uns8; -+typedef int16_t d_int16; -+typedef uint16_t d_uns16; -+typedef int32_t d_int32; -+typedef uint32_t d_uns32; -+typedef int64_t d_int64; -+typedef uint64_t d_uns64; -+ -+typedef float d_float32; -+typedef double d_float64; -+typedef longdouble d_float80; -+ -+typedef d_uns8 d_char; -+typedef d_uns16 d_wchar; -+typedef d_uns32 d_dchar; -+ - typedef longdouble real_t; - --// Modify OutBuffer::writewchar to write the correct size of wchar --#if _WIN32 --#define writewchar writeword --#else --// This needs a configuration test... --#define writewchar write4 --#endif - --struct Module; -+class Module; - - //typedef unsigned Loc; // file location - struct Loc -@@ -334,12 +364,6 @@ struct Loc - filename = NULL; - } - -- Loc(int x) -- { -- linnum = x; -- filename = NULL; -- } -- - Loc(Module *mod, unsigned linnum); - - char *toChars(); -@@ -414,23 +438,21 @@ void deleteExeFile(); - int runProgram(); - const char *inifile(const char *argv0, const char *inifile, const char* envsectionname); - void halt(); --void util_progress(); - --/*** Where to send error messages ***/ --#ifdef IN_GCC --#define stdmsg stderr --#else --#define stdmsg stderr --#endif -- --struct Dsymbol; -+class Dsymbol; - class Library; --struct File; -+class File; - void obj_start(char *srcfile); - void obj_end(Library *library, File *objfile); - void obj_append(Dsymbol *s); - void obj_write_deferred(Library *library); - -+void readFile(Loc loc, File *f); -+void writeFile(Loc loc, File *f); -+void ensurePathToNameExists(Loc loc, const char *name); -+ - const char *importHint(const char *s); -+/// Little helper function for writting out deps. -+void escapePath(OutBuffer *buf, const char *fname); - - #endif /* DMD_MARS_H */ ---- a/src/gcc/d/dfrontend/module.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/module.c 2014-04-01 16:32:51.000000000 +0100 -@@ -27,15 +27,18 @@ - #include "d-dmd-gcc.h" - #endif - --ClassDeclaration *Module::moduleinfo; -+AggregateDeclaration *Module::moduleinfo; - - Module *Module::rootModule; - DsymbolTable *Module::modules; - Modules Module::amodules; - - Dsymbols Module::deferred; // deferred Dsymbol's needing semantic() run on them -+Dsymbols Module::deferred3; - unsigned Module::dprogress; - -+const char *lookForSourceFile(const char *filename); -+ - void Module::init() - { - modules = new DsymbolTable(); -@@ -57,13 +60,7 @@ Module::Module(char *filename, Identifie - needmoduleinfo = 0; - selfimports = 0; - insearch = 0; -- searchCacheIdent = NULL; -- searchCacheSymbol = NULL; -- searchCacheFlags = 0; -- semanticstarted = 0; -- semanticRun = 0; - decldefs = NULL; -- vmoduleinfo = NULL; - massert = NULL; - munittest = NULL; - marray = NULL; -@@ -74,7 +71,6 @@ Module::Module(char *filename, Identifie - sshareddtor = NULL; - stest = NULL; - sfilename = NULL; -- root = 0; - importedFrom = NULL; - srcfile = NULL; - docfile = NULL; -@@ -218,55 +214,23 @@ Module *Module::load(Loc loc, Identifier - m = new Module(filename, ident, 0, 0); - m->loc = loc; - -- /* Search along global.path for .di file, then .d file. -+ /* Look for the source file - */ -- const char *result = NULL; -- const char *fdi = FileName::forceExt(filename, global.hdr_ext); -- const char *fd = FileName::forceExt(filename, global.mars_ext); -- const char *sdi = fdi; -- const char *sd = fd; -- -- if (FileName::exists(sdi)) -- result = sdi; -- else if (FileName::exists(sd)) -- result = sd; -- else if (FileName::absolute(filename)) -- ; -- else if (!global.path) -- ; -- else -- { -- for (size_t i = 0; i < global.path->dim; i++) -- { -- const char *p = (*global.path)[i]; -- const char *n = FileName::combine(p, sdi); -- if (FileName::exists(n)) -- { result = n; -- break; -- } -- FileName::free(n); -- n = FileName::combine(p, sd); -- if (FileName::exists(n)) -- { result = n; -- break; -- } -- FileName::free(n); -- } -- } -+ const char *result = lookForSourceFile(filename); - if (result) - m->srcfile = new File(result); - - if (global.params.verbose) - { -- fprintf(stdmsg, "import "); -+ fprintf(global.stdmsg, "import "); - if (packages) - { - for (size_t i = 0; i < packages->dim; i++) - { Identifier *pid = (*packages)[i]; -- fprintf(stdmsg, "%s.", pid->toChars()); -+ fprintf(global.stdmsg, "%s.", pid->toChars()); - } - } -- fprintf(stdmsg, "%s\t(%s)\n", ident->toChars(), m->srcfile->toChars()); -+ fprintf(global.stdmsg, "%s\t(%s)\n", ident->toChars(), m->srcfile->toChars()); - } - - if (!m->read(loc)) -@@ -293,7 +257,15 @@ bool Module::read(Loc loc) - } - else - { -- error(loc, "is in file '%s' which cannot be read", srcfile->toChars()); -+ // if module is not named 'package' but we're trying to read 'package.d', we're looking for a package module -+ bool isPackageMod = (strcmp(toChars(), "package") != 0) && -+ (strcmp(srcfile->name->name(), "package.d") == 0); -+ -+ if (isPackageMod) -+ ::error(loc, "importing package '%s' requires a 'package.d' file which cannot be found in '%s'", -+ toChars(), srcfile->toChars()); -+ else -+ error(loc, "is in file '%s' which cannot be read", srcfile->toChars()); - } - - if (!global.gag) -@@ -304,11 +276,11 @@ bool Module::read(Loc loc) - for (size_t i = 0; i < global.path->dim; i++) - { - char *p = (*global.path)[i]; -- fprintf(stdmsg, "import path[%llu] = %s\n", (ulonglong)i, p); -+ fprintf(stderr, "import path[%llu] = %s\n", (ulonglong)i, p); - } - } - else -- fprintf(stdmsg, "Specify path to file '%s' with -I switch\n", srcfile->toChars()); -+ fprintf(stderr, "Specify path to file '%s' with -I switch\n", srcfile->toChars()); - fatal(); - } - return false; -@@ -349,7 +321,7 @@ void Module::parse() - char *srcname = srcfile->name->toChars(); - //printf("Module::parse(srcname = '%s')\n", srcname); - -- unsigned char *buf = srcfile->buffer; -+ utf8_t *buf = srcfile->buffer; - size_t buflen = srcfile->len; - - if (buflen >= 2) -@@ -399,7 +371,7 @@ void Module::parse() - } - dbuf.writeByte(0); // add 0 as sentinel for scanner - buflen = dbuf.offset - 1; // don't include sentinel in count -- buf = (unsigned char *) dbuf.extractData(); -+ buf = (utf8_t *) dbuf.extractData(); - } - else - { // UTF-16LE (X86) -@@ -452,7 +424,7 @@ void Module::parse() - } - dbuf.writeByte(0); // add 0 as sentinel for scanner - buflen = dbuf.offset - 1; // don't include sentinel in count -- buf = (unsigned char *) dbuf.extractData(); -+ buf = (utf8_t *) dbuf.extractData(); - } - } - else if (buf[0] == 0xFE && buf[1] == 0xFF) -@@ -528,30 +500,43 @@ void Module::parse() - p.nextToken(); - members = p.parseModule(); - -- ::free(srcfile->buffer); -+ if (srcfile->ref == 0) -+ ::free(srcfile->buffer); - srcfile->buffer = NULL; - srcfile->len = 0; - - md = p.md; -- numlines = p.loc.linnum; -+ numlines = p.scanloc.linnum; - -+ /* The symbol table into which the module is to be inserted. -+ */ - DsymbolTable *dst; - - if (md) -- { this->ident = md->id; -+ { -+ /* A ModuleDeclaration, md, was provided. -+ * The ModuleDeclaration sets the packages this module appears in, and -+ * the name of this module. -+ */ -+ this->ident = md->id; - this->safe = md->safe; - Package *ppack = NULL; - dst = Package::resolve(md->packages, &this->parent, &ppack); -- if (ppack && ppack->isModule()) -+ assert(dst); -+ -+ Module *m = ppack ? ppack->isModule() : NULL; -+ if (m && strcmp(m->srcfile->name->name(), "package.d") != 0) - { -- error(loc, "package name '%s' in file %s conflicts with usage as a module name in file %s", -- ppack->toChars(), srcname, ppack->isModule()->srcfile->toChars()); -- dst = modules; -+ ::error(md->loc, "package name '%s' conflicts with usage as a module name in file %s", -+ ppack->toPrettyChars(), m->srcfile->toChars()); - } - } - else - { -- dst = modules; -+ /* The name of the module is set to the source file name. -+ * There are no packages. -+ */ -+ dst = modules; // and so this module goes into global module symbol table - - /* Check to see if module name is a valid identifier - */ -@@ -559,25 +544,71 @@ void Module::parse() - error("has non-identifier characters in filename, use module declaration instead"); - } - -- // Update global list of modules -- if (!dst->insert(this)) -+ // Insert module into the symbol table -+ Dsymbol *s = this; -+ bool isPackageMod = strcmp(srcfile->name->name(), "package.d") == 0; -+ if (isPackageMod) -+ { -+ /* If the source tree is as follows: -+ * pkg/ -+ * +- package.d -+ * +- common.d -+ * the 'pkg' will be incorporated to the internal package tree in two ways: -+ * import pkg; -+ * and: -+ * import pkg.common; -+ * -+ * If both are used in one compilation, 'pkg' as a module (== pkg/package.d) -+ * and a package name 'pkg' will conflict each other. -+ * -+ * To avoid the conflict: -+ * 1. If preceding package name insertion had occurred by Package::resolve, -+ * later package.d loading will change Package::isPkgMod to PKGmodule and set Package::mod. -+ * 2. Otherwise, 'package.d' wrapped by 'Package' is inserted to the internal tree in here. -+ */ -+ Package *p = new Package(ident); -+ p->parent = this->parent; -+ p->isPkgMod = PKGmodule; -+ p->mod = this; -+ p->symtab = new DsymbolTable(); -+ s = p; -+ } -+ if (!dst->insert(s)) - { -+ /* It conflicts with a name that is already in the symbol table. -+ * Figure out what went wrong, and issue error message. -+ */ - Dsymbol *prev = dst->lookup(ident); - assert(prev); -- Module *mprev = prev->isModule(); -- if (mprev) -- error(loc, "from file %s conflicts with another module %s from file %s", -- srcname, mprev->toChars(), mprev->srcfile->toChars()); -- else -+ if (Module *mprev = prev->isModule()) - { -- Package *pkg = prev->isPackage(); -- assert(pkg); -- error(pkg->loc, "from file %s conflicts with package name %s", -- srcname, pkg->toChars()); -+ if (strcmp(srcname, mprev->srcfile->toChars()) == 0) -+ error(loc, "from file %s must be imported as module '%s'", -+ srcname, toPrettyChars()); -+ else -+ error(loc, "from file %s conflicts with another module %s from file %s", -+ srcname, mprev->toChars(), mprev->srcfile->toChars()); - } -+ else if (Package *pkg = prev->isPackage()) -+ { -+ if (pkg->isPkgMod == PKGunknown && isPackageMod) -+ { -+ /* If the previous inserted Package is not yet determined as package.d, -+ * link it to the actual module. -+ */ -+ pkg->isPkgMod = PKGmodule; -+ pkg->mod = this; -+ } -+ else -+ error(pkg->loc, "from file %s conflicts with package name %s", -+ srcname, pkg->toChars()); -+ } -+ else -+ assert(global.errors); - } - else - { -+ // Add to global array of all modules - amodules.push(this); - } - } -@@ -608,7 +639,7 @@ void Module::importAll(Scope *prevsc) - // would fail inside object.d. - if (members->dim == 0 || ((*members)[0])->ident != Id::object) - { -- Import *im = new Import(0, NULL, Id::object, NULL, 0); -+ Import *im = new Import(Loc(), NULL, Id::object, NULL, 0); - members->shift(im); - } - -@@ -647,18 +678,18 @@ void Module::importAll(Scope *prevsc) - - void Module::semantic() - { -- if (semanticstarted) -+ if (semanticRun != PASSinit) - return; - - //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); -- semanticstarted = 1; -+ semanticRun = PASSsemantic; - - // Note that modules get their own scope, from scratch. - // This is so regardless of where in the syntax a module - // gets imported, it is unaffected by context. - Scope *sc = scope; // see if already got one from importAll() - if (!sc) -- { printf("test2\n"); -+ { - Scope::createGlobal(this); // create root scope - } - -@@ -690,14 +721,6 @@ void Module::semantic() - } - #endif - -- // Do semantic() on members that don't depend on others -- for (size_t i = 0; i < members->dim; i++) -- { Dsymbol *s = (*members)[i]; -- -- //printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars()); -- s->semantic0(sc); -- } -- - // Pass 1 semantic routines: do public side of the definition - for (size_t i = 0; i < members->dim; i++) - { Dsymbol *s = (*members)[i]; -@@ -711,7 +734,7 @@ void Module::semantic() - { sc = sc->pop(); - sc->pop(); // 2 pops because Scope::createGlobal() created 2 - } -- semanticRun = semanticstarted; -+ semanticRun = PASSsemanticdone; - //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); - } - -@@ -728,12 +751,9 @@ void Module::semantic2() - return; - } - //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent); -- if (semanticRun == 0) // semantic() not completed yet - could be recursive call -- return; -- if (semanticstarted >= 2) -+ if (semanticRun != PASSsemanticdone) // semantic() not completed yet - could be recursive call - return; -- assert(semanticstarted == 1); -- semanticstarted = 2; -+ semanticRun = PASSsemantic2; - - // Note that modules get their own scope, from scratch. - // This is so regardless of where in the syntax a module -@@ -751,17 +771,16 @@ void Module::semantic2() - - sc = sc->pop(); - sc->pop(); -- semanticRun = semanticstarted; -+ semanticRun = PASSsemantic2done; - //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent); - } - - void Module::semantic3() - { - //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent); -- if (semanticstarted >= 3) -+ if (semanticRun != PASSsemantic2done) - return; -- assert(semanticstarted == 2); -- semanticstarted = 3; -+ semanticRun = PASSsemantic3; - - // Note that modules get their own scope, from scratch. - // This is so regardless of where in the syntax a module -@@ -780,15 +799,14 @@ void Module::semantic3() - - sc = sc->pop(); - sc->pop(); -- semanticRun = semanticstarted; -+ semanticRun = PASSsemantic3done; - } - - void Module::inlineScan() - { -- if (semanticstarted >= 4) -+ if (semanticRun != PASSsemantic3done) - return; -- assert(semanticstarted == 3); -- semanticstarted = 4; -+ semanticRun = PASSinline; - - // Note that modules get their own scope, from scratch. - // This is so regardless of where in the syntax a module -@@ -798,11 +816,11 @@ void Module::inlineScan() - for (size_t i = 0; i < members->dim; i++) - { Dsymbol *s = (*members)[i]; - //if (global.params.verbose) -- //printf("inline scan symbol %s\n", s->toChars()); -+ //fprintf(global.stdmsg, "inline scan symbol %s\n", s->toChars()); - - s->inlineScan(); - } -- semanticRun = semanticstarted; -+ semanticRun = PASSinlinedone; - } - - /**************************************************** -@@ -828,7 +846,7 @@ void Module::gensymfile() - symfile->setbuffer(buf.data, buf.offset); - buf.data = NULL; - -- symfile->writev(); -+ writeFile(loc, symfile); - } - - /********************************** -@@ -853,38 +871,15 @@ Dsymbol *Module::search(Loc loc, Identif - Dsymbol *s; - if (insearch) - s = NULL; -- else if (searchCacheIdent == ident && searchCacheFlags == flags) -- { -- s = searchCacheSymbol; -- //printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", toChars(), ident->toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol->toChars() : "null"); -- } - else - { - insearch = 1; - s = ScopeDsymbol::search(loc, ident, flags); - insearch = 0; -- -- searchCacheIdent = ident; -- searchCacheSymbol = s; -- searchCacheFlags = flags; - } - return s; - } - --Dsymbol *Module::symtabInsert(Dsymbol *s) --{ -- searchCacheIdent = 0; // symbol is inserted, so invalidate cache -- return Package::symtabInsert(s); --} -- --void Module::clearCache() --{ -- for (size_t i = 0; i < amodules.dim; i++) -- { Module *m = amodules[i]; -- m->searchCacheIdent = NULL; -- } --} -- - /******************************************* - * Can't run semantic on s now, try again later. - */ -@@ -959,6 +954,33 @@ void Module::runDeferredSemantic() - //printf("-Module::runDeferredSemantic(), len = %d\n", deferred.dim); - } - -+void Module::addDeferredSemantic3(Dsymbol *s) -+{ -+ // Don't add it if it is already there -+ for (size_t i = 0; i < deferred3.dim; i++) -+ { -+ Dsymbol *sd = deferred3[i]; -+ if (sd == s) -+ return; -+ } -+ deferred3.push(s); -+} -+ -+void Module::runDeferredSemantic3() -+{ -+ Dsymbols *a = &Module::deferred3; -+ for (size_t i = 0; i < a->dim; i++) -+ { -+ Dsymbol *s = (*a)[i]; -+ //printf("[%d] %s semantic3a\n", i, s->toPrettyChars()); -+ -+ s->semantic3(NULL); -+ -+ if (global.errors) -+ break; -+ } -+} -+ - /************************************ - * Recursively look at every module this module imports, - * return TRUE if it imports m. -@@ -1018,8 +1040,9 @@ int Module::selfImports() - - /* =========================== ModuleDeclaration ===================== */ - --ModuleDeclaration::ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe) -+ModuleDeclaration::ModuleDeclaration(Loc loc, Identifiers *packages, Identifier *id, bool safe) - { -+ this->loc = loc; - this->packages = packages; - this->id = id; - this->safe = safe; -@@ -1048,6 +1071,8 @@ char *ModuleDeclaration::toChars() - Package::Package(Identifier *ident) - : ScopeDsymbol(ident) - { -+ this->isPkgMod = PKGunknown; -+ this->mod = NULL; - } - - -@@ -1056,6 +1081,15 @@ const char *Package::kind() - return "package"; - } - -+/**************************************************** -+ * Input: -+ * packages[] the pkg1.pkg2 of pkg1.pkg2.mod -+ * Returns: -+ * the symbol table that mod should be inserted into -+ * Output: -+ * *pparent the rightmost package, i.e. pkg2, or NULL if no packages -+ * *ppkg the leftmost package, i.e. pkg1, or NULL if no packages -+ */ - - DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg) - { -@@ -1069,40 +1103,135 @@ DsymbolTable *Package::resolve(Identifie - if (packages) - { - for (size_t i = 0; i < packages->dim; i++) -- { Identifier *pid = (*packages)[i]; -- Dsymbol *p; -- -- p = dst->lookup(pid); -+ { -+ Identifier *pid = (*packages)[i]; -+ Package *pkg; -+ Dsymbol *p = dst->lookup(pid); - if (!p) - { -- p = new Package(pid); -- dst->insert(p); -- p->parent = parent; -- ((ScopeDsymbol *)p)->symtab = new DsymbolTable(); -+ pkg = new Package(pid); -+ dst->insert(pkg); -+ pkg->parent = parent; -+ pkg->symtab = new DsymbolTable(); - } - else - { -- assert(p->isPackage()); -+ pkg = p->isPackage(); -+ assert(pkg); - // It might already be a module, not a package, but that needs - // to be checked at a higher level, where a nice error message - // can be generated. - // dot net needs modules and packages with same name -+ -+ // But we still need a symbol table for it -+ if (!pkg->symtab) -+ pkg->symtab = new DsymbolTable(); - } -- parent = p; -- dst = ((Package *)p)->symtab; -+ parent = pkg; -+ dst = pkg->symtab; - if (ppkg && !*ppkg) -- *ppkg = (Package *)p; -- if (p->isModule()) -- { // Return the module so that a nice error message can be generated -+ *ppkg = pkg; -+ if (pkg->isModule()) -+ { -+ // Return the module so that a nice error message can be generated - if (ppkg) - *ppkg = (Package *)p; - break; - } - } -- if (pparent) -+ } -+ if (pparent) -+ *pparent = parent; -+ return dst; -+} -+ -+Dsymbol *Package::search(Loc loc, Identifier *ident, int flags) -+{ -+ if (!isModule() && mod) -+ { -+ // Prefer full package name. -+ Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; -+ if (s) -+ return s; -+ //printf("[%s] through pkdmod: %s\n", loc.toChars(), toChars()); -+ return mod->search(loc, ident, flags); -+ } -+ -+ return ScopeDsymbol::search(loc, ident, flags); -+} -+ -+/* =========================== ===================== */ -+ -+/******************************************** -+ * Look for the source file if it's different from filename. -+ * Look for .di, .d, directory, and along global.path. -+ * Does not open the file. -+ * Input: -+ * filename as supplied by the user -+ * global.path -+ * Returns: -+ * NULL if it's not different from filename. -+ */ -+ -+const char *lookForSourceFile(const char *filename) -+{ -+ -+ /* Search along global.path for .di file, then .d file. -+ */ -+ -+ const char *sdi = FileName::forceExt(filename, global.hdr_ext); -+ if (FileName::exists(sdi) == 1) -+ return sdi; -+ -+ const char *sd = FileName::forceExt(filename, global.mars_ext); -+ if (FileName::exists(sd) == 1) -+ return sd; -+ -+ if (FileName::exists(filename) == 2) -+ { -+ /* The filename exists and it's a directory. -+ * Therefore, the result should be: filename/package.d -+ * iff filename/package.d is a file -+ */ -+ const char *n = FileName::combine(filename, "package.d"); -+ if (FileName::exists(n) == 1) -+ return n; -+ FileName::free(n); -+ } -+ -+ if (FileName::absolute(filename)) -+ return NULL; -+ -+ if (!global.path) -+ return NULL; -+ -+ for (size_t i = 0; i < global.path->dim; i++) -+ { -+ const char *p = (*global.path)[i]; -+ -+ const char *n = FileName::combine(p, sdi); -+ if (FileName::exists(n) == 1) -+ return n; -+ FileName::free(n); -+ -+ n = FileName::combine(p, sd); -+ if (FileName::exists(n) == 1) -+ return n; -+ FileName::free(n); -+ -+ const char *b = FileName::removeExt(filename); -+ n = FileName::combine(p, b); -+ FileName::free(b); -+ if (FileName::exists(n) == 2) - { -- *pparent = parent; -+ const char *n2 = FileName::combine(n, "package.d"); -+ if (FileName::exists(n2) == 1) -+ return n2; -+ FileName::free(n2); - } -+ FileName::free(n); - } -- return dst; -+ return NULL; - } -+ -+ ---- a/src/gcc/d/dfrontend/module.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/module.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -18,12 +18,11 @@ - #include "root.h" - #include "dsymbol.h" - --struct ModuleInfoDeclaration; --struct ClassDeclaration; -+class ClassDeclaration; - struct ModuleDeclaration; - struct Macro; - struct Escape; --struct VarDeclaration; -+class VarDeclaration; - class Library; - - // Back end -@@ -33,8 +32,19 @@ typedef union tree_node elem; - struct elem; - #endif - --struct Package : ScopeDsymbol -+enum PKG - { -+ PKGunknown, // not yet determined whether it's a package.d or not -+ PKGmodule, // already determined that's an actual package.d -+ PKGpackage, // already determined that's an actual package -+}; -+ -+class Package : public ScopeDsymbol -+{ -+public: -+ PKG isPkgMod; -+ Module *mod; // != NULL if isPkgMod == PKGmodule -+ - Package(Identifier *ident); - const char *kind(); - -@@ -42,19 +52,23 @@ struct Package : ScopeDsymbol - - Package *isPackage() { return this; } - -- virtual void semantic(Scope *sc) { (void)sc; } -+ virtual void semantic(Scope *) { } -+ Dsymbol *search(Loc loc, Identifier *ident, int flags); - }; - --struct Module : Package -+class Module : public Package - { -+public: - static Module *rootModule; - static DsymbolTable *modules; // symbol table of all modules - static Modules amodules; // array of all modules - static Dsymbols deferred; // deferred Dsymbol's needing semantic() run on them -+ static Dsymbols deferred3; // deferred Dsymbol's needing semantic3() run on them - static unsigned dprogress; // progress resolving the deferred list - static void init(); - -- static ClassDeclaration *moduleinfo; -+ static AggregateDeclaration *moduleinfo; -+ - - const char *arg; // original argument name - ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration -@@ -72,15 +86,7 @@ struct Module : Package - int selfImports(); // returns !=0 if module imports itself - - int insearch; -- Identifier *searchCacheIdent; -- Dsymbol *searchCacheSymbol; // cached value of search -- int searchCacheFlags; // cached flags -- -- int semanticstarted; // has semantic() been started? -- int semanticRun; // has semantic() been done? -- int root; // != 0 if this is a 'root' module, -- // i.e. a module that will be taken all the -- // way to an object file -+ - Module *importedFrom; // module from command line we're imported from, - // i.e. a module that will be taken all the - // way to an object file -@@ -89,8 +95,6 @@ struct Module : Package - - Modules aimports; // all imported modules - -- ModuleInfoDeclaration *vmoduleinfo; -- - unsigned debuglevel; // debug level - Strings *debugids; // debug identifiers - Strings *debugidsNot; // forward referenced debug identifiers -@@ -101,7 +105,7 @@ struct Module : Package - - Macro *macrotable; // document comment macros - Escape *escapetable; // document comment escapes -- bool safe; // TRUE if module is marked as 'safe' -+ bool safe; // true if module is marked as 'safe' - - size_t nameoffset; // offset of module name from start of ModuleInfo - size_t namelen; // length of module name in characters -@@ -130,13 +134,17 @@ struct Module : Package - void gendocfile(); - int needModuleInfo(); - Dsymbol *search(Loc loc, Identifier *ident, int flags); -- Dsymbol *symtabInsert(Dsymbol *s); - void deleteObjFile(); -- void addDeferredSemantic(Dsymbol *s); -+ static void addDeferredSemantic(Dsymbol *s); - static void runDeferredSemantic(); -- static void clearCache(); -+ static void addDeferredSemantic3(Dsymbol *s); -+ static void runDeferredSemantic3(); - int imports(Module *m); - -+ bool isRoot() { return this->importedFrom == this; } -+ // true if the module source file is directly -+ // listed in command line. -+ - // Back end - - int doppelganger; // sub-module -@@ -162,7 +170,6 @@ struct Module : Package - Symbol *toModuleArray(); // get module array bounds function - - -- static Symbol *gencritsec(); - elem *toEfilename(); - - Symbol *toSymbol(); -@@ -174,11 +181,12 @@ struct Module : Package - - struct ModuleDeclaration - { -+ Loc loc; - Identifier *id; - Identifiers *packages; // array of Identifier's representing packages - bool safe; - -- ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe); -+ ModuleDeclaration(Loc loc, Identifiers *packages, Identifier *id, bool safe); - - char *toChars(); - }; ---- a/src/gcc/d/dfrontend/mtype.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/mtype.c 2014-04-01 16:32:51.000000000 +0100 -@@ -41,19 +41,19 @@ - #include "template.h" - #include "id.h" - #include "enum.h" -+#include "module.h" - #include "import.h" - #include "aggregate.h" - #include "hdrgen.h" - - FuncDeclaration *hasThis(Scope *sc); --void ObjectNotFound(Identifier *id); -- -+void sizeToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e); - - #define LOGDOTEXP 0 // log ::dotExp() - #define LOGDEFAULTINIT 0 // log ::defaultInit() - --// Allow implicit conversion of T[] to T* --#define IMPLICIT_ARRAY_TO_PTR global.params.useDeprecated -+// Allow implicit conversion of T[] to T* --> Removed in 2.063 -+#define IMPLICIT_ARRAY_TO_PTR 0 - - int Tsize_t = Tuns32; - int Tptrdiff_t = Tint32; -@@ -62,7 +62,7 @@ int CLASSINFO_SIZE_64 = (0x98); - - /***************************** Type *****************************/ - --ClassDeclaration *Type::typeinfo; -+ClassDeclaration *Type::dtypeinfo; - ClassDeclaration *Type::typeinfoclass; - ClassDeclaration *Type::typeinfointerface; - ClassDeclaration *Type::typeinfostruct; -@@ -84,6 +84,44 @@ ClassDeclaration *Type::typeinfowild; - TemplateDeclaration *Type::associativearray; - TemplateDeclaration *Type::rtinfo; - -+Type *Type::tvoid; -+Type *Type::tint8; -+Type *Type::tuns8; -+Type *Type::tint16; -+Type *Type::tuns16; -+Type *Type::tint32; -+Type *Type::tuns32; -+Type *Type::tint64; -+Type *Type::tuns64; -+Type *Type::tint128; -+Type *Type::tuns128; -+Type *Type::tfloat32; -+Type *Type::tfloat64; -+Type *Type::tfloat80; -+ -+Type *Type::timaginary32; -+Type *Type::timaginary64; -+Type *Type::timaginary80; -+ -+Type *Type::tcomplex32; -+Type *Type::tcomplex64; -+Type *Type::tcomplex80; -+ -+Type *Type::tbool; -+Type *Type::tchar; -+Type *Type::twchar; -+Type *Type::tdchar; -+ -+Type *Type::tshiftcnt; -+Type *Type::tboolean; -+Type *Type::terror; -+Type *Type::tnull; -+ -+Type *Type::tsize_t; -+Type *Type::tptrdiff_t; -+Type *Type::thash_t; -+Type *Type::tindex; -+ - Type *Type::tvoidptr; - Type *Type::tstring; - Type *Type::tvalist; -@@ -119,28 +157,34 @@ const char *Type::kind() - return NULL; - } - -+Type *Type::copy() -+{ -+ Type *t = (Type *)mem.malloc(sizeTy[ty]); -+ memcpy((void*)t, (void*)this, sizeTy[ty]); -+ return t; -+} -+ - Type *Type::syntaxCopy() - { - print(); -- fprintf(stdmsg, "ty = %d\n", ty); -+ fprintf(stderr, "ty = %d\n", ty); - assert(0); - return this; - } - --int Type::equals(Object *o) --{ Type *t; -- -- t = (Type *)o; -+bool Type::equals(RootObject *o) -+{ -+ Type *t = (Type *)o; - //printf("Type::equals(%s, %s)\n", toChars(), t->toChars()); - if (this == o || - ((t && deco == t->deco) && // deco strings are unique - deco != NULL)) // and semantic() has been run - { - //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco); -- return 1; -+ return true; - } - //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco); -- return 0; -+ return false; - } - - char Type::needThisPrefix() -@@ -150,7 +194,7 @@ char Type::needThisPrefix() - - void Type::init() - { -- stringtable.init(1543); -+ stringtable._init(1543); - Lexer::initKeywords(); - - for (size_t i = 0; i < TMAX; i++) -@@ -229,7 +273,7 @@ void Type::init() - - for (size_t i = 0; i < TMAX; i++) - { if (!mangleChar[i]) -- fprintf(stdmsg, "ty = %llu\n", (ulonglong)i); -+ fprintf(stderr, "ty = %llu\n", (ulonglong)i); - assert(mangleChar[i]); - } - -@@ -250,11 +294,43 @@ void Type::init() - } - basic[Terror] = new TypeError(); - -+ tvoid = basic[Tvoid]; -+ tint8 = basic[Tint8]; -+ tuns8 = basic[Tuns8]; -+ tint16 = basic[Tint16]; -+ tuns16 = basic[Tuns16]; -+ tint32 = basic[Tint32]; -+ tuns32 = basic[Tuns32]; -+ tint64 = basic[Tint64]; -+ tuns64 = basic[Tuns64]; -+ tint128 = basic[Tint128]; -+ tuns128 = basic[Tuns128]; -+ tfloat32 = basic[Tfloat32]; -+ tfloat64 = basic[Tfloat64]; -+ tfloat80 = basic[Tfloat80]; -+ -+ timaginary32 = basic[Timaginary32]; -+ timaginary64 = basic[Timaginary64]; -+ timaginary80 = basic[Timaginary80]; -+ -+ tcomplex32 = basic[Tcomplex32]; -+ tcomplex64 = basic[Tcomplex64]; -+ tcomplex80 = basic[Tcomplex80]; -+ -+ tbool = basic[Tbool]; -+ tchar = basic[Tchar]; -+ twchar = basic[Twchar]; -+ tdchar = basic[Tdchar]; -+ -+ tshiftcnt = tint32; -+ tboolean = tbool; -+ terror = basic[Terror]; -+ tnull = basic[Tnull]; - tnull = new TypeNull(); - tnull->deco = tnull->merge()->deco; - - tvoidptr = tvoid->pointerTo(); -- tstring = tchar->invariantOf()->arrayOf(); -+ tstring = tchar->immutableOf()->arrayOf(); - tvalist = tvoid->pointerTo(); - - if (global.params.isLP64) -@@ -267,22 +343,27 @@ void Type::init() - Tsize_t = Tuns32; - Tptrdiff_t = Tint32; - } -+ -+ tsize_t = basic[Tsize_t]; -+ tptrdiff_t = basic[Tptrdiff_t]; -+ thash_t = tsize_t; -+ tindex = tsize_t; - } - - d_uns64 Type::size() - { -- return size(0); -+ return size(Loc()); - } - - d_uns64 Type::size(Loc loc) - { - error(loc, "no size for type %s", toChars()); -- return 1; -+ return SIZE_INVALID; - } - - unsigned Type::alignsize() - { -- return size(0); -+ return size(Loc()); - } - - Type *Type::semantic(Loc loc, Scope *sc) -@@ -301,7 +382,7 @@ Type *Type::trySemantic(Loc loc, Scope * - //printf("+trySemantic(%s) %d\n", toChars(), global.errors); - unsigned errors = global.startGagging(); - Type *t = semantic(loc, sc); -- if (global.endGagging(errors)) // if any errors happened -+ if (global.endGagging(errors) || t->ty == Terror) // if any errors happened - { - t = NULL; - } -@@ -310,6 +391,34 @@ Type *Type::trySemantic(Loc loc, Scope * - } - - /******************************** -+ * Return a copy of this type with all attributes null-initialized. -+ * Useful for creating a type with different modifiers. -+ */ -+ -+Type *Type::nullAttributes() -+{ -+ unsigned sz = sizeTy[ty]; -+ Type *t = (Type *)mem.malloc(sz); -+ memcpy((void*)t, (void*)this, sz); -+ // t->mod = NULL; // leave mod unchanged -+ t->deco = NULL; -+ t->arrayof = NULL; -+ t->pto = NULL; -+ t->rto = NULL; -+ t->cto = NULL; -+ t->ito = NULL; -+ t->sto = NULL; -+ t->scto = NULL; -+ t->wto = NULL; -+ t->swto = NULL; -+ t->vtinfo = NULL; -+ t->ctype = NULL; -+ if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; -+ if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; -+ return t; -+} -+ -+/******************************** - * Convert to 'const'. - */ - -@@ -333,9 +442,9 @@ Type *Type::constOf() - * Convert to 'immutable'. - */ - --Type *Type::invariantOf() -+Type *Type::immutableOf() - { -- //printf("Type::invariantOf() %p %s\n", this, toChars()); -+ //printf("Type::immutableOf() %p %s\n", this, toChars()); - if (isImmutable()) - { - return this; -@@ -459,21 +568,9 @@ Type *Type::unSharedOf() - - if (!t) - { -- unsigned sz = sizeTy[ty]; -- t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -+ t = this->nullAttributes(); - t->mod = mod & ~MODshared; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -+ t->ctype = ctype; - t = t->merge(); - - t->fixTo(this); -@@ -826,7 +923,7 @@ void Type::check() - } - - Type *tn = nextOf(); -- if (tn && ty != Tfunction && tn->ty != Tfunction) -+ if (tn && ty != Tfunction && tn->ty != Tfunction && ty != Tenum) - { // Verify transitivity - switch (mod) - { -@@ -867,161 +964,57 @@ void Type::check() - Type *Type::makeConst() - { - //printf("Type::makeConst() %p, %s\n", this, toChars()); -- if (cto) -- return cto; -- unsigned sz = sizeTy[ty]; -- Type *t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -+ if (cto) return cto; -+ Type *t = this->nullAttributes(); - t->mod = MODconst; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -- t->ctype = NULL; - //printf("-Type::makeConst() %p, %s\n", t, toChars()); - return t; - } - - Type *Type::makeInvariant() - { -- if (ito) -- return ito; -- unsigned sz = sizeTy[ty]; -- Type *t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -+ if (ito) return ito; -+ Type *t = this->nullAttributes(); - t->mod = MODimmutable; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -- t->ctype = NULL; - return t; - } - - Type *Type::makeShared() - { -- if (sto) -- return sto; -- unsigned sz = sizeTy[ty]; -- Type *t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -+ if (sto) return sto; -+ Type *t = this->nullAttributes(); - t->mod = MODshared; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -- t->ctype = NULL; - return t; - } - - Type *Type::makeSharedConst() - { -- if (scto) -- return scto; -- unsigned sz = sizeTy[ty]; -- Type *t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -+ if (scto) return scto; -+ Type *t = this->nullAttributes(); - t->mod = MODshared | MODconst; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -- t->ctype = NULL; - return t; - } - - Type *Type::makeWild() - { -- if (wto) -- return wto; -- unsigned sz = sizeTy[ty]; -- Type *t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -+ if (wto) return wto; -+ Type *t = this->nullAttributes(); - t->mod = MODwild; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -- t->ctype = NULL; - return t; - } - - Type *Type::makeSharedWild() - { -- if (swto) -- return swto; -- unsigned sz = sizeTy[ty]; -- Type *t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -+ if (swto) return swto; -+ Type *t = this->nullAttributes(); - t->mod = MODshared | MODwild; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -- t->ctype = NULL; - return t; - } - - Type *Type::makeMutable() - { -- unsigned sz = sizeTy[ty]; -- Type *t = (Type *)mem.malloc(sz); -- memcpy(t, this, sz); -- t->mod = mod & MODshared; -- t->deco = NULL; -- t->arrayof = NULL; -- t->pto = NULL; -- t->rto = NULL; -- t->cto = NULL; -- t->ito = NULL; -- t->sto = NULL; -- t->scto = NULL; -- t->wto = NULL; -- t->swto = NULL; -- t->vtinfo = NULL; -- t->ctype = NULL; -+ Type *t = this->nullAttributes(); -+ t->mod = mod & MODshared; - return t; - } - -@@ -1074,7 +1067,7 @@ Type *Type::castMod(unsigned mod) - break; - - case MODimmutable: -- t = invariantOf(); -+ t = immutableOf(); - break; - - case MODshared: -@@ -1126,7 +1119,7 @@ Type *Type::addMod(unsigned mod) - break; - - case MODimmutable: -- t = invariantOf(); -+ t = immutableOf(); - break; - - case MODshared: -@@ -1193,10 +1186,15 @@ Type *Type::pointerTo() - if (ty == Terror) - return this; - if (!pto) -- { Type *t; -- -- t = new TypePointer(this); -- pto = t->merge(); -+ { -+ Type *t = new TypePointer(this); -+ if (ty == Tfunction) -+ { -+ t->deco = t->merge()->deco; -+ pto = t; -+ } -+ else -+ pto = t->merge(); - } - return pto; - } -@@ -1252,9 +1250,7 @@ Type *Type::aliasthisOf() - } - else if (d->isFuncDeclaration()) - { -- FuncDeclaration *fd = (FuncDeclaration *)d; -- Expression *ethis = this->defaultInit(0); -- fd = fd->overloadResolve(0, ethis, NULL, 1); -+ FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, d, NULL, this, NULL, 1); - if (fd && fd->functionSemantic()) - { - t = fd->type->nextOf(); -@@ -1274,8 +1270,7 @@ Type *Type::aliasthisOf() - TemplateDeclaration *td = ad->aliasthis->isTemplateDeclaration(); - if (td) - { assert(td->scope); -- Expression *ethis = defaultInit(0); -- FuncDeclaration *fd = td->deduceFunctionTemplate(td->scope, 0, NULL, ethis, NULL, 1); -+ FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, td, NULL, this, NULL, 1); - if (fd && fd->functionSemantic()) - { - Type *t = fd->type->nextOf(); -@@ -1290,6 +1285,27 @@ Type *Type::aliasthisOf() - return NULL; - } - -+int Type::checkAliasThisRec() -+{ -+ Type *tb = toBasetype(); -+ AliasThisRec* pflag; -+ if (tb->ty == Tstruct) -+ pflag = &((TypeStruct *)tb)->att; -+ else if (tb->ty == Tclass) -+ pflag = &((TypeClass *)tb)->att; -+ else -+ return 0; -+ -+ AliasThisRec flag = (AliasThisRec)(*pflag & ~RECtracing); -+ if (flag == RECfwdref) -+ { -+ Type *att = aliasthisOf(); -+ flag = att && att->implicitConvTo(this) ? RECyes : RECno; -+ } -+ *pflag = (AliasThisRec)(flag | (*pflag & RECtracing)); -+ return flag == RECyes; -+} -+ - Dsymbol *Type::toDsymbol(Scope *sc) - { - return NULL; -@@ -1365,57 +1381,19 @@ int MODmerge(unsigned char mod1, unsigne - return mod1; - - //printf("MODmerge(1 = %x, 2 = %x)\n", modfrom, modto); -- #define X(m, n) (((m) << 4) | (n)) -- // cases are commutative -- #define Y(m, n) X(m, n): case X(n, m) -- switch (X(mod1, mod2)) -- { --#if 0 -- case X(0, 0): -- case X(MODconst, MODconst): -- case X(MODimmutable, MODimmutable): -- case X(MODshared, MODshared): -- case X(MODshared | MODconst, MODshared | MODconst): -- case X(MODwild, MODwild): -- case X(MODshared | MODwild, MODshared | MODwild): --#endif -- -- case Y(0, MODconst): -- case Y(0, MODimmutable): -- case Y(MODconst, MODimmutable): -- case Y(MODconst, MODwild): -- case Y(0, MODwild): -- case Y(MODimmutable, MODwild): -- return MODconst; -- -- case Y(0, MODshared): -- return MODshared; -+ unsigned char result = 0; - -- case Y(0, MODshared | MODconst): -- case Y(MODconst, MODshared): -- case Y(MODconst, MODshared | MODconst): -- case Y(MODimmutable, MODshared): -- case Y(MODimmutable, MODshared | MODconst): -- case Y(MODshared, MODshared | MODconst): -- case Y(0, MODshared | MODwild): -- case Y(MODconst, MODshared | MODwild): -- case Y(MODimmutable, MODshared | MODwild): -- case Y(MODshared, MODwild): -- case Y(MODshared, MODshared | MODwild): -- case Y(MODshared | MODconst, MODwild): -- case Y(MODshared | MODconst, MODshared | MODwild): -- return MODshared | MODconst; -- -- case Y(MODwild, MODshared | MODwild): -- return MODshared | MODwild; -- -- default: -- assert(0); -- } -- #undef Y -- #undef X -- assert(0); -- return 0; -+ // If either type is shared, the result will be shared -+ if ((mod1 | mod2) & MODshared) -+ result |= MODshared; -+ // If both types are wild, the result will be wild -+ // Otherwise if either type is const or immutable or wild -+ // the result will be const -+ if (mod1 & mod2 & MODwild) -+ result |= MODwild; -+ else if ((mod1 | mod2) & (MODconst | MODimmutable | MODwild)) -+ result |= MODconst; -+ return result; - } - - /********************************* -@@ -1491,6 +1469,7 @@ void MODtoBuffer(OutBuffer *buf, unsigne - char *MODtoChars(unsigned char mod) - { - OutBuffer buf; -+ buf.reserve(16); - MODtoBuffer(&buf, mod); - buf.writebyte(0); - return buf.extractData(); -@@ -1516,12 +1495,13 @@ void Type::toDecoBuffer(OutBuffer *buf, - */ - - char *Type::toChars() --{ OutBuffer *buf; -+{ OutBuffer buf; -+ buf.reserve(16); - HdrGenState hgs; - -- buf = new OutBuffer(); -- toCBuffer(buf, NULL, &hgs); -- return buf->toChars(); -+ toCBuffer(&buf, NULL, &hgs); -+ buf.writebyte(0); -+ return buf.extractData(); - } - - void Type::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) -@@ -1587,12 +1567,92 @@ void Type::modToBuffer(OutBuffer *buf) - char *Type::modToChars() - { - OutBuffer buf; -+ buf.reserve(16); - modToBuffer(&buf); - buf.writebyte(0); - return buf.extractData(); - } - - /************************************ -+ * Strip all parameter's idenfiers and their default arguments for merging types. -+ * If some of parameter types or return type are function pointer, delegate, or -+ * the types which contains either, then strip also from them. -+ */ -+ -+Type *stripDefaultArgs(Type *t) -+{ -+ struct N -+ { -+ static Parameters *stripParams(Parameters *arguments) -+ { -+ Parameters *args = arguments; -+ if (args && args->dim > 0) -+ { -+ for (size_t i = 0; i < args->dim; i++) -+ { -+ Parameter *a = (*args)[i]; -+ Type *ta = stripDefaultArgs(a->type); -+ if (ta != a->type || a->defaultArg || a->ident) -+ { -+ if (args == arguments) -+ { -+ args = new Parameters(); -+ args->setDim(arguments->dim); -+ for (size_t j = 0; j < args->dim; j++) -+ (*args)[j] = (*arguments)[j]; -+ } -+ (*args)[i] = new Parameter(a->storageClass, ta, NULL, NULL); -+ } -+ } -+ } -+ return args; -+ } -+ }; -+ -+ if (t == NULL) -+ return t; -+ -+ if (t->ty == Tfunction) -+ { -+ TypeFunction *tf = (TypeFunction *)t; -+ Type *tret = stripDefaultArgs(tf->next); -+ Parameters *args = N::stripParams(tf->parameters); -+ if (tret == tf->next && args == tf->parameters) -+ goto Lnot; -+ tf = (TypeFunction *)tf->copy(); -+ tf->parameters = args; -+ tf->next = tret; -+ //printf("strip %s\n <- %s\n", tf->toChars(), t->toChars()); -+ t = tf; -+ } -+ else if (t->ty == Ttuple) -+ { -+ TypeTuple *tt = (TypeTuple *)t; -+ Parameters *args = N::stripParams(tt->arguments); -+ if (args == tt->arguments) -+ goto Lnot; -+ t = new TypeTuple(args); -+ } -+ else if (t->ty == Tenum) -+ { -+ // TypeEnum::nextOf() may be != NULL, but it's not necessary here. -+ goto Lnot; -+ } -+ else -+ { -+ Type *tn = t->nextOf(); -+ Type *n = stripDefaultArgs(tn); -+ if (n == tn) -+ goto Lnot; -+ t = t->copy(); -+ ((TypeNext *)t)->next = n; -+ } -+ //printf("strip %s\n", t->toChars()); -+Lnot: -+ return t; -+} -+ -+/************************************ - */ - - Type *Type::merge() -@@ -1603,7 +1663,7 @@ Type *Type::merge() - if (ty == Tinstance) return this; - if (ty == Taarray && !((TypeAArray *)this)->index->merge()->deco) - return this; -- if (nextOf() && !nextOf()->deco) -+ if (ty != Tenum && nextOf() && !nextOf()->deco) - return this; - - //printf("merge(%s)\n", toChars()); -@@ -1612,12 +1672,12 @@ Type *Type::merge() - if (!deco) - { - OutBuffer buf; -- StringValue *sv; -+ buf.reserve(32); - - //if (next) - //next = next->merge(); - toDecoBuffer(&buf); -- sv = stringtable.update((char *)buf.data, buf.offset); -+ StringValue *sv = stringtable.update((char *)buf.data, buf.offset); - if (sv->ptrvalue) - { t = (Type *) sv->ptrvalue; - #ifdef DEBUG -@@ -1629,8 +1689,8 @@ Type *Type::merge() - } - else - { -- sv->ptrvalue = this; -- deco = (char *)sv->toDchars(); -+ sv->ptrvalue = (char *)(t = stripDefaultArgs(t)); -+ deco = t->deco = (char *)sv->toDchars(); - //printf("new value, deco = '%s' %p\n", t->deco, t->deco); - } - } -@@ -1800,7 +1860,7 @@ MATCH Type::implicitConvTo(Type *to) - //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to); - //printf("from: %s\n", toChars()); - //printf("to : %s\n", to->toChars()); -- if (this == to) -+ if (this->equals(to)) - return MATCHexact; - return MATCHnomatch; - } -@@ -1853,10 +1913,17 @@ Type *Type::substWildTo(unsigned mod) - //printf("+Type::substWildTo this = %s, mod = x%x\n", toChars(), mod); - Type *t; - -- if (nextOf()) -+ if (Type *tn = nextOf()) - { -- t = nextOf()->substWildTo(mod); -- if (t == nextOf()) -+ // substitution has no effect on function pointer type. -+ if (ty == Tpointer && tn->ty == Tfunction) -+ { -+ t = this; -+ goto L1; -+ } -+ -+ t = tn->substWildTo(mod); -+ if (t == tn) - t = this; - else - { -@@ -1871,6 +1938,10 @@ Type *Type::substWildTo(unsigned mod) - t = new TypeAArray(t, ((TypeAArray *)this)->index->syntaxCopy()); - ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc; // duplicate scope - } -+ else if (ty == Tdelegate) -+ { -+ t = new TypeDelegate(t); -+ } - else - assert(0); - -@@ -1880,12 +1951,13 @@ Type *Type::substWildTo(unsigned mod) - else - t = this; - -+L1: - if (isWild()) - { - if (mod & MODconst) - t = isShared() ? t->sharedConstOf() : t->constOf(); - else if (mod & MODimmutable) -- t = t->invariantOf(); -+ t = t->immutableOf(); - else if (mod & MODwild) - t = isShared() ? t->sharedWildOf() : t->wildOf(); - else -@@ -1896,6 +1968,47 @@ Type *Type::substWildTo(unsigned mod) - return t; - } - -+Type *TypeFunction::substWildTo(unsigned) -+{ -+ if (!iswild && !(mod & MODwild)) -+ return this; -+ -+ // Substitude inout qualifier of function type to mutable or immutable -+ // would break type system. Instead substitude inout to the most weak -+ // qualifer - const. -+ unsigned m = MODconst; -+ -+ assert(next); -+ Type *tret = next->substWildTo(m); -+ Parameters *params = parameters; -+ if (mod & MODwild) -+ params = parameters->copy(); -+ for (size_t i = 0; i < params->dim; i++) -+ { -+ Parameter *p = (*params)[i]; -+ Type *t = p->type->substWildTo(m); -+ if (t == p->type) -+ continue; -+ if (params == parameters) -+ params = parameters->copy(); -+ (*params)[i] = new Parameter(p->storageClass, t, NULL, NULL); -+ } -+ if (next == tret && params == parameters) -+ return this; -+ -+ // Similar to TypeFunction::syntaxCopy; -+ TypeFunction *t = new TypeFunction(params, tret, varargs, linkage); -+ t->mod = ((mod & MODwild) ? (mod & ~MODwild) | MODconst : mod); -+ t->isnothrow = isnothrow; -+ t->purity = purity; -+ t->isproperty = isproperty; -+ t->isref = isref; -+ t->iswild = false; // done -+ t->trust = trust; -+ t->fargs = fargs; -+ return t->merge(); -+} -+ - /************************** - * Return type with the top level of it being mutable. - */ -@@ -1906,7 +2019,12 @@ Type *Type::toHeadMutable() - return mutableOf(); - } - --Expression *Type::getProperty(Loc loc, Identifier *ident) -+/*************************************** -+ * Calculate built-in properties which just the type is necessary. -+ * -+ * If flag == 1, don't report "not a property" error and just return NULL. -+ */ -+Expression *Type::getProperty(Loc loc, Identifier *ident, int flag) - { Expression *e; - - #if LOGDOTEXP -@@ -1914,7 +2032,10 @@ Expression *Type::getProperty(Loc loc, I - #endif - if (ident == Id::__sizeof) - { -- e = new IntegerExp(loc, size(loc), Type::tsize_t); -+ d_uns64 sz = size(loc); -+ if (sz == SIZE_INVALID) -+ return new ErrorExp(); -+ e = new IntegerExp(loc, sz, Type::tsize_t); - } - else if (ident == Id::__xalignof) - { -@@ -1936,16 +2057,18 @@ Expression *Type::getProperty(Loc loc, I - } - } - else if (ident == Id::mangleof) -- { const char *s; -+ { - if (!deco) -- { s = toChars(); -- error(loc, "forward reference of type %s.mangleof", s); -+ { -+ error(loc, "forward reference of type %s.mangleof", toChars()); -+ e = new ErrorExp(); - } - else -- s = deco; -- e = new StringExp(loc, (char *)s, strlen(s), 'c'); -- Scope sc; -- e = e->semantic(&sc); -+ { -+ e = new StringExp(loc, (char *)deco, strlen(deco), 'c'); -+ Scope sc; -+ e = e->semantic(&sc); -+ } - } - else if (ident == Id::stringof) - { char *s = toChars(); -@@ -1953,6 +2076,10 @@ Expression *Type::getProperty(Loc loc, I - Scope sc; - e = e->semantic(&sc); - } -+ else if (flag && this != Type::terror) -+ { -+ return NULL; -+ } - else - { - Dsymbol *s = NULL; -@@ -1972,20 +2099,28 @@ Expression *Type::getProperty(Loc loc, I - return e; - } - --Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident) -+/*************************************** -+ * Access the members of the object e. This type is same as e->type. -+ * -+ * If flag == 1, don't report "not a property" error and just return NULL. -+ */ -+Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { VarDeclaration *v = NULL; - - #if LOGDOTEXP - printf("Type::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); - #endif -- if (e->op == TOKdotvar) -+ Expression *ex = e; -+ while (ex->op == TOKcomma) -+ ex = ((CommaExp *)ex)->e2; -+ if (ex->op == TOKdotvar) - { -- DotVarExp *dv = (DotVarExp *)e; -+ DotVarExp *dv = (DotVarExp *)ex; - v = dv->var->isVarDeclaration(); - } -- else if (e->op == TOKvar) -+ else if (ex->op == TOKvar) - { -- VarExp *ve = (VarExp *)e; -+ VarExp *ve = (VarExp *)ex; - v = ve->var->isVarDeclaration(); - } - if (v) -@@ -1998,7 +2133,7 @@ Expression *Type::dotExp(Scope *sc, Expr - else if (ident == Id::offsetof) - { - Loffset: -- if (v->storage_class & STCfield) -+ if (v->isField()) - { - e = new IntegerExp(e->loc, v->offset, Type::tsize_t); - return e; -@@ -2029,10 +2164,11 @@ Expression *Type::dotExp(Scope *sc, Expr - e = new StringExp(e->loc, s, strlen(s), 'c'); - } - else -- e = getProperty(e->loc, ident); -+ e = getProperty(e->loc, ident, flag); - - Lreturn: -- e = e->semantic(sc); -+ if (!flag || e) -+ e = e->semantic(sc); - return e; - } - -@@ -2048,8 +2184,10 @@ structalign_t Type::alignment() - /*************************************** - * Figures out what to do with an undefined member reference - * for classes and structs. -+ * -+ * If flag == 1, don't report "not a property" error and just return NULL. - */ --Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident) -+Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident, int flag) - { - assert(ty == Tstruct || ty == Tclass); - AggregateDeclaration *sym = toDsymbol(sc)->isAggregateDeclaration(); -@@ -2095,10 +2233,20 @@ Expression *Type::noMember(Scope *sc, Ex - tiargs->push(se); - DotTemplateInstanceExp *dti = new DotTemplateInstanceExp(e->loc, e, Id::opDispatch, tiargs); - dti->ti->tempdecl = td; -- return dti->semantic(sc, 1); -- } - -- /* See if we should forward to the alias this. -+ /* opDispatch, which doesn't need IFTI, may occur instantiate error. -+ * It should be gagged if flag != 0. -+ * e.g. -+ * tempalte opDispatch(name) if (isValid!name) { ... } -+ */ -+ unsigned errors = flag ? global.startGagging() : 0; -+ Expression *e = dti->semanticY(sc, 0); -+ if (flag && global.endGagging(errors)) -+ e = NULL; -+ return e; -+ } -+ -+ /* See if we should forward to the alias this. - */ - if (sym->aliasthis) - { /* Rewrite e.ident as: -@@ -2106,11 +2254,11 @@ Expression *Type::noMember(Scope *sc, Ex - */ - e = resolveAliasThis(sc, e); - DotIdExp *die = new DotIdExp(e->loc, e, ident); -- return die->semantic(sc, 1); -+ return die->semanticY(sc, flag); - } - } - -- return Type::dotExp(sc, e, ident); -+ return Type::dotExp(sc, e, ident, flag); - } - - void Type::error(Loc loc, const char *format, ...) -@@ -2133,6 +2281,7 @@ Identifier *Type::getTypeInfoIdent(int i - { - // _init_10TypeInfo_%s - OutBuffer buf; -+ buf.reserve(32); - - if (internal) - { buf.writeByte(mangleChar[ty]); -@@ -2151,7 +2300,7 @@ Identifier *Type::getTypeInfoIdent(int i - char *name = namelen <= sizeof(namebuf) ? namebuf : (char *)malloc(namelen); - assert(name); - -- sprintf(name, "_D%dTypeInfo_%s6__initZ", 9 + len, buf.data); -+ sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.data); - //printf("name = %s\n", name); - assert(strlen(name) < namelen); // don't overflow the buffer - -@@ -2171,7 +2320,7 @@ TypeBasic *Type::isTypeBasic() - } - - --void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) -+void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { - //printf("Type::resolve() %s, %d\n", toChars(), ty); - Type *t = semantic(loc, sc); -@@ -2234,6 +2383,18 @@ Type *Type::nextOf() - return NULL; - } - -+/************************************* -+ * If this is a type of static array, return its base element type. -+ */ -+ -+Type *Type::baseElemOf() -+{ -+ Type *t = toBasetype(); -+ while (t->ty == Tsarray) -+ t = ((TypeSArray *)t)->next->toBasetype(); -+ return t; -+} -+ - /**************************************** - * Return the mask that an integral type will - * fit into. -@@ -2279,9 +2440,9 @@ void TypeError::toCBuffer(OutBuffer *buf - buf->writestring("_error_"); - } - --d_uns64 TypeError::size(Loc loc) { return 1; } --Expression *TypeError::getProperty(Loc loc, Identifier *ident) { return new ErrorExp(); } --Expression *TypeError::dotExp(Scope *sc, Expression *e, Identifier *ident) { return new ErrorExp(); } -+d_uns64 TypeError::size(Loc loc) { return SIZE_INVALID; } -+Expression *TypeError::getProperty(Loc loc, Identifier *ident, int flag) { return new ErrorExp(); } -+Expression *TypeError::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) { return new ErrorExp(); } - Expression *TypeError::defaultInit(Loc loc) { return new ErrorExp(); } - Expression *TypeError::defaultInitLiteral(Loc loc) { return new ErrorExp(); } - -@@ -2366,7 +2527,7 @@ Type *TypeNext::makeInvariant() - if (ty != Tfunction && next->ty != Tfunction && - //(next->deco || next->ty == Tfunction) && - !next->isImmutable()) -- { t->next = next->invariantOf(); -+ { t->next = next->immutableOf(); - } - if (ty == Taarray) - { -@@ -2543,11 +2704,6 @@ void TypeNext::transitive() - - /* ============================= TypeBasic =========================== */ - --TypeBasic::TypeBasic(TY ty) -- : Type(ty) --{ const char *d; -- unsigned flags; -- - #define TFLAGSintegral 1 - #define TFLAGSfloating 2 - #define TFLAGSunsigned 4 -@@ -2556,6 +2712,11 @@ TypeBasic::TypeBasic(TY ty) - #define TFLAGScomplex 0x20 - #define TFLAGSvector 0x40 // valid for a SIMD vector type - -+TypeBasic::TypeBasic(TY ty) -+ : Type(ty) -+{ const char *d; -+ unsigned flags; -+ - flags = 0; - switch (ty) - { -@@ -2745,15 +2906,11 @@ unsigned TypeBasic::alignsize() - } - - --Expression *TypeBasic::getProperty(Loc loc, Identifier *ident) -+Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag) - { - Expression *e; - d_int64 ivalue; --#ifdef IN_GCC -- real_t fvalue; --#else - d_float80 fvalue; --#endif - - //printf("TypeBasic::getProperty('%s')\n", ident->toChars()); - if (ident == Id::max) -@@ -2781,7 +2938,7 @@ Expression *TypeBasic::getProperty(Loc l - case Tfloat64: fvalue = DBL_MAX; goto Lfvalue; - case Tcomplex80: - case Timaginary80: -- case Tfloat80: fvalue = LDBL_MAX; goto Lfvalue; -+ case Tfloat80: fvalue = Port::ldbl_max; goto Lfvalue; - } - } - else if (ident == Id::min) -@@ -2844,7 +3001,7 @@ Expression *TypeBasic::getProperty(Loc l - case Tfloat64: - case Tfloat80: - { -- fvalue = Port::nan; -+ fvalue = Port::ldbl_nan; - goto Lfvalue; - } - } -@@ -2862,7 +3019,7 @@ Expression *TypeBasic::getProperty(Loc l - case Tfloat32: - case Tfloat64: - case Tfloat80: -- fvalue = Port::infinity; -+ fvalue = Port::ldbl_infinity; - goto Lfvalue; - } - } -@@ -2972,7 +3129,7 @@ Expression *TypeBasic::getProperty(Loc l - } - } - -- return Type::getProperty(loc, ident); -+ return Type::getProperty(loc, ident, flag); - - Livalue: - e = new IntegerExp(loc, ivalue, this); -@@ -3005,7 +3162,7 @@ Lint: - return e; - } - --Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeBasic::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); -@@ -3036,7 +3193,7 @@ Expression *TypeBasic::dotExp(Scope *sc, - break; - - default: -- e = Type::getProperty(e->loc, ident); -+ e = Type::getProperty(e->loc, ident, flag); - break; - } - } -@@ -3068,47 +3225,26 @@ Expression *TypeBasic::dotExp(Scope *sc, - break; - - default: -- e = Type::getProperty(e->loc, ident); -+ e = Type::getProperty(e->loc, ident, flag); - break; - } - } - else - { -- return Type::dotExp(sc, e, ident); -+ return Type::dotExp(sc, e, ident, flag); - } -- e = e->semantic(sc); -+ if (!flag || e) -+ e = e->semantic(sc); - return e; - } - - Expression *TypeBasic::defaultInit(Loc loc) --{ dinteger_t value = 0; -- --#if SNAN_DEFAULT_INIT --#ifndef IN_GCC -- /* -- * Use a payload which is different from the machine NaN, -- * so that uninitialised variables can be -- * detected even if exceptions are disabled. -- */ -- union -- { unsigned short us[8]; -- longdouble ld; -- } snan = {{ 0, 0, 0, 0xA000, 0x7FFF }}; -- /* -- * Although long doubles are 10 bytes long, some -- * C ABIs pad them out to 12 or even 16 bytes, so -- * leave enough space in the snan array. -- */ -- assert(Target::realsize <= sizeof(snan)); -- d_float80 fvalue = snan.ld; --#else -- real_t fvalue = Port::snan; --#endif --#endif -- -+{ - #if LOGDEFAULTINIT - printf("TypeBasic::defaultInit() '%s'\n", toChars()); - #endif -+ dinteger_t value = 0; -+ - switch (ty) - { - case Tchar: -@@ -3127,7 +3263,7 @@ Expression *TypeBasic::defaultInit(Loc l - case Tfloat64: - case Tfloat80: - #if SNAN_DEFAULT_INIT -- return new RealExp(loc, fvalue, this); -+ return new RealExp(loc, Port::snan, this); - #else - return getProperty(loc, Id::nan); - #endif -@@ -3138,8 +3274,8 @@ Expression *TypeBasic::defaultInit(Loc l - #if SNAN_DEFAULT_INIT - { // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN). - complex_t cvalue; -- ((real_t *)&cvalue)[0] = fvalue; -- ((real_t *)&cvalue)[1] = fvalue; -+ ((real_t *)&cvalue)[0] = Port::snan; -+ ((real_t *)&cvalue)[1] = Port::snan; - return new ComplexExp(loc, cvalue, this); - } - #else -@@ -3170,8 +3306,9 @@ int TypeBasic::isZeroInit(Loc loc) - case Tcomplex64: - case Tcomplex80: - return 0; // no -+ default: -+ return 1; // yes - } -- return 1; // yes - } - - int TypeBasic::isintegral() -@@ -3255,8 +3392,8 @@ MATCH TypeBasic::implicitConvTo(Type *to - #if DMDV2 - // If converting from integral to integral - if (tob->flags & TFLAGSintegral) -- { d_uns64 sz = size(0); -- d_uns64 tosz = tob->size(0); -+ { d_uns64 sz = size(Loc()); -+ d_uns64 tosz = tob->size(Loc()); - - /* Can't convert to smaller size - */ -@@ -3320,7 +3457,7 @@ const char *TypeVector::kind() - - Type *TypeVector::syntaxCopy() - { -- return new TypeVector(0, basetype->syntaxCopy()); -+ return new TypeVector(Loc(), basetype->syntaxCopy()); - } - - Type *TypeVector::semantic(Loc loc, Scope *sc) -@@ -3335,16 +3472,6 @@ Type *TypeVector::semantic(Loc loc, Scop - return terror; - } - TypeSArray *t = (TypeSArray *)basetype; -- -- if (sc && sc->parameterSpecialization && t->dim->op == TOKvar && -- ((VarExp *)t->dim)->var->storage_class & STCtemplateparameter) -- { -- /* It could be a template parameter N which has no value yet: -- * template Foo(T : __vector(T[N]), size_t N); -- */ -- return this; -- } -- - d_uns64 sz = t->size(loc); - if (sz != 8 && sz != 16 && sz != 32) - { error(loc, "base type of __vector must be a 8, 16 or 32 byte static array, not %s", t->toChars()); -@@ -3409,12 +3536,12 @@ unsigned TypeVector::alignsize() - return (unsigned)basetype->size(); - } - --Expression *TypeVector::getProperty(Loc loc, Identifier *ident) -+Expression *TypeVector::getProperty(Loc loc, Identifier *ident, int flag) - { -- return basetype->getProperty(loc, ident); -+ return basetype->getProperty(loc, ident, flag); - } - --Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeVector::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); -@@ -3424,7 +3551,7 @@ Expression *TypeVector::dotExp(Scope *sc - e = e->castTo(sc, basetype); - return e; - } -- return basetype->dotExp(sc, e->castTo(sc, basetype), ident); -+ return basetype->dotExp(sc, e->castTo(sc, basetype), ident, flag); - } - - Expression *TypeVector::defaultInit(Loc loc) -@@ -3432,6 +3559,11 @@ Expression *TypeVector::defaultInit(Loc - return basetype->defaultInit(loc); - } - -+Expression *TypeVector::defaultInitLiteral(Loc loc) -+{ -+ return basetype->defaultInitLiteral(loc); -+} -+ - int TypeVector::isZeroInit(Loc loc) - { - return basetype->isZeroInit(loc); -@@ -3468,6 +3600,11 @@ MATCH TypeVector::implicitConvTo(Type *t - return MATCHnomatch; - } - -+Type *TypeVector::reliesOnTident(TemplateParameters *tparams) -+{ -+ return basetype->reliesOnTident(tparams); -+} -+ - /***************************** TypeArray *****************************/ - - TypeArray::TypeArray(TY ty, Type *next) -@@ -3475,7 +3612,7 @@ TypeArray::TypeArray(TY ty, Type *next) - { - } - --Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - Type *n = this->next->toBasetype(); // uncover any typedef's - -@@ -3485,38 +3622,48 @@ Expression *TypeArray::dotExp(Scope *sc, - - if (!n->isMutable()) - if (ident == Id::sort || ident == Id::reverse) -- error(e->loc, "can only %s a mutable array", ident->toChars()); -+ { error(e->loc, "can only %s a mutable array", ident->toChars()); -+ goto Lerror; -+ } - - if (ident == Id::reverse && (n->ty == Tchar || n->ty == Twchar)) - { -- Expression *ec; -- FuncDeclaration *fd; -- Expressions *arguments; -- const char *nm; -- static const char *name[2] = { "_adReverseChar", "_adReverseWchar" }; -+ static const char *reverseName[2] = { "_adReverseChar", "_adReverseWchar" }; -+ static FuncDeclaration *reverseFd[2] = { NULL, NULL }; -+ -+ int i = n->ty == Twchar; -+ if (!reverseFd[i]) { -+ Parameters *args = new Parameters; -+ Type *next = n->ty == Twchar ? Type::twchar : Type::tchar; -+ Type *arrty = next->arrayOf(); -+ args->push(new Parameter(STCin, arrty, NULL, NULL)); -+ reverseFd[i] = FuncDeclaration::genCfunc(args, arrty, reverseName[i]); -+ } - -- nm = name[n->ty == Twchar]; -- fd = FuncDeclaration::genCfunc(Type::tindex, nm); -- ec = new VarExp(0, fd); -+ Expression *ec = new VarExp(Loc(), reverseFd[i]); - e = e->castTo(sc, n->arrayOf()); // convert to dynamic array -- arguments = new Expressions(); -+ Expressions *arguments = new Expressions(); - arguments->push(e); - e = new CallExp(e->loc, ec, arguments); - e->type = next->arrayOf(); - } - else if (ident == Id::sort && (n->ty == Tchar || n->ty == Twchar)) - { -- Expression *ec; -- FuncDeclaration *fd; -- Expressions *arguments; -- const char *nm; -- static const char *name[2] = { "_adSortChar", "_adSortWchar" }; -+ static const char *sortName[2] = { "_adSortChar", "_adSortWchar" }; -+ static FuncDeclaration *sortFd[2] = { NULL, NULL }; -+ -+ int i = n->ty == Twchar; -+ if (!sortFd[i]) { -+ Parameters *args = new Parameters; -+ Type *next = n->ty == Twchar ? Type::twchar : Type::tchar; -+ Type *arrty = next->arrayOf(); -+ args->push(new Parameter(STCin, arrty, NULL, NULL)); -+ sortFd[i] = FuncDeclaration::genCfunc(args, arrty, sortName[i]); -+ } - -- nm = name[n->ty == Twchar]; -- fd = FuncDeclaration::genCfunc(Type::tindex, nm); -- ec = new VarExp(0, fd); -+ Expression *ec = new VarExp(Loc(), sortFd[i]); - e = e->castTo(sc, n->arrayOf()); // convert to dynamic array -- arguments = new Expressions(); -+ Expressions *arguments = new Expressions(); - arguments->push(e); - e = new CallExp(e->loc, ec, arguments); - e->type = next->arrayOf(); -@@ -3532,29 +3679,53 @@ Expression *TypeArray::dotExp(Scope *sc, - Expression *olde = e; - assert(size); - dup = (ident == Id::dup || ident == Id::idup); -- fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse); -- ec = new VarExp(0, fd); -+ -+ if (dup) { -+ static FuncDeclaration *adDup_fd = NULL; -+ if (!adDup_fd) { -+ Parameters* args = new Parameters; -+ args->push(new Parameter(STCin, Type::dtypeinfo->type, NULL, NULL)); -+ args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); -+ adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup); -+ } -+ fd = adDup_fd; -+ } else { -+ static FuncDeclaration *adReverse_fd = NULL; -+ if (!adReverse_fd) { -+ Parameters* args = new Parameters; -+ args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); -+ args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); -+ adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse); -+ } -+ fd = adReverse_fd; -+ } -+ -+ ec = new VarExp(Loc(), fd); - e = e->castTo(sc, n->arrayOf()); // convert to dynamic array - arguments = new Expressions(); - if (dup) - arguments->push(getTypeInfo(sc)); - arguments->push(e); - if (!dup) -- arguments->push(new IntegerExp(0, size, Type::tsize_t)); -+ arguments->push(new IntegerExp(Loc(), size, Type::tsize_t)); - e = new CallExp(e->loc, ec, arguments); - if (ident == Id::idup) -- { Type *einv = next->invariantOf(); -+ { Type *einv = next->immutableOf(); - if (next->implicitConvTo(einv) < MATCHconst) -- error(e->loc, "cannot implicitly convert element type %s to immutable in %s.idup", -+ { error(e->loc, "cannot implicitly convert element type %s to immutable in %s.idup", - next->toChars(), olde->toChars()); -+ goto Lerror; -+ } - e->type = einv->arrayOf(); - } - else if (ident == Id::dup) - { - Type *emut = next->mutableOf(); - if (next->implicitConvTo(emut) < MATCHconst) -- error(e->loc, "cannot implicitly convert element type %s to mutable in %s.dup", -+ { error(e->loc, "cannot implicitly convert element type %s to mutable in %s.dup", - next->toChars(), olde->toChars()); -+ goto Lerror; -+ } - e->type = emut->arrayOf(); - } - else -@@ -3562,12 +3733,17 @@ Expression *TypeArray::dotExp(Scope *sc, - } - else if (ident == Id::sort) - { -+ static FuncDeclaration *fd = NULL; - Expression *ec; -- FuncDeclaration *fd; - Expressions *arguments; - -- fd = FuncDeclaration::genCfunc(tint32->arrayOf(), "_adSort"); -- ec = new VarExp(0, fd); -+ if (!fd) { -+ Parameters* args = new Parameters; -+ args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); -+ args->push(new Parameter(STCin, Type::dtypeinfo->type, NULL, NULL)); -+ fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort"); -+ } -+ ec = new VarExp(Loc(), fd); - e = e->castTo(sc, n->arrayOf()); // convert to dynamic array - arguments = new Expressions(); - arguments->push(e); -@@ -3579,10 +3755,14 @@ Expression *TypeArray::dotExp(Scope *sc, - } - else - { -- e = Type::dotExp(sc, e, ident); -+ e = Type::dotExp(sc, e, ident, flag); - } -- e = e->semantic(sc); -+ if (!flag || e) -+ e = e->semantic(sc); - return e; -+ -+Lerror: -+ return new ErrorExp(); - } - - -@@ -3627,8 +3807,8 @@ d_uns64 TypeSArray::size(Loc loc) - return sz; - - Loverflow: -- error(loc, "index %lld overflow for static array", sz); -- return 1; -+ error(loc, "index %lld overflow for static array", (long long)sz); -+ return SIZE_INVALID; - } - - unsigned TypeSArray::alignsize() -@@ -3643,16 +3823,24 @@ unsigned TypeSArray::alignsize() - Expression *semanticLength(Scope *sc, Type *t, Expression *exp) - { - if (t->ty == Ttuple) -- { ScopeDsymbol *sym = new ArrayScopeSymbol(sc, (TypeTuple *)t); -+ { -+ ScopeDsymbol *sym = new ArrayScopeSymbol(sc, (TypeTuple *)t); - sym->parent = sc->scopesym; - sc = sc->push(sym); - -+ sc = sc->startCTFE(); - exp = exp->semantic(sc); -+ sc = sc->endCTFE(); - - sc->pop(); - } - else -+ { -+ sc = sc->startCTFE(); - exp = exp->semantic(sc); -+ sc = sc->endCTFE(); -+ } -+ - return exp; - } - -@@ -3662,45 +3850,52 @@ Expression *semanticLength(Scope *sc, Tu - sym->parent = sc->scopesym; - sc = sc->push(sym); - -+ sc = sc->startCTFE(); - exp = exp->semantic(sc); -+ sc = sc->endCTFE(); - - sc->pop(); - return exp; - } - --void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) -+void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { - //printf("TypeSArray::resolve() %s\n", toChars()); -- next->resolve(loc, sc, pe, pt, ps); -+ next->resolve(loc, sc, pe, pt, ps, intypeid); - //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt); - if (*pe) -- { // It's really an index expression -+ { -+ // It's really an index expression - Expressions *exps = new Expressions(); - exps->setDim(1); - (*exps)[0] = dim; -- Expression *e = new ArrayExp(loc, *pe, exps); -- *pe = e; -+ if (Dsymbol *s = getDsymbol(*pe)) -+ *pe = new DsymbolExp(loc, s, 1); -+ *pe = new ArrayExp(loc, *pe, exps); - } - else if (*ps) -- { Dsymbol *s = *ps; -+ { -+ Dsymbol *s = *ps; - TupleDeclaration *td = s->isTupleDeclaration(); - if (td) - { - ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td); - sym->parent = sc->scopesym; - sc = sc->push(sym); -- -+ sc = sc->startCTFE(); - dim = dim->semantic(sc); -+ sc = sc->endCTFE(); -+ sc = sc->pop(); -+ - dim = dim->ctfeInterpret(); - uinteger_t d = dim->toUInteger(); - -- sc = sc->pop(); -- - if (d >= td->objects->dim) -- { error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim); -+ { -+ error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim); - goto Ldefault; - } -- Object *o = (*td->objects)[(size_t)d]; -+ RootObject *o = (*td->objects)[(size_t)d]; - if (o->dyncast() == DYNCAST_DSYMBOL) - { - *ps = (Dsymbol *)o; -@@ -3746,7 +3941,7 @@ void TypeSArray::resolve(Loc loc, Scope - else - { - Ldefault: -- Type::resolve(loc, sc, pe, pt, ps); -+ Type::resolve(loc, sc, pe, pt, ps, intypeid); - } - } - -@@ -3769,7 +3964,7 @@ Type *TypeSArray::semantic(Loc loc, Scop - { error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim); - return Type::terror; - } -- Object *o = (*sd->objects)[(size_t)d]; -+ RootObject *o = (*sd->objects)[(size_t)d]; - if (o->dyncast() != DYNCAST_TYPE) - { error(loc, "%s is not a type", toChars()); - return Type::terror; -@@ -3778,7 +3973,7 @@ Type *TypeSArray::semantic(Loc loc, Scop - return t; - } - -- Type *tn = next->semantic(loc,sc); -+ Type *tn = next->semantic(loc, sc); - if (tn->ty == Terror) - return terror; - -@@ -3793,14 +3988,6 @@ Type *TypeSArray::semantic(Loc loc, Scop - goto Lerror; - - dim = dim->optimize(WANTvalue); -- if (sc && sc->parameterSpecialization && dim->op == TOKvar && -- ((VarExp *)dim)->var->storage_class & STCtemplateparameter) -- { -- /* It could be a template parameter N which has no value yet: -- * template Foo(T : T[N], size_t N); -- */ -- return this; -- } - dim = dim->ctfeInterpret(); - errors = global.errors; - dinteger_t d1 = dim->toInteger(); -@@ -3825,6 +4012,7 @@ Type *TypeSArray::semantic(Loc loc, Scop - tbn->ty == Tarray || - tbn->ty == Tsarray || - tbn->ty == Taarray || -+ (tbn->ty == Tstruct && (((TypeStruct *)tbn)->sym->sizeok == SIZEOKdone)) || - tbn->ty == Tclass) - { - /* Only do this for types that don't need to have semantic() -@@ -3859,18 +4047,12 @@ Type *TypeSArray::semantic(Loc loc, Scop - Parameter *arg = (*tt->arguments)[(size_t)d]; - return arg->type->addMod(this->mod); - } -- case Tstruct: -- { TypeStruct *ts = (TypeStruct *)tbn; -- if (0 && ts->sym->isnested) -- { error(loc, "cannot have static array of inner struct %s", ts->toChars()); -- goto Lerror; -- } -- break; -- } - case Tfunction: - case Tnone: - error(loc, "can't have array of %s", tbn->toChars()); - goto Lerror; -+ default: -+ break; - } - if (tbn->isscope()) - { error(loc, "cannot have array of scope %s", tbn->toChars()); -@@ -3890,6 +4072,19 @@ Lerror: - return Type::terror; - } - -+// Make corresponding static array type without semantic -+Type *TypeSArray::makeType(Loc loc, Type *tn, dinteger_t dim) -+{ -+ assert(tn->deco); -+ Type *t = new TypeSArray(tn, new IntegerExp(loc, dim, Type::tindex)); -+ -+ // according to TypeSArray::semantic() -+ t = t->addMod(tn->mod); -+ t = t->merge(); -+ -+ return t; -+} -+ - void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag) - { - Type::toDecoBuffer(buf, flag); -@@ -3911,10 +4106,12 @@ void TypeSArray::toCBuffer2(OutBuffer *b - return; - } - next->toCBuffer2(buf, hgs, this->mod); -- buf->printf("[%s]", dim->toChars()); -+ buf->writeByte('['); -+ sizeToCBuffer(buf, hgs, dim); -+ buf->writeByte(']'); - } - --Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeSArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); -@@ -3937,9 +4134,10 @@ Expression *TypeSArray::dotExp(Scope *sc - } - else - { -- e = TypeArray::dotExp(sc, e, ident); -+ e = TypeArray::dotExp(sc, e, ident, flag); - } -- e = e->semantic(sc); -+ if (!flag || e) -+ e = e->semantic(sc); - return e; - } - -@@ -4036,7 +4234,10 @@ Expression *TypeSArray::defaultInit(Loc - #if LOGDEFAULTINIT - printf("TypeSArray::defaultInit() '%s'\n", toChars()); - #endif -- return next->defaultInit(loc); -+ if (next->ty == Tvoid) -+ return tuns8->defaultInit(loc); -+ else -+ return next->defaultInit(loc); - } - - int TypeSArray::isZeroInit(Loc loc) -@@ -4064,12 +4265,16 @@ Expression *TypeSArray::defaultInitLiter - printf("TypeSArray::defaultInitLiteral() '%s'\n", toChars()); - #endif - size_t d = dim->toInteger(); -- Expression *elementinit = next->defaultInitLiteral(loc); -+ Expression *elementinit; -+ if (next->ty == Tvoid) -+ elementinit = tuns8->defaultInitLiteral(loc); -+ else -+ elementinit = next->defaultInitLiteral(loc); - Expressions *elements = new Expressions(); - elements->setDim(d); - for (size_t i = 0; i < d; i++) - (*elements)[i] = elementinit; -- ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements); -+ ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), elements); - ae->type = this; - return ae; - } -@@ -4151,31 +4356,29 @@ Type *TypeDArray::semantic(Loc loc, Scop - error(loc, "can't have array of %s", tbn->toChars()); - case Terror: - return Type::terror; -- -- case Tstruct: -- { TypeStruct *ts = (TypeStruct *)tbn; -- if (0 && ts->sym->isnested) -- error(loc, "cannot have dynamic array of inner struct %s", ts->toChars()); -+ default: - break; -- } - } - if (tn->isscope()) -- error(loc, "cannot have array of scope %s", tn->toChars()); -- -+ { error(loc, "cannot have array of scope %s", tn->toChars()); -+ return Type::terror; -+ } - next = tn; - transitive(); - return merge(); - } - --void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) -+void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { - //printf("TypeDArray::resolve() %s\n", toChars()); -- next->resolve(loc, sc, pe, pt, ps); -+ next->resolve(loc, sc, pe, pt, ps, intypeid); - //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt); - if (*pe) -- { // It's really a slice expression -- Expression *e = new SliceExp(loc, *pe, NULL, NULL); -- *pe = e; -+ { -+ // It's really a slice expression -+ if (Dsymbol *s = getDsymbol(*pe)) -+ *pe = new DsymbolExp(loc, s, 1); -+ *pe = new SliceExp(loc, *pe, NULL, NULL); - } - else if (*ps) - { -@@ -4188,7 +4391,7 @@ void TypeDArray::resolve(Loc loc, Scope - else - { - Ldefault: -- Type::resolve(loc, sc, pe, pt, ps); -+ Type::resolve(loc, sc, pe, pt, ps, intypeid); - } - } - -@@ -4213,7 +4416,7 @@ void TypeDArray::toCBuffer2(OutBuffer *b - } - } - --Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeDArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); -@@ -4238,7 +4441,7 @@ Expression *TypeDArray::dotExp(Scope *sc - } - else - { -- e = TypeArray::dotExp(sc, e, ident); -+ e = TypeArray::dotExp(sc, e, ident, flag); - } - return e; - } -@@ -4268,7 +4471,7 @@ MATCH TypeDArray::implicitConvTo(Type *t - return MATCHconvert; - } - -- return next->constConv(to) ? MATCHconvert : MATCHnomatch; -+ return next->constConv(tp->next) ? MATCHconvert : MATCHnomatch; - } - - if (to->ty == Tarray) -@@ -4334,7 +4537,7 @@ TypeAArray::TypeAArray(Type *t, Type *in - { - this->index = index; - this->impl = NULL; -- this->loc = 0; -+ this->loc = Loc(); - this->sc = NULL; - } - -@@ -4383,22 +4586,23 @@ Type *TypeAArray::semantic(Loc loc, Scop - - index->resolve(loc, sc, &e, &t, &s); - if (e) -- { // It was an expression - -+ { -+ // It was an expression - - // Rewrite as a static array -- TypeSArray *tsa; -- -- tsa = new TypeSArray(next, e); -- return tsa->semantic(loc,sc); -+ TypeSArray *tsa = new TypeSArray(next, e); -+ return tsa->semantic(loc, sc); - } - else if (t) -- index = t; -+ index = t->semantic(loc, sc); - else -- { index->error(loc, "index is not a type or an expression"); -+ { -+ index->error(loc, "index is not a type or an expression"); - return Type::terror; - } - } - else - index = index->semantic(loc,sc); -+ index = index->merge2(); - - if (index->nextOf() && !index->nextOf()->isImmutable()) - { -@@ -4425,7 +4629,7 @@ printf("index->ito->ito = x%x\n", index- - case Terror: - return Type::terror; - } -- next = next->semantic(loc,sc); -+ next = next->semantic(loc,sc)->merge2(); - transitive(); - - switch (next->toBasetype()->ty) -@@ -4458,7 +4662,7 @@ StructDeclaration *TypeAArray::getImpl() - next = terror; - - // Head off future failures -- StructDeclaration *s = new StructDeclaration(0, NULL); -+ StructDeclaration *s = new StructDeclaration(Loc(), NULL); - s->type = terror; - impl = s; - return impl; -@@ -4489,9 +4693,13 @@ StructDeclaration *TypeAArray::getImpl() - dti->semantic(sc); - TemplateInstance *ti = dti->ti; - #endif -- ti->semantic(sc); -- ti->semantic2(sc); -- ti->semantic3(sc); -+ // Instantiate on the root module of import dependency graph. -+ Scope *scx = sc->push(sc->module->importedFrom); -+ scx->instantiatingModule = sc->module->importedFrom; -+ ti->semantic(scx); -+ ti->semantic2(scx); -+ ti->semantic3(scx); -+ scx->pop(); - impl = ti->toAlias()->isStructDeclaration(); - #ifdef DEBUG - if (!impl) -@@ -4504,7 +4712,7 @@ StructDeclaration *TypeAArray::getImpl() - return impl; - } - --void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) -+void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { - //printf("TypeAArray::resolve() %s\n", toChars()); - -@@ -4516,92 +4724,29 @@ void TypeAArray::resolve(Loc loc, Scope - Type *t; - Dsymbol *s; - -- index->resolve(loc, sc, &e, &t, &s); -+ index->resolve(loc, sc, &e, &t, &s, intypeid); - if (e) -- { // It was an expression - -+ { -+ // It was an expression - - // Rewrite as a static array -- - TypeSArray *tsa = new TypeSArray(next, e); -- return tsa->addMod(this->mod)->resolve(loc, sc, pe, pt, ps); -+ tsa->mod = this->mod; // just copy mod field so tsa's semantic is not yet done -+ return tsa->resolve(loc, sc, pe, pt, ps, intypeid); - } - else if (t) - index = t; - else - index->error(loc, "index is not a type or an expression"); - } -- Type::resolve(loc, sc, pe, pt, ps); -+ Type::resolve(loc, sc, pe, pt, ps, intypeid); - } - - --Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeAArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); - #endif --#if 0 -- if (ident == Id::length) -- { -- Expression *ec; -- FuncDeclaration *fd; -- Expressions *arguments; -- -- fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen); -- ec = new VarExp(0, fd); -- arguments = new Expressions(); -- arguments->push(e); -- e = new CallExp(e->loc, ec, arguments); -- e->type = ((TypeFunction *)fd->type)->next; -- } -- else -- if (ident == Id::keys) -- { -- Expression *ec; -- FuncDeclaration *fd; -- Expressions *arguments; -- int size = index->size(e->loc); -- -- assert(size); -- fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaKeys); -- ec = new VarExp(0, fd); -- arguments = new Expressions(); -- arguments->push(e); -- arguments->push(new IntegerExp(0, size, Type::tsize_t)); -- e = new CallExp(e->loc, ec, arguments); -- e->type = index->arrayOf(); -- } -- else if (ident == Id::values) -- { -- Expression *ec; -- FuncDeclaration *fd; -- Expressions *arguments; -- -- fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaValues); -- ec = new VarExp(0, fd); -- arguments = new Expressions(); -- arguments->push(e); -- size_t keysize = index->size(e->loc); -- keysize = (keysize + Target::ptrsize - 1) & ~(Target::ptrsize - 1); -- arguments->push(new IntegerExp(0, keysize, Type::tsize_t)); -- arguments->push(new IntegerExp(0, next->size(e->loc), Type::tsize_t)); -- e = new CallExp(e->loc, ec, arguments); -- e->type = next->arrayOf(); -- } -- else if (ident == Id::rehash) -- { -- Expression *ec; -- FuncDeclaration *fd; -- Expressions *arguments; -- -- fd = FuncDeclaration::genCfunc(Type::tint64, Id::aaRehash); -- ec = new VarExp(0, fd); -- arguments = new Expressions(); -- arguments->push(e->addressOf(sc)); -- arguments->push(index->getInternalTypeInfo(sc)); -- e = new CallExp(e->loc, ec, arguments); -- e->type = this; -- } -- else --#endif - if (ident != Id::__sizeof && - ident != Id::__xalignof && - ident != Id::init && -@@ -4609,15 +4754,13 @@ Expression *TypeAArray::dotExp(Scope *sc - ident != Id::stringof && - ident != Id::offsetof) - { --//printf("test1: %s, %s\n", e->toChars(), e->type->toChars()); - Type *t = getImpl()->type; --//printf("test2: %s, %s\n", e->toChars(), e->type->toChars()); -+ e = e->copy(); - e->type = t; -- e = t->dotExp(sc, e, ident); --//printf("test3: %s, %s\n", e->toChars(), e->type->toChars()); -+ e = t->dotExp(sc, e, ident, flag); - } - else -- e = Type::dotExp(sc, e, ident); -+ e = Type::dotExp(sc, e, ident, flag); - return e; - } - -@@ -4779,6 +4922,8 @@ Type *TypePointer::semantic(Loc loc, Sco - error(loc, "can't have pointer to %s", n->toChars()); - case Terror: - return Type::terror; -+ default: -+ break; - } - if (n != next) - { -@@ -4789,7 +4934,7 @@ Type *TypePointer::semantic(Loc loc, Sco - { transitive(); - return merge(); - } --#if 1 -+#if 0 - return merge(); - #else - deco = merge()->deco; -@@ -4967,14 +5112,14 @@ void TypeReference::toCBuffer2(OutBuffer - buf->writeByte('&'); - } - --Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeReference::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); - #endif - - // References just forward things along -- return next->dotExp(sc, e, ident); -+ return next->dotExp(sc, e, ident, flag); - } - - Expression *TypeReference::defaultInit(Loc loc) -@@ -4993,7 +5138,7 @@ int TypeReference::isZeroInit(Loc loc) - - /***************************** TypeFunction *****************************/ - --TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, enum LINK linkage, StorageClass stc) -+TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc) - : TypeNext(Tfunction, treturn) - { - //if (!treturn) *(char*)0=0; -@@ -5034,13 +5179,6 @@ const char *TypeFunction::kind() - return "function"; - } - --TypeFunction *TypeFunction::copy() --{ -- TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); -- memcpy(tf, this, sizeof(TypeFunction)); -- return tf; --} -- - Type *TypeFunction::syntaxCopy() - { - Type *treturn = next ? next->syntaxCopy() : NULL; -@@ -5051,6 +5189,7 @@ Type *TypeFunction::syntaxCopy() - t->purity = purity; - t->isproperty = isproperty; - t->isref = isref; -+ t->iswild = iswild; - t->trust = trust; - t->fargs = fargs; - return t; -@@ -5110,12 +5249,7 @@ int Type::covariant(Type *t, StorageClas - - if (!arg1->type->equals(arg2->type)) - { --#if 0 // turn on this for contravariant argument types, see bugzilla 3075 -- // BUG: cannot convert ref to const to ref to immutable -- // We can add const, but not subtract it -- if (arg2->type->implicitConvTo(arg1->type) < MATCHconst) --#endif -- goto Ldistinct; -+ goto Ldistinct; - } - const StorageClass sc = STCref | STCin | STCout | STClazy; - if ((arg1->storageClass & sc) != (arg2->storageClass & sc)) -@@ -5161,13 +5295,9 @@ int Type::covariant(Type *t, StorageClas - - // If t1n is forward referenced: - ClassDeclaration *cd = ((TypeClass *)t1n)->sym; --// if (cd->scope) --// cd->semantic(NULL); --#if 0 -- if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) --#else -+ if (cd->scope) -+ cd->semantic(NULL); - if (!cd->isBaseInfoComplete()) --#endif - { - return 3; // forward references - } -@@ -5180,7 +5310,8 @@ int Type::covariant(Type *t, StorageClas - } - else if (t1n->ty == t2n->ty && t1n->implicitConvTo(t2n)) - goto Lcovariant; -- else if (t1n->ty == Tnull && t1n->implicitConvTo(t2n)) -+ else if (t1n->ty == Tnull && t1n->implicitConvTo(t2n) && -+ t1n->size() == t2n->size()) - goto Lcovariant; - } - goto Lnotcovariant; -@@ -5193,11 +5324,15 @@ Lcovariant: - */ - if (!MODimplicitConv(t2->mod, t1->mod)) - { -+#if 0//stop attribute inference with const - // If adding 'const' will make it covariant - if (MODimplicitConv(t2->mod, MODmerge(t1->mod, MODconst))) - stc |= STCconst; - else - goto Lnotcovariant; -+#else -+ goto Ldistinct; -+#endif - } - - /* Can convert pure to impure, and nothrow to throw -@@ -5476,13 +5611,13 @@ Type *TypeFunction::semantic(Loc loc, Sc - * This can produce redundant copies if inferring return type, - * as semantic() will get called again on this. - */ -- TypeFunction *tf = copy(); -+ TypeFunction *tf = (TypeFunction *)copy(); - if (parameters) - { tf->parameters = (Parameters *)parameters->copy(); - for (size_t i = 0; i < parameters->dim; i++) - { Parameter *arg = (*parameters)[i]; - Parameter *cpy = (Parameter *)mem.malloc(sizeof(Parameter)); -- memcpy(cpy, arg, sizeof(Parameter)); -+ memcpy((void*)cpy, (void*)arg, sizeof(Parameter)); - (*tf->parameters)[i] = cpy; - } - } -@@ -5505,7 +5640,7 @@ Type *TypeFunction::semantic(Loc loc, Sc - tf->isproperty = TRUE; - - tf->linkage = sc->linkage; -- -+#if 0 - /* If the parent is @safe, then this function defaults to safe - * too. - * If the parent's @safe-ty is inferred, then this function's @safe-ty needs -@@ -5521,7 +5656,7 @@ Type *TypeFunction::semantic(Loc loc, Sc - break; - } - } -- -+#endif - bool wildreturn = FALSE; - if (tf->next) - { -@@ -5529,18 +5664,30 @@ Type *TypeFunction::semantic(Loc loc, Sc - sc->stc &= ~(STC_TYPECTOR | STC_FUNCATTR); - tf->next = tf->next->semantic(loc,sc); - sc = sc->pop(); -- if (tf->next->toBasetype()->ty == Tfunction) -- { error(loc, "functions cannot return a function"); -+ Type *tb = tf->next->toBasetype(); -+ if (tb->ty == Tfunction) -+ { -+ error(loc, "functions cannot return a function"); - tf->next = Type::terror; - } -- if (tf->next->toBasetype()->ty == Ttuple) -- { error(loc, "functions cannot return a tuple"); -+ else if (tb->ty == Ttuple) -+ { -+ error(loc, "functions cannot return a tuple"); - tf->next = Type::terror; - } -+ else if (tb->ty == Tstruct) -+ { -+ StructDeclaration *sd = ((TypeStruct *)tb)->sym; -+ if (sd->isforwardRef()) -+ { -+ error(loc, "cannot return opaque struct %s by value", tb->toChars()); -+ tf->next = Type::terror; -+ } -+ } -+ else if (tb->ty == Tvoid) -+ tf->isref = FALSE; // rewrite "ref void" as just "void" - if (tf->next->isscope() && !(sc->flags & SCOPEctor)) - error(loc, "functions cannot return scope %s", tf->next->toChars()); -- if (tf->next->toBasetype()->ty == Tvoid) -- tf->isref = FALSE; // rewrite "ref void" as just "void" - if (tf->next->hasWild() && - !(tf->next->ty == Tpointer && tf->next->nextOf()->ty == Tfunction || tf->next->ty == Tdelegate)) - wildreturn = TRUE; -@@ -5574,15 +5721,27 @@ Type *TypeFunction::semantic(Loc loc, Sc - - Type *t = fparam->type->toBasetype(); - -- if (fparam->storageClass & (STCout | STCref | STClazy)) -- { -- //if (t->ty == Tsarray) -- //error(loc, "cannot have out or ref parameter of type %s", t->toChars()); -- if (fparam->storageClass & STCout && fparam->type->mod & (STCconst | STCimmutable)) -- error(loc, "cannot have const or immutable out parameter of type %s", t->toChars()); -- } - if (!(fparam->storageClass & STClazy) && t->ty == Tvoid) - error(loc, "cannot have parameter of type %s", fparam->type->toChars()); -+ if (fparam->storageClass & (STCref | STClazy)) -+ { -+ } -+ else if (fparam->storageClass & STCout) -+ { -+ if (unsigned m = fparam->type->mod & (MODimmutable | MODconst | MODwild)) -+ error(loc, "cannot have %s out parameter of type %s", MODtoChars(m), t->toChars()); -+ else -+ { -+ Type *tv = t; -+ while (tv->ty == Tsarray) -+ tv = tv->nextOf()->toBasetype(); -+ if (tv->ty == Tstruct && ((TypeStruct *)tv)->sym->noDefaultCtor) -+ { -+ error(loc, "cannot have out parameter of type %s because the default construction is disbaled", -+ fparam->type->toChars()); -+ } -+ } -+ } - - if (t->hasWild() && - !(t->ty == Tpointer && t->nextOf()->ty == Tfunction || t->ty == Tdelegate)) -@@ -5658,7 +5817,10 @@ Type *TypeFunction::semantic(Loc loc, Sc - if (fparam->storageClass & STCauto) - { - if (fargs && i < fargs->dim) -- { Expression *farg = (*fargs)[i]; -+ { -+ Expression *farg = (*fargs)[i]; -+ if (Expression *e = farg->isTemp()) -+ farg = e; - if (farg->isLvalue()) - ; // ref parameter - else -@@ -5703,168 +5865,78 @@ Type *TypeFunction::semantic(Loc loc, Sc - } - - --Type *getIndirection(Type *t) --{ -- t = t->toBasetype(); -- -- if (t->ty == Tsarray) -- { while (t->ty == Tsarray) -- t = t->nextOf()->toBasetype(); -- } -- if (t->ty == Tarray || t->ty == Tpointer) -- return t->nextOf()->toBasetype(); -- if (t->ty == Taarray || t->ty == Tclass) -- return t; -- if (t->ty == Tstruct) -- return t->hasPointers() ? t : NULL; // TODO -- -- // should consider TypeDelegate? -- return NULL; --} -- - /******************************************** - * Do this lazily, as the parameter types might be forward referenced. - */ - void TypeFunction::purityLevel() - { -- //printf("purityLevel(%s)\n", toChars()); -- - TypeFunction *tf = this; -- if (tf->purity == PUREfwdref && tf->next) -+ if (tf->purity == PUREfwdref) - { /* Evaluate what kind of purity based on the modifiers for the parameters - */ -- enum PURE purity = PUREstrong; // assume strong until something weakens it -- size_t dim = Parameter::dim(tf->parameters); -- -- if (dim) -+ tf->purity = PUREstrong; // assume strong until something weakens it -+ if (tf->parameters) - { -- Type *tret = tf->next; -- assert(tret); -- Type *treti = tf->isref ? tret->toBasetype() : getIndirection(tret); -- if (treti && (treti->mod & MODimmutable)) -- treti = NULL; // indirection is immutable -- //printf(" tret = %s, treti = %s\n", tret->toChars(), treti ? treti->toChars() : "NULL"); -- -+ size_t dim = Parameter::dim(tf->parameters); - for (size_t i = 0; i < dim; i++) - { Parameter *fparam = Parameter::getNth(tf->parameters, i); - if (fparam->storageClass & STClazy) - { -- purity = PUREweak; -+ tf->purity = PUREweak; - break; - } - if (fparam->storageClass & STCout) - { -- purity = PUREweak; -+ tf->purity = PUREweak; - break; - } - if (!fparam->type) - continue; -- -- Type *tprm = fparam->type; -- Type *tprmi = fparam->storageClass & STCref ? tprm->toBasetype() : getIndirection(tprm); -- //printf(" [%d] tprm = %s, tprmi = %s\n", i, tprm->toChars(), tprmi ? tprmi->toChars() : "NULL"); -- -- if (!tprmi || (tprmi->mod & MODimmutable)) -- continue; // there is no mutable indirection -- if (tprmi->isMutable()) -- { purity = PUREweak; // indirection is mutable -- break; -+ if (fparam->storageClass & STCref) -+ { -+ if (!(fparam->type->mod & (MODconst | MODimmutable | MODwild))) -+ { tf->purity = PUREweak; -+ break; -+ } -+ if (fparam->type->mod & MODconst) -+ { tf->purity = PUREconst; -+ continue; -+ } - } -- if (!treti) -- continue; // mutable indirection is never returned -- -- if (purity < PUREstrong) -+ Type *t = fparam->type->toBasetype(); -+ if (!t->hasPointers()) - continue; -- -- // Determine the parameter is really PUREconst or not -- assert(tprmi->mod & (MODconst | MODwild)); -- if (tprmi->constConv(treti)) // simple case -- purity = PUREconst; -- else if (tprmi->invariantOf()->equals(treti->invariantOf())) -+ if (t->mod & MODimmutable) -+ continue; -+ /* The rest of this is too strict; fix later. -+ * For example, the only pointer members of a struct may be immutable, -+ * which would maintain strong purity. -+ */ -+ if (t->mod & (MODconst | MODwild)) -+ { tf->purity = PUREconst; - continue; -- else -- { -- /* The rest of this is little strict; fix later. -- * For example: -- * -- * struct S { immutable* p; } -- * pure S foo(const int* p); -- * -- * which would maintain strong purity. -- */ -- if (tprmi->hasPointers() || treti->hasPointers()) -- purity = PUREconst; - } -- -+ Type *tn = t->nextOf(); -+ if (tn) -+ { tn = tn->toBasetype(); -+ if (tn->ty == Tpointer || tn->ty == Tarray) -+ { /* Accept immutable(T)* and immutable(T)[] as being strongly pure -+ */ -+ if (tn->mod & MODimmutable) -+ continue; -+ if (tn->mod & (MODconst | MODwild)) -+ { tf->purity = PUREconst; -+ continue; -+ } -+ } -+ } - /* Should catch delegates and function pointers, and fold in their purity - */ -+ tf->purity = PUREweak; // err on the side of too strict -+ break; - } - } -- -- //printf(" --> purity: %d\n", purity); -- tf->purity = purity; -- } --} -- --/******************************************** -- * FIXME: This function is a workaround for fixing Bugzilla 9210. -- * In 2.061, TypeFunction::purityLevel() improved to make more functions -- * strong purity, but immutable conversion on return statemet had broken by that. -- * Because, it is essentially unrelated to PUREstrong. This function is -- * necessary to check the convertibility. -- */ --bool TypeFunction::hasMutableIndirectionParams() --{ -- TypeFunction *tf = this; -- size_t dim = Parameter::dim(tf->parameters); -- for (size_t i = 0; i < dim; i++) -- { -- Parameter *fparam = Parameter::getNth(tf->parameters, i); -- if (fparam->storageClass & STClazy) -- { -- return true; -- } -- if (fparam->storageClass & STCout) -- { -- return true; -- } -- if (!fparam->type) -- continue; -- if (fparam->storageClass & STCref) -- { -- if (!(fparam->type->mod & (MODconst | MODimmutable | MODwild))) -- return true; -- if (fparam->type->mod & MODconst) -- return true; -- } -- Type *t = fparam->type->toBasetype(); -- if (!t->hasPointers()) -- continue; -- if (t->mod & (MODimmutable | MODwild)) -- continue; -- /* The rest of this is too strict; fix later. -- * For example, the only pointer members of a struct may be immutable, -- * which would maintain strong purity. -- */ -- if (t->mod & MODconst) -- return true; -- Type *tn = t->nextOf(); -- if (tn) -- { tn = tn->toBasetype(); -- if (tn->ty == Tpointer || tn->ty == Tarray) -- { /* Accept immutable(T)* and immutable(T)[] as being strongly pure -- */ -- if (tn->mod & (MODimmutable | MODwild)) -- continue; -- if (tn->mod & MODconst) -- return true; -- } -- } -- /* Should catch delegates and function pointers, and fold in their purity -- */ -- return true; - } -- return false; - } - - -@@ -5877,14 +5949,14 @@ bool TypeFunction::hasMutableIndirection - * MATCHxxxx - */ - --MATCH TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag) -+MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag) - { - //printf("TypeFunction::callMatch() %s\n", toChars()); - MATCH match = MATCHexact; // assume exact match - unsigned wildmatch = 0; - -- if (ethis) -- { Type *t = ethis->type; -+ if (tthis) -+ { Type *t = tthis; - if (t->toBasetype()->ty == Tpointer) - t = t->toBasetype()->nextOf(); // change struct* to struct - if (t->mod != mod) -@@ -5971,6 +6043,8 @@ MATCH TypeFunction::callMatch(Expression - { - Expression *arg = (*args)[u]; - assert(arg); -+ if (Expression *e = arg->isTemp()) -+ arg = e; - - if (arg->op == TOKfunction) - { -@@ -5999,24 +6073,37 @@ MATCH TypeFunction::callMatch(Expression - - // Non-lvalues do not match ref or out parameters - if (p->storageClass & STCref) -- { if (m && !arg->isLvalue()) -+ { -+ Type *targb = targ->toBasetype(); -+ Type *tprmb = tprm->toBasetype(); -+ //printf("%s\n", targb->toChars()); -+ //printf("%s\n", tprmb->toChars()); -+ -+ if (m && !arg->isLvalue()) - { -- Type *ta = targ->aliasthisOf(); -- if (arg->op == TOKstring && tprm->ty == Tsarray) -- { if (targ->ty != Tsarray) -- targ = new TypeSArray(targ->nextOf(), -- new IntegerExp(0, ((StringExp *)arg)->len, -- Type::tindex)); -+ if (arg->op == TOKstring && tprmb->ty == Tsarray) -+ { -+ if (targb->ty != Tsarray) -+ { -+ Type *tn = tprmb->nextOf()->castMod(targb->nextOf()->mod); -+ dinteger_t dim = ((StringExp *)arg)->len; -+ targb = TypeSArray::makeType(Loc(), tn, dim); -+ } -+ } -+ else if (arg->op == TOKslice && tprmb->ty == Tsarray) -+ { -+ // Allow conversion from T[lwr .. upr] to ref T[upr-lwr] -+ if (targb->ty != Tsarray) -+ { -+ Type *tn = targb->nextOf(); -+ dinteger_t dim = ((TypeSArray *)tprmb)->dim->toUInteger(); -+ targb = TypeSArray::makeType(Loc(), tn, dim); -+ } - } - else - goto Nomatch; - } - -- Type *targb = targ->toBasetype(); -- Type *tprmb = tprm->toBasetype(); -- //printf("%s\n", targb->toChars()); -- //printf("%s\n", tprmb->toChars()); -- - /* find most derived alias this type being matched. - */ - while (1) -@@ -6178,7 +6265,7 @@ bool TypeFunction::parameterEscapes(Para - if (!nextOf()) - return TRUE; - -- if (purity) -+ if (purity > PUREweak) - { /* With pure functions, we need only be concerned if p escapes - * via any return statement. - */ -@@ -6218,6 +6305,7 @@ Type *TypeFunction::addStorageClass(Stor - tf->isproperty = t->isproperty; - tf->isref = t->isref; - tf->trust = t->trust; -+ tf->iswild = t->iswild; - - if (stc & STCpure) - tf->purity = PUREfwdref; -@@ -6270,7 +6358,7 @@ Type *TypeDelegate::semantic(Loc loc, Sc - * be removed from next before the merge. - */ - --#if 1 -+#if 0 - return merge(); - #else - /* Don't return merge(), because arg identifiers and default args -@@ -6339,7 +6427,7 @@ int TypeDelegate::checkBoolean() - return TRUE; - } - --Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeDelegate::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); -@@ -6349,12 +6437,12 @@ Expression *TypeDelegate::dotExp(Scope * - #ifndef IN_GCC - e->type = tvoidptr; - #else -- if (e->op == TOKdelegate || e->op == TOKcast) -- e = e->castTo(sc, tvoidptr); // Not an lvalue -+ if (!e->isLvalue()) -+ e = e->castTo(sc, tvoidptr); - else - { - e = e->addressOf(sc); -- e = e->castTo(sc, tvoidptr->pointerTo()); -+ e->type = tvoidptr; - e = new PtrExp(e->loc, e); - e->type = tvoidptr; - } -@@ -6366,7 +6454,7 @@ Expression *TypeDelegate::dotExp(Scope * - if (!e->isLvalue()) - { - Identifier *idtmp = Lexer::uniqueId("__dgtmp"); -- VarDeclaration *tmp = new VarDeclaration(e->loc, this, idtmp, new ExpInitializer(0, e)); -+ VarDeclaration *tmp = new VarDeclaration(e->loc, this, idtmp, new ExpInitializer(Loc(), e)); - tmp->storage_class |= STCctfe; - e = new DeclarationExp(e->loc, tmp); - e = new CommaExp(e->loc, e, new VarExp(e->loc, tmp)); -@@ -6382,7 +6470,7 @@ Expression *TypeDelegate::dotExp(Scope * - } - else - { -- e = Type::dotExp(sc, e, ident); -+ e = Type::dotExp(sc, e, ident, flag); - } - return e; - } -@@ -6408,13 +6496,13 @@ void TypeQualified::syntaxCopyHelper(Typ - idents.setDim(t->idents.dim); - for (size_t i = 0; i < idents.dim; i++) - { -- Identifier *id = t->idents[i]; -+ RootObject *id = t->idents[i]; - if (id->dyncast() == DYNCAST_DSYMBOL) - { - TemplateInstance *ti = (TemplateInstance *)id; - - ti = (TemplateInstance *)ti->syntaxCopy(NULL); -- id = (Identifier *)ti; -+ id = ti; - } - idents[i] = id; - } -@@ -6426,10 +6514,15 @@ void TypeQualified::addIdent(Identifier - idents.push(ident); - } - -+void TypeQualified::addInst(TemplateInstance *inst) -+{ -+ idents.push(inst); -+} -+ - void TypeQualified::toCBuffer2Helper(OutBuffer *buf, HdrGenState *hgs) - { - for (size_t i = 0; i < idents.dim; i++) -- { Identifier *id = idents[i]; -+ { RootObject *id = idents[i]; - - buf->writeByte('.'); - -@@ -6446,7 +6539,7 @@ void TypeQualified::toCBuffer2Helper(Out - d_uns64 TypeQualified::size(Loc loc) - { - error(this->loc, "size of type %s is not known", toChars()); -- return 1; -+ return SIZE_INVALID; - } - - /************************************* -@@ -6459,13 +6552,8 @@ d_uns64 TypeQualified::size(Loc loc) - - void TypeQualified::resolveHelper(Loc loc, Scope *sc, - Dsymbol *s, Dsymbol *scopesym, -- Expression **pe, Type **pt, Dsymbol **ps) -+ Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { -- VarDeclaration *v; -- EnumMember *em; -- Expression *e; -- TemplateInstance *ti; -- - #if 0 - printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); - if (scopesym) -@@ -6482,66 +6570,63 @@ void TypeQualified::resolveHelper(Loc lo - //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); - for (size_t i = 0; i < idents.dim; i++) - { -- Identifier *id = idents[i]; -+ RootObject *id = idents[i]; -+ Type *t = s->getType(); // type symbol, type alias, or type tuple? - Dsymbol *sm = s->searchX(loc, sc, id); -- //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); -- //printf("\tgetType = '%s'\n", s->getType()->toChars()); -+ //printf("\t3: s = %p %s %s, sm = %p\n", s, s->kind(), s->toChars(), sm); -+ if (intypeid && !t && sm && sm->needThis()) -+ goto L3; - if (!sm) -- { Type *t; -- -- v = s->isVarDeclaration(); -- ti = s->isTemplateInstance(); -- if (v && id == Id::length) -- { -- e = new VarExp(loc, v); -- t = e->type; -- if (!t) -- goto Lerror; -- goto L3; -- } -- else if ((v && (id == Id::stringof || id == Id::offsetof)) -- || (ti && (id == Id::stringof || id == Id::mangleof))) -+ { -+ if (!t) - { -- e = new DsymbolExp(loc, s, 0); -- do -+ if (s->isDeclaration()) // var, func, or tuple declaration? - { -- id = idents[i]; -- e = new DotIdExp(loc, e, id); -- } while (++i < idents.dim); -- e = e->semantic(sc); -- *pe = e; -- return; -- } -- -- t = s->getType(); -- if (!t && s->isDeclaration()) -- { t = s->isDeclaration()->type; -- if (!t && s->isTupleDeclaration()) -+ t = s->isDeclaration()->type; -+ if (!t && s->isTupleDeclaration()) // expression tuple? -+ goto L3; -+ } -+ else if (s->isTemplateInstance() || -+ s->isImport() || s->isPackage() || s->isModule()) - { -- e = new TupleExp(loc, s->isTupleDeclaration()); -- e = e->semantic(sc); -- t = e->type; -+ goto L3; - } - } - if (t) - { - sm = t->toDsymbol(sc); -- if (sm) -- { sm = sm->search(loc, id, 0); -+ if (sm && id->dyncast() == DYNCAST_IDENTIFIER) -+ { -+ sm = sm->search(loc, (Identifier *)id, 0); - if (sm) - goto L2; - } -- //e = t->getProperty(loc, id); -- e = new TypeExp(loc, t); -- e = t->dotExp(sc, e, id); -- i++; - L3: -+ Expression *e; -+ VarDeclaration *v = s->isVarDeclaration(); -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ if (intypeid || !v && !f) -+ e = new DsymbolExp(loc, s); -+ else -+ e = new VarExp(loc, s->isDeclaration()); -+ e = e->semantic(sc); - for (; i < idents.dim; i++) - { -- id = idents[i]; -+ RootObject *id = idents[i]; - //printf("e: '%s', id: '%s', type = %s\n", e->toChars(), id->toChars(), e->type->toChars()); -- e = new DotIdExp(e->loc, e, id); -- e = e->semantic(sc); -+ if (id->dyncast() == DYNCAST_IDENTIFIER) -+ { -+ DotIdExp *die = new DotIdExp(e->loc, e, (Identifier *)id); -+ e = die->semanticY(sc, 0); -+ } -+ else -+ { -+ assert(id->dyncast() == DYNCAST_DSYMBOL); -+ TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance(); -+ assert(ti); -+ DotTemplateInstanceExp *dte = new DotTemplateInstanceExp(e->loc, e, ti->name, ti->tiargs); -+ e = dte->semanticY(sc, 0); -+ } - } - if (e->op == TOKtype) - *pt = e->type; -@@ -6550,14 +6635,14 @@ void TypeQualified::resolveHelper(Loc lo - } - else - { -- Lerror: - if (id->dyncast() == DYNCAST_DSYMBOL) - { // searchX already handles errors for template instances - assert(global.errors); - } - else - { -- sm = s->search_correct(id); -+ assert(id->dyncast() == DYNCAST_IDENTIFIER); -+ sm = s->search_correct((Identifier *)id); - if (sm) - error(loc, "identifier '%s' of '%s' is not defined, did you mean '%s %s'?", - id->toChars(), toChars(), sm->kind(), sm->toChars()); -@@ -6572,25 +6657,27 @@ void TypeQualified::resolveHelper(Loc lo - s = sm->toAlias(); - } - -- v = s->isVarDeclaration(); -- if (v) -+ if (VarDeclaration *v = s->isVarDeclaration()) - { -+ if (v && v->inuse && (!v->type || !v->type->deco)) // Bugzilla 9494 -+ { error(loc, "circular reference to '%s'", v->toPrettyChars()); -+ *pe = new ErrorExp(); -+ return; -+ } - *pe = new VarExp(loc, v); - return; - } - #if 0 -- fd = s->isFuncDeclaration(); -- if (fd) -+ if (FuncDeclaration *fd = s->isFuncDeclaration()) - { - *pe = new DsymbolExp(loc, fd, 1); - return; - } - #endif -- em = s->isEnumMember(); -- if (em) -+ if (EnumMember *em = s->isEnumMember()) - { - // It's not a type, it's an expression -- *pe = em->value->copy(); -+ *pe = em->getVarExp(loc, sc); - return; - } - -@@ -6599,10 +6686,7 @@ L1: - if (!t) - { - // If the symbol is an import, try looking inside the import -- Import *si; -- -- si = s->isImport(); -- if (si) -+ if (Import *si = s->isImport()) - { - s = si->search(loc, s->ident, 0); - if (s && s != si) -@@ -6614,6 +6698,7 @@ L1: - } - if (t->ty == Tinstance && t != this && !t->deco) - { error(loc, "forward reference to '%s'", t->toChars()); -+ *pt = Type::terror; - return; - } - -@@ -6633,6 +6718,7 @@ L1: - { - if (!scx) - { error(loc, "forward reference to '%s'", t->toChars()); -+ *pt = Type::terror; - return; - } - if (scx->scopesym == scopesym) -@@ -6718,7 +6804,7 @@ void TypeIdentifier::toCBuffer2(OutBuffe - * if type, *pt is set - */ - --void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) -+void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { - Dsymbol *scopesym; - -@@ -6747,7 +6833,7 @@ void TypeIdentifier::resolve(Loc loc, Sc - } - - Dsymbol *s = sc->search(loc, ident, &scopesym); -- resolveHelper(loc, sc, s, scopesym, pe, pt, ps); -+ resolveHelper(loc, sc, s, scopesym, pe, pt, ps, intypeid); - if (*pt) - (*pt) = (*pt)->addMod(mod); - } -@@ -6770,7 +6856,7 @@ Dsymbol *TypeIdentifier::toDsymbol(Scope - { - for (size_t i = 0; i < idents.dim; i++) - { -- Identifier *id = idents[i]; -+ RootObject *id = idents[i]; - s = s->searchX(loc, sc, id); - if (!s) // failed to find a symbol - { //printf("\tdidn't find a symbol\n"); -@@ -6794,10 +6880,12 @@ Type *TypeIdentifier::semantic(Loc loc, - //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco); - - if (t->ty == Ttypedef) -- { TypeTypedef *tt = (TypeTypedef *)t; -- -+ { -+ TypeTypedef *tt = (TypeTypedef *)t; - if (tt->sym->sem == SemanticIn) -- error(loc, "circular reference of typedef %s", tt->toChars()); -+ { error(loc, "circular reference of typedef %s", tt->toChars()); -+ return terror; -+ } - } - t = t->addMod(mod); - } -@@ -6820,14 +6908,11 @@ Type *TypeIdentifier::reliesOnTident(Tem - { - if (tparams) - { -- if (idents.dim == 0) -+ for (size_t i = 0; i < tparams->dim; i++) - { -- for (size_t i = 0; i < tparams->dim; i++) -- { TemplateParameter *tp = (*tparams)[i]; -- -- if (tp->ident->equals(ident)) -- return this; -- } -+ TemplateParameter *tp = (*tparams)[i]; -+ if (tp->ident->equals(ident)) -+ return this; - } - return NULL; - } -@@ -6840,8 +6925,18 @@ Expression *TypeIdentifier::toExpression - Expression *e = new IdentifierExp(loc, ident); - for (size_t i = 0; i < idents.dim; i++) - { -- Identifier *id = idents[i]; -- e = new DotIdExp(loc, e, id); -+ RootObject *id = idents[i]; -+ if (id->dyncast() == DYNCAST_IDENTIFIER) -+ { -+ e = new DotIdExp(loc, e, (Identifier *)id); -+ } -+ else -+ { -+ assert(id->dyncast() == DYNCAST_DSYMBOL); -+ TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance(); -+ assert(ti); -+ e = new DotTemplateInstanceExp(loc, e, ti->name, ti->tiargs); -+ } - } - - return e; -@@ -6882,7 +6977,7 @@ void TypeInstance::toCBuffer2(OutBuffer - toCBuffer2Helper(buf, hgs); - } - --void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) -+void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { - // Note close similarity to TypeIdentifier::resolve() - -@@ -6903,10 +6998,11 @@ void TypeInstance::resolve(Loc loc, Scop - //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars()); - s = tempinst; - if (s) -- { //printf("s = %s\n", s->toChars()); -+ { -+ //printf("s = %s\n", s->toChars()); - s->semantic(sc); - } -- resolveHelper(loc, sc, s, NULL, pe, pt, ps); -+ resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid); - if (*pt) - *pt = (*pt)->addMod(mod); - //printf("pt = '%s'\n", (*pt)->toChars()); -@@ -6919,23 +7015,23 @@ Type *TypeInstance::semantic(Loc loc, Sc - Dsymbol *s; - - //printf("TypeInstance::semantic(%p, %s)\n", this, toChars()); -- -- if (sc->parameterSpecialization) - { -- unsigned errors = global.startGagging(); -+ unsigned errors = global.errors; - resolve(loc, sc, &e, &t, &s); -- -- if (global.endGagging(errors)) -- { -- return this; -- } -+ // if we had an error evaluating the symbol, suppress further errors -+ if (!t && errors != global.errors) -+ return terror; - } -- else -- resolve(loc, sc, &e, &t, &s); - - if (!t) - { -- error(loc, "%s is used as a type", toChars()); -+ if (!e && s && s->errors) -+ { // if there was an error evaluating the symbol, it might actually -+ // be a type. Avoid misleading error messages. -+ error(loc, "%s had previous errors", toChars()); -+ } -+ else -+ error(loc, "%s is used as a type", toChars()); - t = terror; - } - return t; -@@ -6948,18 +7044,7 @@ Dsymbol *TypeInstance::toDsymbol(Scope * - Dsymbol *s; - - //printf("TypeInstance::semantic(%s)\n", toChars()); -- -- if (sc->parameterSpecialization) -- { -- unsigned errors = global.startGagging(); -- -- resolve(loc, sc, &e, &t, &s); -- -- if (global.endGagging(errors)) -- return NULL; -- } -- else -- resolve(loc, sc, &e, &t, &s); -+ resolve(loc, sc, &e, &t, &s); - - return s; - } -@@ -6991,6 +7076,28 @@ Type *TypeInstance::reliesOnTident(Templ - } - } - -+Expression *TypeInstance::toExpression() -+{ -+ Expression *e = new ScopeExp(loc, tempinst); -+ for (size_t i = 0; i < idents.dim; i++) -+ { -+ RootObject *id = idents[i]; -+ if (id->dyncast() == DYNCAST_IDENTIFIER) -+ { -+ e = new DotIdExp(loc, e, (Identifier *)id); -+ } -+ else -+ { -+ assert(id->dyncast() == DYNCAST_DSYMBOL); -+ TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance(); -+ assert(ti); -+ e = new DotTemplateInstanceExp(loc, e, ti->name, ti->tiargs); -+ } -+ } -+ -+ return e; -+} -+ - - /***************************** TypeTypeof *****************************/ - -@@ -7039,83 +7146,36 @@ void TypeTypeof::toCBuffer2(OutBuffer *b - toCBuffer2Helper(buf, hgs); - } - --Type *TypeTypeof::semantic(Loc loc, Scope *sc) -+void TypeTypeof::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { -- Type *t; -- -- //printf("TypeTypeof::semantic() %s\n", toChars()); -+ *pe = NULL; -+ *pt = NULL; -+ *ps = NULL; - -+ //printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars()); - //static int nest; if (++nest == 50) *(char*)0=0; - if (inuse) - { - inuse = 2; - error(loc, "circular typeof definition"); -- return Type::terror; -+ goto Lerr; - } - inuse++; - --#if 0 -- /* Special case for typeof(this) and typeof(super) since both -- * should work even if they are not inside a non-static member function -- */ -- if (exp->op == TOKthis || exp->op == TOKsuper) -- { -- // Find enclosing struct or class -- for (Dsymbol *s = sc->parent; 1; s = s->parent) -- { -- ClassDeclaration *cd; -- StructDeclaration *sd; -- -- if (!s) -- { -- error(loc, "%s is not in a struct or class scope", exp->toChars()); -- goto Lerr; -- } -- cd = s->isClassDeclaration(); -- if (cd) -- { -- if (exp->op == TOKsuper) -- { -- cd = cd->baseClass; -- if (!cd) -- { error(loc, "class %s has no 'super'", s->toChars()); -- goto Lerr; -- } -- } -- t = cd->type; -- break; -- } -- sd = s->isStructDeclaration(); -- if (sd) -- { -- if (exp->op == TOKsuper) -- { -- error(loc, "struct %s has no 'super'", sd->toChars()); -- goto Lerr; -- } -- t = sd->type->pointerTo(); -- break; -- } -- } -- } -- else --#endif -+ Type *t; - { - Scope *sc2 = sc->push(); -- sc2->intypeof++; -+ sc2->intypeof = 1; - sc2->speculative = true; - sc2->flags |= sc->flags & SCOPEstaticif; - unsigned oldspecgag = global.speculativeGag; - if (global.gag) - global.speculativeGag = global.gag; - exp = exp->semantic(sc2); -- global.speculativeGag = oldspecgag; -- - #if DMDV2 -- if (exp->type && exp->type->ty == Tfunction && -- ((TypeFunction *)exp->type)->isproperty) -- exp = resolveProperties(sc2, exp); -+ exp = resolvePropertiesOnly(sc2, exp); - #endif -+ global.speculativeGag = oldspecgag; - sc2->pop(); - if (exp->op == TOKtype) - { -@@ -7129,47 +7189,75 @@ Type *TypeTypeof::semantic(Loc loc, Scop - goto Lerr; - } - if (t->ty == Ttypeof) -- { error(loc, "forward reference to %s", toChars()); -+ { -+ error(loc, "forward reference to %s", toChars()); - goto Lerr; - } -- -- t = t->addMod(mod); -- -- /* typeof should reflect the true type, -- * not what 'auto' would have gotten us. -- */ -- //t = t->toHeadMutable(); - } -- if (idents.dim) -+ if (idents.dim == 0) -+ *pt = t; -+ else - { -- Dsymbol *s = t->toDsymbol(sc); -- for (size_t i = 0; i < idents.dim; i++) -- { -- if (!s) -- break; -- Identifier *id = idents[i]; -- s = s->searchX(loc, sc, id); -- } -- -- if (s) -+ if (Dsymbol *s = t->toDsymbol(sc)) -+ resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid); -+ else - { -- t = s->getType(); -- if (!t) -- { error(loc, "%s is not a type", s->toChars()); -- goto Lerr; -+ Expression *e = new TypeExp(loc, t); -+ for (size_t i = 0; i < idents.dim; i++) -+ { -+ RootObject *id = idents[i]; -+ switch (id->dyncast()) -+ { -+ case DYNCAST_IDENTIFIER: -+ e = new DotIdExp(loc, e, (Identifier *)id); -+ break; -+ case DYNCAST_DSYMBOL: -+ { -+ TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance(); -+ e = new DotExp(loc, e, new ScopeExp(loc, ti)); -+ break; -+ } -+ default: -+ assert(0); -+ } -+ } -+ e = e->semantic(sc); -+ if ((*ps = getDsymbol(e)) == NULL) -+ { -+ if (e->op == TOKtype) -+ *pt = e->type; -+ else -+ *pe = e; - } -- } -- else -- { error(loc, "cannot resolve .property for %s", toChars()); -- goto Lerr; - } - } -+ if (*pt) -+ (*pt) = (*pt)->addMod(mod); - inuse--; -- return t; -+ return; - - Lerr: -+ *pt = Type::terror; - inuse--; -- return terror; -+ return; -+} -+ -+Type *TypeTypeof::semantic(Loc loc, Scope *sc) -+{ -+ //printf("TypeTypeof::semantic() %s\n", toChars()); -+ -+ Expression *e; -+ Type *t; -+ Dsymbol *s; -+ resolve(loc, sc, &e, &t, &s); -+ if (s && (t = s->getType()) != NULL) -+ t = t->addMod(mod); -+ if (!t) -+ { -+ error(loc, "%s is used as a type", toChars()); -+ t = Type::terror; -+ } -+ return t; - } - - d_uns64 TypeTypeof::size(Loc loc) -@@ -7204,58 +7292,99 @@ Type *TypeReturn::syntaxCopy() - - Dsymbol *TypeReturn::toDsymbol(Scope *sc) - { -- Type *t = semantic(0, sc); -+ Type *t = semantic(Loc(), sc); - if (t == this) -- return NULL; -- return t->toDsymbol(sc); --} -- --Type *TypeReturn::semantic(Loc loc, Scope *sc) --{ -- Type *t; -- FuncDeclaration *func = sc->func; -- if (!func) -- { error(loc, "typeof(return) must be inside function"); -- goto Lerr; -- } -- if (func->fes) -- func = func->fes->func; -- -- t = func->type->nextOf(); -- if (!t) -- { -- error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc->func->toChars()); -- goto Lerr; -- } -- t = t->addMod(mod); -+ return NULL; -+ return t->toDsymbol(sc); -+} -+ -+void TypeReturn::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) -+{ -+ *pe = NULL; -+ *pt = NULL; -+ *ps = NULL; - -- if (idents.dim) -+ //printf("TypeReturn::resolve(sc = %p, idents = '%s')\n", sc, toChars()); -+ Type *t; - { -- Dsymbol *s = t->toDsymbol(sc); -- for (size_t i = 0; i < idents.dim; i++) -+ FuncDeclaration *func = sc->func; -+ if (!func) - { -- if (!s) -- break; -- Identifier *id = idents[i]; -- s = s->searchX(loc, sc, id); -+ error(loc, "typeof(return) must be inside function"); -+ goto Lerr; - } -- if (s) -+ if (func->fes) -+ func = func->fes->func; -+ -+ t = func->type->nextOf(); -+ if (!t) - { -- t = s->getType(); -- if (!t) -- { error(loc, "%s is not a type", s->toChars()); -- goto Lerr; -- } -+ error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc->func->toChars()); -+ goto Lerr; - } -+ } -+ if (idents.dim == 0) -+ *pt = t; -+ else -+ { -+ if (Dsymbol *s = t->toDsymbol(sc)) -+ resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid); - else -- { error(loc, "cannot resolve .property for %s", toChars()); -- goto Lerr; -+ { -+ Expression *e = new TypeExp(loc, t); -+ for (size_t i = 0; i < idents.dim; i++) -+ { -+ RootObject *id = idents[i]; -+ switch (id->dyncast()) -+ { -+ case DYNCAST_IDENTIFIER: -+ e = new DotIdExp(loc, e, (Identifier *)id); -+ break; -+ case DYNCAST_DSYMBOL: -+ { -+ TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance(); -+ e = new DotExp(loc, e, new ScopeExp(loc, ti)); -+ break; -+ } -+ default: -+ assert(0); -+ } -+ } -+ e = e->semantic(sc); -+ if ((*ps = getDsymbol(e)) == NULL) -+ { -+ if (e->op == TOKtype) -+ *pt = e->type; -+ else -+ *pe = e; -+ } - } - } -- return t; -+ if (*pt) -+ (*pt) = (*pt)->addMod(mod); -+ return; - - Lerr: -- return terror; -+ *pt = Type::terror; -+ return; -+} -+ -+Type *TypeReturn::semantic(Loc loc, Scope *sc) -+{ -+ //printf("TypeReturn::semantic() %s\n", toChars()); -+ -+ Expression *e; -+ Type *t; -+ Dsymbol *s; -+ resolve(loc, sc, &e, &t, &s); -+ if (s && (t = s->getType()) != NULL) -+ t = t->addMod(mod); -+ if (!t) -+ { -+ error(loc, "%s is used as a type", toChars()); -+ t = Type::terror; -+ } -+ return t; - } - - void TypeReturn::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) -@@ -7297,28 +7426,22 @@ Type *TypeEnum::syntaxCopy() - Type *TypeEnum::semantic(Loc loc, Scope *sc) - { - //printf("TypeEnum::semantic() %s\n", toChars()); -- //sym->semantic(sc); -+ if (deco) -+ return this; - return merge(); - } - - d_uns64 TypeEnum::size(Loc loc) - { -- if (!sym->memtype) -- { -- error(loc, "enum %s is forward referenced", sym->toChars()); -- return 4; -- } -- return sym->memtype->size(loc); -+ return sym->getMemtype(loc)->size(loc); - } - - unsigned TypeEnum::alignsize() - { -- if (!sym->memtype) -- { -- error(0, "enum %s is forward referenced", sym->toChars()); -+ Type *t = sym->getMemtype(Loc()); -+ if (t->ty == Terror) - return 4; -- } -- return sym->memtype->alignsize(); -+ return t->alignsize(); - } - - Dsymbol *TypeEnum::toDsymbol(Scope *sc) -@@ -7328,30 +7451,14 @@ Dsymbol *TypeEnum::toDsymbol(Scope *sc) - - Type *TypeEnum::toBasetype() - { -- if (sym->scope) -- { // Enum is forward referenced. We don't need to resolve the whole thing, -- // just the base type -- if (sym->memtype) -- { sym->memtype = sym->memtype->semantic(sym->loc, sym->scope); -- } -- else -- { if (!sym->isAnonymous()) -- sym->memtype = Type::tint32; -- } -- } -- if (!sym->memtype) -- { -- error(sym->loc, "enum %s is forward referenced", sym->toChars()); -- return tint32; -- } -- return sym->memtype->toBasetype(); -+ return sym->getMemtype(Loc())->toBasetype(); - } - - void TypeEnum::toDecoBuffer(OutBuffer *buf, int flag) - { - const char *name = sym->mangle(); - Type::toDecoBuffer(buf, flag); -- buf->printf("%s", name); -+ buf->writestring(name); - } - - void TypeEnum::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) -@@ -7363,7 +7470,7 @@ void TypeEnum::toCBuffer2(OutBuffer *buf - buf->writestring(sym->toChars()); - } - --Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); -@@ -7378,30 +7485,20 @@ Expression *TypeEnum::dotExp(Scope *sc, - !sym->memtype - ) - { -- return getProperty(e->loc, ident); -+ return getProperty(e->loc, ident, flag); - } -- return sym->memtype->dotExp(sc, e, ident); -+ return sym->getMemtype(Loc())->dotExp(sc, e, ident, flag); - } - EnumMember *m = s->isEnumMember(); -- Expression *em = m->value->copy(); -- em->loc = e->loc; -- return em; -+ return m->getVarExp(e->loc, sc); - } - --Expression *TypeEnum::getProperty(Loc loc, Identifier *ident) -+Expression *TypeEnum::getProperty(Loc loc, Identifier *ident, int flag) - { Expression *e; - -- if (ident == Id::max) -- { -- if (!sym->maxval) -- goto Lfwd; -- e = sym->maxval; -- } -- else if (ident == Id::min) -- { -- if (!sym->minval) -- goto Lfwd; -- e = sym->minval; -+ if (ident == Id::max || ident == Id::min) -+ { -+ return sym->getMaxMinValue(loc, ident); - } - else if (ident == Id::init) - { -@@ -7415,17 +7512,13 @@ Expression *TypeEnum::getProperty(Loc lo - } - else if (ident == Id::mangleof) - { -- e = Type::getProperty(loc, ident); -+ e = Type::getProperty(loc, ident, flag); - } - else - { -- e = toBasetype()->getProperty(loc, ident); -+ e = toBasetype()->getProperty(loc, ident, flag); - } - return e; -- --Lfwd: -- error(loc, "forward reference of %s.%s", toChars(), ident->toChars()); -- return new ErrorExp(); - } - - int TypeEnum::isintegral() -@@ -7463,6 +7556,11 @@ int TypeEnum::isscalar() - return sym->memtype->isscalar(); - } - -+int TypeEnum::isString() -+{ -+ return sym->memtype->isString(); -+} -+ - int TypeEnum::isAssignable() - { - return sym->memtype->isAssignable(); -@@ -7513,30 +7611,15 @@ Expression *TypeEnum::defaultInit(Loc lo - printf("TypeEnum::defaultInit() '%s'\n", toChars()); - #endif - // Initialize to first member of enum -- //printf("%s\n", sym->defaultval->type->toChars()); -- if (!sym->defaultval) -- { -- error(loc, "forward reference of %s.init", toChars()); -- return new ErrorExp(); -- } -- Expression *e = sym->defaultval; -+ Expression *e = sym->getDefaultValue(loc); - e = e->copy(); -- e->type = this; -+ e->type = this; // to deal with const, immutable, etc., variants - return e; - } - - int TypeEnum::isZeroInit(Loc loc) - { -- if (!sym->defaultval && sym->scope) -- { // Enum is forward referenced. We need to resolve the whole thing. -- sym->semantic(NULL); -- } -- if (!sym->defaultval) -- { -- error(loc, "enum %s is forward referenced", sym->toChars()); -- return 0; -- } -- return sym->defaultval->isBool(FALSE); -+ return sym->getDefaultValue(loc)->isBool(FALSE); - } - - int TypeEnum::hasPointers() -@@ -7544,6 +7627,17 @@ int TypeEnum::hasPointers() - return toBasetype()->hasPointers(); - } - -+Type *TypeEnum::nextOf() -+{ -+ if (sym->semanticRun == PASSinit) -+ { -+ assert(sym->scope); -+ sym->semantic(sym->scope); -+ } -+ assert(sym->memtype); -+ return sym->memtype->nextOf(); -+} -+ - /***************************** TypeTypedef *****************************/ - - TypeTypedef::TypeTypedef(TypedefDeclaration *sym) -@@ -7572,7 +7666,7 @@ Type *TypeTypedef::semantic(Loc loc, Sco - //printf("TypeTypedef::semantic(%s), sem = %d\n", toChars(), sym->sem); - int errors = global.errors; - sym->semantic(sc); -- if (errors != global.errors) -+ if (errors != global.errors || sym->errors || sym->basetype->ty == Terror) - return terror; - return merge(); - } -@@ -7596,7 +7690,7 @@ void TypeTypedef::toDecoBuffer(OutBuffer - { - Type::toDecoBuffer(buf, flag); - const char *name = sym->mangle(); -- buf->printf("%s", name); -+ buf->writestring(name); - } - - void TypeTypedef::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) -@@ -7609,16 +7703,16 @@ void TypeTypedef::toCBuffer2(OutBuffer * - buf->writestring(sym->toChars()); - } - --Expression *TypeTypedef::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeTypedef::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeTypedef::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); - #endif - if (ident == Id::init) - { -- return Type::dotExp(sc, e, ident); -+ return Type::dotExp(sc, e, ident, flag); - } -- return sym->basetype->dotExp(sc, e, ident); -+ return sym->basetype->dotExp(sc, e, ident, flag); - } - - structalign_t TypeTypedef::alignment() -@@ -7635,16 +7729,16 @@ structalign_t TypeTypedef::alignment() - return a; - } - --Expression *TypeTypedef::getProperty(Loc loc, Identifier *ident) -+Expression *TypeTypedef::getProperty(Loc loc, Identifier *ident, int flag) - { - #if LOGDOTEXP - printf("TypeTypedef::getProperty(ident = '%s') '%s'\n", ident->toChars(), toChars()); - #endif - if (ident == Id::init) - { -- return Type::getProperty(loc, ident); -+ return Type::getProperty(loc, ident, flag); - } -- return sym->basetype->getProperty(loc, ident); -+ return sym->basetype->getProperty(loc, ident, flag); - } - - int TypeTypedef::isintegral() -@@ -7788,7 +7882,13 @@ Expression *TypeTypedef::defaultInitLite - if (sym->init) - { - //sym->init->toExpression()->print(); -- return sym->init->toExpression(); -+ Expression *e = sym->init->toExpression(); -+ if (!e) -+ { -+ error(loc, "void initializer has no value"); -+ e = new ErrorExp(); -+ } -+ return e; - } - Type *bt = sym->basetype; - Expression *e = bt->defaultInitLiteral(loc); -@@ -7835,6 +7935,7 @@ TypeStruct::TypeStruct(StructDeclaration - : Type(Tstruct) - { - this->sym = sym; -+ this->att = RECfwdref; - } - - const char *TypeStruct::kind() -@@ -7879,7 +7980,7 @@ d_uns64 TypeStruct::size(Loc loc) - - unsigned TypeStruct::alignsize() - { -- sym->size(0); // give error for forward references -+ sym->size(Loc()); // give error for forward references - return sym->alignsize; - } - -@@ -7893,7 +7994,7 @@ void TypeStruct::toDecoBuffer(OutBuffer - const char *name = sym->mangle(); - //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name); - Type::toDecoBuffer(buf, flag); -- buf->printf("%s", name); -+ buf->writestring(name); - } - - void TypeStruct::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) -@@ -7909,12 +8010,11 @@ void TypeStruct::toCBuffer2(OutBuffer *b - buf->writestring(sym->toChars()); - } - --Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - VarDeclaration *v; - Dsymbol *s; - DotVarExp *de; -- Declaration *d; - - #if LOGDOTEXP - printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); -@@ -7937,31 +8037,36 @@ Expression *TypeStruct::dotExp(Scope *sc - Expressions *exps = new Expressions; - exps->reserve(sym->fields.dim); - -- Expression *ev = e; -+ Expression *e0 = NULL; -+ Expression *ev = e->op == TOKtype ? NULL : e; -+ if (sc->func && ev && ev->hasSideEffect()) -+ { -+ Identifier *id = Lexer::uniqueId("__tup"); -+ ExpInitializer *ei = new ExpInitializer(e->loc, ev); -+ VarDeclaration *vd = new VarDeclaration(e->loc, NULL, id, ei); -+ vd->storage_class |= STCctfe | STCref | STCforeach; -+ -+ e0 = new DeclarationExp(e->loc, vd); -+ ev = new VarExp(e->loc, vd); -+ } - for (size_t i = 0; i < sym->fields.dim; i++) -- { VarDeclaration *v = sym->fields[i]; -- Expression *fe; -- if (i == 0 && sc->func && sym->fields.dim > 1 && -- e->hasSideEffect()) -- { -- Identifier *id = Lexer::uniqueId("__tup"); -- ExpInitializer *ei = new ExpInitializer(e->loc, e); -- VarDeclaration *vd = new VarDeclaration(e->loc, NULL, id, ei); -- vd->storage_class |= STCctfe | STCref | STCforeach; -- -- ev = new VarExp(e->loc, vd); -- fe = new CommaExp(e->loc, new DeclarationExp(e->loc, vd), ev); -- fe = new DotVarExp(e->loc, fe, v); -- } -+ { -+ VarDeclaration *v = sym->fields[i]; -+ Expression *ex; -+ if (ev) -+ ex = new DotVarExp(e->loc, ev, v); - else -- fe = new DotVarExp(ev->loc, ev, v); -- exps->push(fe); -+ { -+ ex = new VarExp(e->loc, v); -+ ex->type = ex->type->addMod(e->type->mod); -+ } -+ exps->push(ex); - } -- e = new TupleExp(e->loc, exps); -- sc = sc->push(); -- sc->noaccesscheck = 1; -- e = e->semantic(sc); -- sc->pop(); -+ e = new TupleExp(e->loc, e0, exps); -+ Scope *sc2 = sc->push(); -+ sc2->flags = sc->flags | SCOPEnoaccesscheck; -+ e = e->semantic(sc2); -+ sc2->pop(); - return e; - } - -@@ -7988,25 +8093,24 @@ L1: - { - sym->semantic(NULL); - s = sym->search(e->loc, ident, 0); -- if (!s) -- return noMember(sc, e, ident); - } -- else -- return noMember(sc, e, ident); -+ if (!s) -+ return noMember(sc, e, ident, flag); - } - if (!s->isFuncDeclaration()) // because of overloading - s->checkDeprecated(e->loc, sc); - s = s->toAlias(); - - v = s->isVarDeclaration(); -- if (v && !v->isDataseg()) -+ if (v && v->inuse && (!v->type || !v->type->deco)) // Bugzilla 9494 -+ { e->error("circular reference to '%s'", v->toPrettyChars()); -+ return new ErrorExp(); -+ } -+ if (v && !v->isDataseg() && (v->storage_class & STCmanifest)) - { -- Expression *ei = v->getConstInitializer(); -- if (ei) -- { e = ei->copy(); // need to copy it if it's a StringExp -- e = e->semantic(sc); -- return e; -- } -+ Expression *ve = new VarExp(e->loc, v); -+ ve = ve->semantic(sc); -+ return ve; - } - - if (s->getType()) -@@ -8017,8 +8121,7 @@ L1: - EnumMember *em = s->isEnumMember(); - if (em) - { -- assert(em->value); -- return em->value->copy(); -+ return em->getVarExp(e->loc, sc); - } - - TemplateMixin *tm = s->isTemplateMixin(); -@@ -8032,7 +8135,10 @@ L1: - TemplateDeclaration *td = s->isTemplateDeclaration(); - if (td) - { -- e = new DotTemplateExp(e->loc, e, td); -+ if (e->op == TOKtype) -+ e = new ScopeExp(e->loc, td); -+ else -+ e = new DotTemplateExp(e->loc, e, td); - e = e->semantic(sc); - return e; - } -@@ -8063,13 +8169,13 @@ L1: - OverloadSet *o = s->isOverloadSet(); - if (o) - { -- OverExp *oe = new OverExp(o); -+ OverExp *oe = new OverExp(e->loc, o); - if (e->op == TOKtype) - return oe; - return new DotExp(e->loc, e, oe); - } - -- d = s->isDeclaration(); -+ Declaration *d = s->isDeclaration(); - #ifdef DEBUG - if (!d) - printf("d = %s '%s'\n", s->kind(), s->toChars()); -@@ -8077,19 +8183,27 @@ L1: - assert(d); - - if (e->op == TOKtype) -- { FuncDeclaration *fd = sc->func; -- -- if (d->isTupleDeclaration()) -+ { -+ /* It's: -+ * Struct.d -+ */ -+ if (TupleDeclaration *tup = d->isTupleDeclaration()) - { -- e = new TupleExp(e->loc, d->isTupleDeclaration()); -+ e = new TupleExp(e->loc, tup); - e = e->semantic(sc); - return e; - } -- else if (d->needThis() && fd && fd->vthis) -+ if (d->needThis() && sc->intypeof != 1) - { -- e = new DotVarExp(e->loc, new ThisExp(e->loc), d); -- e = e->semantic(sc); -- return e; -+ /* Rewrite as: -+ * this.d -+ */ -+ if (hasThis(sc)) -+ { -+ e = new DotVarExp(e->loc, new ThisExp(e->loc), d); -+ e = e->semantic(sc); -+ return e; -+ } - } - accessCheck(e->loc, sc, e, d); - VarExp *ve = new VarExp(e->loc, d, 1); -@@ -8098,14 +8212,13 @@ L1: - return ve; - } - -- if (d->isDataseg()) -+ bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField(); -+ if (d->isDataseg() || unreal && d->isField()) - { - // (e, d) -- VarExp *ve; -- - accessCheck(e->loc, sc, e, d); -- ve = new VarExp(e->loc, d); -- e = new CommaExp(e->loc, e, ve); -+ Expression *ve = new VarExp(e->loc, d); -+ e = unreal ? ve : new CommaExp(e->loc, e, ve); - e = e->semantic(sc); - return e; - } -@@ -8135,7 +8248,7 @@ L1: - structalign_t TypeStruct::alignment() - { - if (sym->alignment == 0) -- sym->size(0); -+ sym->size(Loc()); - return sym->alignment; - } - -@@ -8144,8 +8257,7 @@ Expression *TypeStruct::defaultInit(Loc - #if LOGDEFAULTINIT - printf("TypeStruct::defaultInit() '%s'\n", toChars()); - #endif -- Symbol *s = sym->toInitializer(); -- Declaration *d = new SymbolDeclaration(sym->loc, s, sym); -+ Declaration *d = new SymbolDeclaration(sym->loc, sym); - assert(d); - d->type = this; - return new VarExp(sym->loc, d); -@@ -8163,25 +8275,27 @@ Expression *TypeStruct::defaultInitLiter - //if (sym->isNested()) - // return defaultInit(loc); - Expressions *structelems = new Expressions(); -- structelems->setDim(sym->fields.dim - sym->isnested); -+ structelems->setDim(sym->fields.dim - sym->isNested()); -+ unsigned offset = 0; - for (size_t j = 0; j < structelems->dim; j++) - { - VarDeclaration *vd = sym->fields[j]; -- Type *telem = vd->type->addMod(this->mod); - Expression *e; -- if (vd->init) -- { if (vd->init->isVoidInitializer()) -+ if (vd->offset < offset) -+ e = NULL; -+ else if (vd->init) -+ { -+ if (vd->init->isVoidInitializer()) - e = NULL; - else -- e = vd->init->toExpression(); -+ e = vd->getConstInitializer(false); - } - else - e = vd->type->defaultInitLiteral(loc); -- if (e && vd->scope) -- { -- e = e->semantic(vd->scope); -- e = e->implicitCastTo(vd->scope, telem); -- } -+ if (e && e->op == TOKerror) -+ return e; -+ if (e) -+ offset = vd->offset + vd->type->size(); - (*structelems)[j] = e; - } - StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems); -@@ -8214,7 +8328,7 @@ int TypeStruct::needsDestruction() - - bool TypeStruct::needsNested() - { -- if (sym->isnested) -+ if (sym->isNested()) - return true; - - for (size_t i = 0; i < sym->fields.dim; i++) -@@ -8267,7 +8381,7 @@ int TypeStruct::hasPointers() - // Probably should cache this information in sym rather than recompute - StructDeclaration *s = sym; - -- sym->size(0); // give error for forward references -+ sym->size(Loc()); // give error for forward references - for (size_t i = 0; i < s->fields.dim; i++) - { - Dsymbol *sm = s->fields[i]; -@@ -8296,26 +8410,40 @@ MATCH TypeStruct::implicitConvTo(Type *t - } - - if (ty == to->ty && sym == ((TypeStruct *)to)->sym) -- { m = MATCHexact; // exact match -+ { -+ m = MATCHexact; // exact match - if (mod != to->mod) - { - m = MATCHconst; - if (MODimplicitConv(mod, to->mod)) - ; - else -- { /* Check all the fields. If they can all be converted, -+ { -+ /* Check all the fields. If they can all be converted, - * allow the conversion. - */ -+ unsigned offset; - for (size_t i = 0; i < sym->fields.dim; i++) -- { Dsymbol *s = sym->fields[i]; -- VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -+ { -+ VarDeclaration *v = sym->fields[i]; -+ if (i == 0) -+ ; -+ else if (v->offset == offset) -+ { -+ if (m) -+ continue; -+ } -+ else -+ { -+ if (!m) -+ return m; -+ } - - // 'from' type - Type *tvf = v->type->addMod(mod); - - // 'to' type -- Type *tv = v->type->castMod(to->mod); -+ Type *tv = v->type->addMod(to->mod); - - // field match - MATCH mf = tvf->implicitConvTo(tv); -@@ -8325,12 +8453,17 @@ MATCH TypeStruct::implicitConvTo(Type *t - return mf; - if (mf < m) // if field match is worse - m = mf; -+ offset = v->offset; - } - } - } - } -- else if (sym->aliasthis) -+ else if (sym->aliasthis && !(att & RECtracing)) -+ { -+ att = (AliasThisRec)(att | RECtracing); - m = aliasthisOf()->implicitConvTo(to); -+ att = (AliasThisRec)(att & ~RECtracing); -+ } - else - m = MATCHnomatch; // no match - return m; -@@ -8351,13 +8484,16 @@ unsigned TypeStruct::wildConvTo(Type *tp - if (ty == tprm->ty && sym == ((TypeStruct *)tprm)->sym) - return Type::wildConvTo(tprm); - -- if (sym->aliasthis) -- { Type *t = aliasthisOf(); -- assert(t); -- return t->wildConvTo(tprm); -+ unsigned mod = 0; -+ -+ if (sym->aliasthis && !(att & RECtracing)) -+ { -+ att = (AliasThisRec)(att | RECtracing); -+ mod = aliasthisOf()->wildConvTo(tprm); -+ att = (AliasThisRec)(att & ~RECtracing); - } - -- return 0; -+ return mod; - } - - Type *TypeStruct::toHeadMutable() -@@ -8372,6 +8508,7 @@ TypeClass::TypeClass(ClassDeclaration *s - : Type(Tclass) - { - this->sym = sym; -+ this->att = RECfwdref; - } - - const char *TypeClass::kind() -@@ -8415,7 +8552,7 @@ void TypeClass::toDecoBuffer(OutBuffer * - const char *name = sym->mangle(); - //printf("TypeClass::toDecoBuffer('%s' flag=%d mod=%x) = '%s'\n", toChars(), flag, mod, name); - Type::toDecoBuffer(buf, flag); -- buf->printf("%s", name); -+ buf->writestring(name); - } - - void TypeClass::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) -@@ -8427,7 +8564,7 @@ void TypeClass::toCBuffer2(OutBuffer *bu - buf->writestring(sym->toChars()); - } - --Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident) -+Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) - { - VarDeclaration *v; - Dsymbol *s; -@@ -8469,34 +8606,39 @@ Expression *TypeClass::dotExp(Scope *sc, - Expressions *exps = new Expressions; - exps->reserve(sym->fields.dim); - -- Expression *ev = e; -+ Expression *e0 = NULL; -+ Expression *ev = e->op == TOKtype ? NULL : e; -+ if (sc->func && ev && ev->hasSideEffect()) -+ { -+ Identifier *id = Lexer::uniqueId("__tup"); -+ ExpInitializer *ei = new ExpInitializer(e->loc, ev); -+ VarDeclaration *vd = new VarDeclaration(e->loc, NULL, id, ei); -+ vd->storage_class |= STCctfe | STCref | STCforeach; -+ -+ e0 = new DeclarationExp(e->loc, vd); -+ ev = new VarExp(e->loc, vd); -+ } - for (size_t i = 0; i < sym->fields.dim; i++) -- { VarDeclaration *v = sym->fields[i]; -+ { -+ VarDeclaration *v = sym->fields[i]; - // Don't include hidden 'this' pointer - if (v->isThisDeclaration()) - continue; -- Expression *fe; -- if (i == 0 && sc->func && sym->fields.dim > 1 && -- e->hasSideEffect()) -- { -- Identifier *id = Lexer::uniqueId("__tup"); -- ExpInitializer *ei = new ExpInitializer(e->loc, e); -- VarDeclaration *vd = new VarDeclaration(e->loc, NULL, id, ei); -- vd->storage_class |= STCctfe | STCref | STCforeach; -- -- ev = new VarExp(e->loc, vd); -- fe = new CommaExp(e->loc, new DeclarationExp(e->loc, vd), ev); -- fe = new DotVarExp(e->loc, fe, v); -- } -+ Expression *ex; -+ if (ev) -+ ex = new DotVarExp(e->loc, ev, v); - else -- fe = new DotVarExp(e->loc, ev, v); -- exps->push(fe); -+ { -+ ex = new VarExp(e->loc, v); -+ ex->type = ex->type->addMod(e->type->mod); -+ } -+ exps->push(ex); - } -- e = new TupleExp(e->loc, exps); -- sc = sc->push(); -- sc->noaccesscheck = 1; -- e = e->semantic(sc); -- sc->pop(); -+ e = new TupleExp(e->loc, e0, exps); -+ Scope *sc2 = sc->push(); -+ sc2->flags = sc->flags | SCOPEnoaccesscheck; -+ e = e->semantic(sc2); -+ sc2->pop(); - return e; - } - -@@ -8505,34 +8647,27 @@ L1: - if (!s) - { - // See if it's 'this' class or a base class -- if (e->op != TOKtype) -+ if (sym->ident == ident) - { -- if (sym->ident == ident) -- { -- e = new DotTypeExp(0, e, sym); -- return e; -- } -- -- ClassDeclaration *cbase = sym->searchBase(e->loc, ident); -- if (cbase) -- { -- if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration()) -- { -- e = new CastExp(0, e, ifbase->type); -- return e; -- } -- else -- { -- e = new DotTypeExp(0, e, cbase); -- return e; -- } -- } -+ if (e->op == TOKtype) -+ return Type::getProperty(e->loc, ident, 0); -+ return new DotTypeExp(e->loc, e, sym); -+ } -+ if (ClassDeclaration *cbase = sym->searchBase(e->loc, ident)) -+ { -+ if (e->op == TOKtype) -+ return Type::getProperty(e->loc, ident, 0); -+ if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration()) -+ e = new CastExp(e->loc, e, ifbase->type); -+ else -+ e = new DotTypeExp(e->loc, e, cbase); -+ return e; - } - - if (ident == Id::classinfo) - { -- assert(ClassDeclaration::classinfo); -- Type *t = ClassDeclaration::classinfo->type; -+ assert(Type::typeinfoclass); -+ Type *t = Type::typeinfoclass->type; - if (e->op == TOKtype || e->op == TOKdottype) - { - /* For type.classinfo, we know the classinfo -@@ -8578,7 +8713,7 @@ L1: - { /* The pointer to the vtbl[] - * *cast(invariant(void*)**)e - */ -- e = e->castTo(sc, tvoidptr->invariantOf()->pointerTo()->pointerTo()); -+ e = e->castTo(sc, tvoidptr->immutableOf()->pointerTo()->pointerTo()); - e = new PtrExp(e->loc, e); - e = e->semantic(sc); - return e; -@@ -8606,21 +8741,23 @@ L1: - } - else - { -- return noMember(sc, e, ident); -+ return noMember(sc, e, ident, flag); - } - } - if (!s->isFuncDeclaration()) // because of overloading - s->checkDeprecated(e->loc, sc); - s = s->toAlias(); -- v = s->isVarDeclaration(); -- if (v && !v->isDataseg()) -- { Expression *ei = v->getConstInitializer(); - -- if (ei) -- { e = ei->copy(); // need to copy it if it's a StringExp -- e = e->semantic(sc); -- return e; -- } -+ v = s->isVarDeclaration(); -+ if (v && v->inuse && (!v->type || !v->type->deco)) // Bugzilla 9494 -+ { e->error("circular reference to '%s'", v->toPrettyChars()); -+ return new ErrorExp(); -+ } -+ if (v && !v->isDataseg() && (v->storage_class & STCmanifest)) -+ { -+ Expression *ve = new VarExp(e->loc, v); -+ ve = ve->semantic(sc); -+ return ve; - } - - if (s->getType()) -@@ -8631,8 +8768,7 @@ L1: - EnumMember *em = s->isEnumMember(); - if (em) - { -- assert(em->value); -- return em->value->copy(); -+ return em->getVarExp(e->loc, sc); - } - - TemplateMixin *tm = s->isTemplateMixin(); -@@ -8646,7 +8782,10 @@ L1: - TemplateDeclaration *td = s->isTemplateDeclaration(); - if (td) - { -- e = new DotTemplateExp(e->loc, e, td); -+ if (e->op == TOKtype) -+ e = new ScopeExp(e->loc, td); -+ else -+ e = new DotTemplateExp(e->loc, e, td); - e = e->semantic(sc); - return e; - } -@@ -8677,7 +8816,7 @@ L1: - OverloadSet *o = s->isOverloadSet(); - if (o) - { -- OverExp *oe = new OverExp(o); -+ OverExp *oe = new OverExp(e->loc, o); - if (e->op == TOKtype) - return oe; - return new DotExp(e->loc, e, oe); -@@ -8695,30 +8834,27 @@ L1: - /* It's: - * Class.d - */ -- if (d->isTupleDeclaration()) -- { -- e = new TupleExp(e->loc, d->isTupleDeclaration()); -- e = e->semantic(sc); -- return e; -- } - -- #if 1 // Workaround for Bugzilla 9213 -- FuncDeclaration *fd = sc->func; -- if (d->needThis() && d->isVarDeclaration() && fd && fd->vthis) -+ // If Class is in a failed template, return an error -+ TemplateInstance *tiparent = d->inTemplateInstance(); -+ if (tiparent && tiparent->errors) -+ return new ErrorExp(); -+ -+ if (TupleDeclaration *tup = d->isTupleDeclaration()) - { -- e = new DotVarExp(e->loc, new ThisExp(e->loc), d); -+ e = new TupleExp(e->loc, tup); - e = e->semantic(sc); - return e; - } -- #endif -- -- FuncDeclaration *fdthis = hasThis(sc); -- if (d->needThis() && fdthis) -+ if (d->needThis() && sc->intypeof != 1) - { -- if (d->isFuncDeclaration()) -+ /* Rewrite as: -+ * this.d -+ */ -+ if (hasThis(sc)) - { - // This is almost same as getRightThis() in expression.c -- Expression *e1 = new VarExp(e->loc, fdthis->vthis); -+ Expression *e1 = new ThisExp(e->loc); - e1 = e1->semantic(sc); - L2: - Type *t = e1->type->toBasetype(); -@@ -8773,16 +8909,8 @@ L1: - goto L2; - } - } -- else -- { -- /* Rewrite as: -- * this.d -- */ -- DotVarExp *de = new DotVarExp(e->loc, new ThisExp(e->loc), d); -- e = de->semantic(sc); -- return e; -- } - } -+ //printf("e = %s, d = %s\n", e->toChars(), d->toChars()); - accessCheck(e->loc, sc, e, d); - VarExp *ve = new VarExp(e->loc, d, 1); - if (d->isVarDeclaration() && d->needThis()) -@@ -8790,14 +8918,13 @@ L1: - return ve; - } - -- if (d->isDataseg()) -+ bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField(); -+ if (d->isDataseg() || unreal && d->isField()) - { - // (e, d) -- VarExp *ve; -- - accessCheck(e->loc, sc, e, d); -- ve = new VarExp(e->loc, d); -- e = new CommaExp(e->loc, e, ve); -+ Expression *ve = new VarExp(e->loc, d); -+ e = unreal ? ve : new CommaExp(e->loc, e, ve); - e = e->semantic(sc); - return e; - } -@@ -8849,22 +8976,21 @@ MATCH TypeClass::implicitConvTo(Type *to - { - if (cdto->scope) - cdto->semantic(NULL); -+ if (sym->scope) -+ sym->semantic(NULL); - if (cdto->isBaseOf(sym, NULL) && MODimplicitConv(mod, to->mod)) - { //printf("'to' is base\n"); - return MATCHconvert; - } - } - -- if (global.params.Dversion == 1) -- { -- // Allow conversion to (void *) -- if (to->ty == Tpointer && ((TypePointer *)to)->next->ty == Tvoid) -- return MATCHconvert; -- } -- - m = MATCHnomatch; -- if (sym->aliasthis) -+ if (sym->aliasthis && !(att & RECtracing)) -+ { -+ att = (AliasThisRec)(att | RECtracing); - m = aliasthisOf()->implicitConvTo(to); -+ att = (AliasThisRec)(att & ~RECtracing); -+ } - - return m; - } -@@ -8880,7 +9006,7 @@ MATCH TypeClass::constConv(Type *to) - /* Conversion derived to const(base) - */ - int offset = 0; -- if (to->isBaseOf(this, &offset) && offset == 0 && !to->isMutable()) -+ if (to->isBaseOf(this, &offset) && offset == 0 && !to->isMutable() && !to->isWild()) - return MATCHconvert; - - return MATCHnomatch; -@@ -8897,10 +9023,16 @@ unsigned TypeClass::wildConvTo(Type *tpr - if (cdprm && cdprm->isBaseOf(sym, NULL)) - return Type::wildConvTo(tprm); - -- if (sym->aliasthis) -- return aliasthisOf()->wildConvTo(tprm); -+ unsigned mod = 0; - -- return 0; -+ if (sym->aliasthis && !(att & RECtracing)) -+ { -+ att = (AliasThisRec)(att | RECtracing); -+ mod = aliasthisOf()->wildConvTo(tprm); -+ att = (AliasThisRec)(att & ~RECtracing); -+ } -+ -+ return mod; - } - - Type *TypeClass::toHeadMutable() -@@ -9025,31 +9157,28 @@ Type *TypeTuple::semantic(Loc loc, Scope - return this; - } - --int TypeTuple::equals(Object *o) --{ Type *t; -- -- t = (Type *)o; -+bool TypeTuple::equals(RootObject *o) -+{ -+ Type *t = (Type *)o; - //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars()); - if (this == t) -- { -- return 1; -- } -+ return true; - if (t->ty == Ttuple) -- { TypeTuple *tt = (TypeTuple *)t; -- -+ { -+ TypeTuple *tt = (TypeTuple *)t; - if (arguments->dim == tt->arguments->dim) - { - for (size_t i = 0; i < tt->arguments->dim; i++) -- { Parameter *arg1 = (*arguments)[i]; -+ { -+ Parameter *arg1 = (*arguments)[i]; - Parameter *arg2 = (*tt->arguments)[i]; -- - if (!arg1->type->equals(arg2->type)) -- return 0; -+ return false; - } -- return 1; -+ return true; - } - } -- return 0; -+ return false; - } - - Type *TypeTuple::reliesOnTident(TemplateParameters *tparams) -@@ -9095,12 +9224,13 @@ void TypeTuple::toDecoBuffer(OutBuffer * - //printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars()); - Type::toDecoBuffer(buf, flag); - OutBuffer buf2; -+ buf2.reserve(32); - Parameter::argsToDecoBuffer(&buf2, arguments); - int len = (int)buf2.offset; - buf->printf("%d%.*s", len, len, (char *)buf2.extractData()); - } - --Expression *TypeTuple::getProperty(Loc loc, Identifier *ident) -+Expression *TypeTuple::getProperty(Loc loc, Identifier *ident, int flag) - { Expression *e; - - #if LOGDOTEXP -@@ -9114,6 +9244,10 @@ Expression *TypeTuple::getProperty(Loc l - { - e = defaultInitLiteral(loc); - } -+ else if (flag) -+ { -+ e = NULL; -+ } - else - { - error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars()); -@@ -9200,17 +9334,19 @@ Type *TypeSlice::semantic(Loc loc, Scope - return t; - } - --void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) -+void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid) - { -- next->resolve(loc, sc, pe, pt, ps); -+ next->resolve(loc, sc, pe, pt, ps, intypeid); - if (*pe) -- { // It's really a slice expression -- Expression *e; -- e = new SliceExp(loc, *pe, lwr, upr); -- *pe = e; -+ { -+ // It's really a slice expression -+ if (Dsymbol *s = getDsymbol(*pe)) -+ *pe = new DsymbolExp(loc, s, 1); -+ *pe = new SliceExp(loc, *pe, lwr, upr); - } - else if (*ps) -- { Dsymbol *s = *ps; -+ { -+ Dsymbol *s = *ps; - TupleDeclaration *td = s->isTupleDeclaration(); - if (td) - { -@@ -9219,19 +9355,20 @@ void TypeSlice::resolve(Loc loc, Scope * - ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td); - sym->parent = sc->scopesym; - sc = sc->push(sym); -- -+ sc = sc->startCTFE(); - lwr = lwr->semantic(sc); -- lwr = lwr->ctfeInterpret(); -- uinteger_t i1 = lwr->toUInteger(); -- - upr = upr->semantic(sc); -+ sc = sc->endCTFE(); -+ sc = sc->pop(); -+ -+ lwr = lwr->ctfeInterpret(); - upr = upr->ctfeInterpret(); -+ uinteger_t i1 = lwr->toUInteger(); - uinteger_t i2 = upr->toUInteger(); - -- sc = sc->pop(); -- - if (!(i1 <= i2 && i2 <= td->objects->dim)) -- { error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim); -+ { -+ error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim); - goto Ldefault; - } - -@@ -9260,7 +9397,7 @@ void TypeSlice::resolve(Loc loc, Scope * - else - { - Ldefault: -- Type::resolve(loc, sc, pe, pt, ps); -+ Type::resolve(loc, sc, pe, pt, ps, intypeid); - } - } - -@@ -9272,8 +9409,11 @@ void TypeSlice::toCBuffer2(OutBuffer *bu - } - next->toCBuffer2(buf, hgs, this->mod); - -- buf->printf("[%s .. ", lwr->toChars()); -- buf->printf("%s]", upr->toChars()); -+ buf->writeByte('['); -+ sizeToCBuffer(buf, hgs, lwr); -+ buf->writestring(" .. "); -+ sizeToCBuffer(buf, hgs, upr); -+ buf->writeByte(']'); - } - - /***************************** TypeNull *****************************/ -@@ -9333,10 +9473,7 @@ void TypeNull::toCBuffer(OutBuffer *buf, - } - - d_uns64 TypeNull::size(Loc loc) { return tvoidptr->size(loc); } --//Expression *TypeNull::getProperty(Loc loc, Identifier *ident) { return new ErrorExp(); } --//Expression *TypeNull::dotExp(Scope *sc, Expression *e, Identifier *ident) { return new ErrorExp(); } --Expression *TypeNull::defaultInit(Loc loc) { return new NullExp(0, Type::tnull); } --//Expression *TypeNull::defaultInitLiteral(Loc loc) { return new ErrorExp(); } -+Expression *TypeNull::defaultInit(Loc loc) { return new NullExp(Loc(), Type::tnull); } - - /***************************** Parameter *****************************/ - -@@ -9376,12 +9513,14 @@ Parameters *Parameter::arraySyntaxCopy(P - - char *Parameter::argsTypesToChars(Parameters *args, int varargs) - { -- OutBuffer *buf = new OutBuffer(); -+ OutBuffer buf; -+ buf.reserve(16); - - HdrGenState hgs; -- argsToCBuffer(buf, &hgs, args, varargs); -+ argsToCBuffer(&buf, &hgs, args, varargs); - -- return buf->toChars(); -+ buf.writebyte(0); -+ return buf.extractData(); - } - - void Parameter::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *arguments, int varargs) -@@ -9390,6 +9529,7 @@ void Parameter::argsToCBuffer(OutBuffer - if (arguments) - { - OutBuffer argbuf; -+ argbuf.reserve(32); - - size_t dim = Parameter::dim(arguments); - for (size_t i = 0; i < dim; i++) -@@ -9404,8 +9544,7 @@ void Parameter::argsToCBuffer(OutBuffer - if (arg->storageClass & STCout) - buf->writestring("out "); - else if (arg->storageClass & STCref) -- buf->writestring((global.params.Dversion == 1) -- ? "inout " : "ref "); -+ buf->writestring("ref "); - else if (arg->storageClass & STCin) - buf->writestring("in "); - else if (arg->storageClass & STClazy) ---- a/src/gcc/d/dfrontend/mtype.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/mtype.h 2014-04-01 16:32:51.000000000 +0100 -@@ -22,34 +22,33 @@ - #include "expression.h" - - struct Scope; --struct Identifier; --struct Expression; --struct StructDeclaration; --struct ClassDeclaration; --struct VarDeclaration; --struct EnumDeclaration; --struct TypedefDeclaration; --struct TypeInfoDeclaration; --struct Dsymbol; --struct TemplateInstance; -+class Identifier; -+class Expression; -+class StructDeclaration; -+class ClassDeclaration; -+class VarDeclaration; -+class EnumDeclaration; -+class TypedefDeclaration; -+class TypeInfoDeclaration; -+class Dsymbol; -+class TemplateInstance; - struct CppMangleState; --struct TemplateDeclaration; -+class TemplateDeclaration; - struct JsonOut; - enum LINK; - --struct TypeBasic; -+class TypeBasic; - struct HdrGenState; --struct Parameter; -+class Parameter; - - // Back end - #ifdef IN_GCC --typedef union tree_node TYPE; --typedef TYPE type; -+typedef union tree_node type; - #else - typedef struct TYPE type; - #endif - struct Symbol; --struct TypeTuple; -+class TypeTuple; - - enum ENUMTY - { -@@ -112,20 +111,22 @@ extern int Tsize_t; - extern int Tptrdiff_t; - - --struct Type : Object -+/* pick this order of numbers so switch statements work better -+ */ -+#define MODconst 1 // type is const -+#define MODimmutable 4 // type is immutable -+#define MODshared 2 // type is shared -+#define MODwild 8 // type is wild -+#define MODmutable 0x10 // type is mutable (only used in wildcard matching) -+ -+class Type : public RootObject - { -+public: - TY ty; - unsigned char mod; // modifiers MODxxxx -- /* pick this order of numbers so switch statements work better -- */ -- #define MODconst 1 // type is const -- #define MODimmutable 4 // type is immutable -- #define MODshared 2 // type is shared -- #define MODwild 8 // type is wild -- #define MODmutable 0x10 // type is mutable (only used in wildcard matching) - char *deco; - -- /* These are cached values that are lazily evaluated by constOf(), invariantOf(), etc. -+ /* These are cached values that are lazily evaluated by constOf(), immutableOf(), etc. - * They should not be referenced by anybody but mtype.c. - * They can be NULL if not lazily evaluated yet. - * Note that there is no "shared immutable", because that is just immutable -@@ -146,51 +147,49 @@ struct Type : Object - - type *ctype; // for back end - -- #define tvoid basic[Tvoid] -- #define tint8 basic[Tint8] -- #define tuns8 basic[Tuns8] -- #define tint16 basic[Tint16] -- #define tuns16 basic[Tuns16] -- #define tint32 basic[Tint32] -- #define tuns32 basic[Tuns32] -- #define tint64 basic[Tint64] -- #define tuns64 basic[Tuns64] -- #define tint128 basic[Tint128] -- #define tuns128 basic[Tuns128] -- #define tfloat32 basic[Tfloat32] -- #define tfloat64 basic[Tfloat64] -- #define tfloat80 basic[Tfloat80] -- -- #define timaginary32 basic[Timaginary32] -- #define timaginary64 basic[Timaginary64] -- #define timaginary80 basic[Timaginary80] -- -- #define tcomplex32 basic[Tcomplex32] -- #define tcomplex64 basic[Tcomplex64] -- #define tcomplex80 basic[Tcomplex80] -- -- #define tbool basic[Tbool] -- #define tchar basic[Tchar] -- #define twchar basic[Twchar] -- #define tdchar basic[Tdchar] -+ static Type *tvoid; -+ static Type *tint8; -+ static Type *tuns8; -+ static Type *tint16; -+ static Type *tuns16; -+ static Type *tint32; -+ static Type *tuns32; -+ static Type *tint64; -+ static Type *tuns64; -+ static Type *tint128; -+ static Type *tuns128; -+ static Type *tfloat32; -+ static Type *tfloat64; -+ static Type *tfloat80; -+ -+ static Type *timaginary32; -+ static Type *timaginary64; -+ static Type *timaginary80; -+ -+ static Type *tcomplex32; -+ static Type *tcomplex64; -+ static Type *tcomplex80; -+ -+ static Type *tbool; -+ static Type *tchar; -+ static Type *twchar; -+ static Type *tdchar; - - // Some special types -- #define tshiftcnt tint32 // right side of shift expression --// #define tboolean tint32 // result of boolean expression -- #define tboolean tbool // result of boolean expression -- #define tindex tsize_t // array/ptr index -+ static Type *tshiftcnt; -+ static Type *tboolean; - static Type *tvoidptr; // void* - static Type *tstring; // immutable(char)[] - static Type *tvalist; // va_list alias -- #define terror basic[Terror] // for error recovery -- -- #define tnull basic[Tnull] // for null type -+ static Type *terror; // for error recovery -+ static Type *tnull; // for null type - -- #define tsize_t basic[Tsize_t] // matches size_t alias -- #define tptrdiff_t basic[Tptrdiff_t] // matches ptrdiff_t alias -- #define thash_t tsize_t // matches hash_t alias -+ static Type *tsize_t; // matches size_t alias -+ static Type *tptrdiff_t; // matches ptrdiff_t alias -+ static Type *thash_t; // matches hash_t alias -+ static Type *tindex; // array/ptr index - -- static ClassDeclaration *typeinfo; -+ static ClassDeclaration *dtypeinfo; - static ClassDeclaration *typeinfoclass; - static ClassDeclaration *typeinfointerface; - static ClassDeclaration *typeinfostruct; -@@ -228,13 +227,16 @@ struct Type : Object - - Type(TY ty); - virtual const char *kind(); -+ Type *copy(); - virtual Type *syntaxCopy(); -- int equals(Object *o); -+ bool equals(RootObject *o); - int dyncast() { return DYNCAST_TYPE; } // kludge for template.isType() - int covariant(Type *t, StorageClass *pstc = NULL); - char *toChars(); - static char needThisPrefix(); - static void init(); -+ -+ #define SIZE_INVALID (~(d_uns64)0) - d_uns64 size(); - virtual d_uns64 size(Loc loc); - virtual unsigned alignsize(); -@@ -248,7 +250,6 @@ struct Type : Object - void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); - void modToBuffer(OutBuffer *buf); - char *modToChars(); -- void toJsonProperty(JsonOut *json, const char *); - virtual void toJson(JsonOut *json); - #if CPP_MANGLE - virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms); -@@ -273,8 +274,9 @@ struct Type : Object - int isWild() { return mod & MODwild; } - int isSharedWild() { return mod == (MODshared | MODwild); } - int isNaked() { return mod == 0; } -+ Type *nullAttributes(); - Type *constOf(); -- Type *invariantOf(); -+ Type *immutableOf(); - Type *mutableOf(); - Type *sharedOf(); - Type *sharedConstOf(); -@@ -291,6 +293,7 @@ struct Type : Object - Type *referenceTo(); - Type *arrayOf(); - Type *aliasthisOf(); -+ int checkAliasThisRec(); - virtual Type *makeConst(); - virtual Type *makeInvariant(); - virtual Type *makeShared(); -@@ -304,21 +307,21 @@ struct Type : Object - virtual MATCH implicitConvTo(Type *to); - virtual MATCH constConv(Type *to); - virtual unsigned wildConvTo(Type *tprm); -- Type *substWildTo(unsigned mod); -+ virtual Type *substWildTo(unsigned mod); - virtual Type *toHeadMutable(); - virtual ClassDeclaration *isClassHandle(); -- virtual Expression *getProperty(Loc loc, Identifier *ident); -- virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ virtual Expression *getProperty(Loc loc, Identifier *ident, int flag); -+ virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - virtual structalign_t alignment(); -- Expression *noMember(Scope *sc, Expression *e, Identifier *ident); -- virtual Expression *defaultInit(Loc loc = 0); -+ Expression *noMember(Scope *sc, Expression *e, Identifier *ident, int flag); -+ virtual Expression *defaultInit(Loc loc = Loc()); - virtual Expression *defaultInitLiteral(Loc loc); - virtual Expression *voidInitLiteral(VarDeclaration *var); -- virtual int isZeroInit(Loc loc = 0); // if initializer is 0 -+ virtual int isZeroInit(Loc loc = Loc()); // if initializer is 0 - virtual dt_t **toDt(dt_t **pdt); - Identifier *getTypeInfoIdent(int internal); - virtual MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL); -- virtual void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); -+ virtual void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - Expression *getInternalTypeInfo(Scope *sc); - Expression *getTypeInfo(Scope *sc); - virtual TypeInfoDeclaration *getTypeInfoDeclaration(); -@@ -329,6 +332,7 @@ struct Type : Object - virtual int hasPointers(); - virtual TypeTuple *toArgTypes(); - virtual Type *nextOf(); -+ Type *baseElemOf(); - uinteger_t sizemask(); - virtual int needsDestruction(); - virtual bool needsNested(); -@@ -346,23 +350,25 @@ struct Type : Object - virtual TypeBasic *isTypeBasic(); - }; - --struct TypeError : Type -+class TypeError : public Type - { -+public: - TypeError(); - Type *syntaxCopy(); - - void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); - - d_uns64 size(Loc loc); -- Expression *getProperty(Loc loc, Identifier *ident); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *getProperty(Loc loc, Identifier *ident, int flag); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - Expression *defaultInit(Loc loc); - Expression *defaultInitLiteral(Loc loc); - TypeTuple *toArgTypes(); - }; - --struct TypeNext : Type -+class TypeNext : public Type - { -+public: - Type *next; - - TypeNext(TY ty, Type *next); -@@ -383,8 +389,9 @@ struct TypeNext : Type - void transitive(); - }; - --struct TypeBasic : Type -+class TypeBasic : public Type - { -+public: - const char *dstring; - unsigned flags; - -@@ -393,8 +400,8 @@ struct TypeBasic : Type - Type *syntaxCopy(); - d_uns64 size(Loc loc); - unsigned alignsize(); -- Expression *getProperty(Loc loc, Identifier *ident); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *getProperty(Loc loc, Identifier *ident, int flag); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - char *toChars(); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - #if CPP_MANGLE -@@ -417,8 +424,9 @@ struct TypeBasic : Type - TypeBasic *isTypeBasic(); - }; - --struct TypeVector : Type -+class TypeVector : public Type - { -+public: - Type *basetype; - - TypeVector(Loc loc, Type *basetype); -@@ -427,13 +435,14 @@ struct TypeVector : Type - Type *semantic(Loc loc, Scope *sc); - d_uns64 size(Loc loc); - unsigned alignsize(); -- Expression *getProperty(Loc loc, Identifier *ident); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *getProperty(Loc loc, Identifier *ident, int flag); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - char *toChars(); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toDecoBuffer(OutBuffer *buf, int flag); - void toJson(JsonOut *json); - MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL); -+ Type *reliesOnTident(TemplateParameters *tparams); - #if CPP_MANGLE - void toCppMangle(OutBuffer *buf, CppMangleState *cms); - #endif -@@ -444,23 +453,27 @@ struct TypeVector : Type - int checkBoolean(); - MATCH implicitConvTo(Type *to); - Expression *defaultInit(Loc loc); -+ Expression *defaultInitLiteral(Loc loc); - TypeBasic *elementType(); - int isZeroInit(Loc loc); -+ dt_t **toDt(dt_t **pdt); - TypeInfoDeclaration *getTypeInfoDeclaration(); - TypeTuple *toArgTypes(); - - type *toCtype(); - }; - --struct TypeArray : TypeNext -+class TypeArray : public TypeNext - { -+public: - TypeArray(TY ty, Type *next); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - }; - - // Static array, one with a fixed dimension --struct TypeSArray : TypeArray -+class TypeSArray : public TypeArray - { -+public: - Expression *dim; - - TypeSArray(Type *t, Expression *dim); -@@ -469,11 +482,11 @@ struct TypeSArray : TypeArray - d_uns64 size(Loc loc); - unsigned alignsize(); - Type *semantic(Loc loc, Scope *sc); -- void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - int isString(); - int isZeroInit(Loc loc); - structalign_t alignment(); -@@ -495,24 +508,27 @@ struct TypeSArray : TypeArray - void toCppMangle(OutBuffer *buf, CppMangleState *cms); - #endif - -+ static Type *makeType(Loc loc, Type *tn, dinteger_t dim); -+ - type *toCtype(); - type *toCParamtype(); - }; - - // Dynamic array, no dimension --struct TypeDArray : TypeArray -+class TypeDArray : public TypeArray - { -+public: - TypeDArray(Type *t); - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(Loc loc); - unsigned alignsize(); - Type *semantic(Loc loc, Scope *sc); -- void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - int isString(); - int isZeroInit(Loc loc); - int checkBoolean(); -@@ -530,8 +546,9 @@ struct TypeDArray : TypeArray - type *toCtype(); - }; - --struct TypeAArray : TypeArray -+class TypeAArray : public TypeArray - { -+public: - Type *index; // key type - Loc loc; - Scope *sc; -@@ -544,11 +561,11 @@ struct TypeAArray : TypeArray - d_uns64 size(Loc loc); - Type *semantic(Loc loc, Scope *sc); - StructDeclaration *getImpl(); -- void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - Expression *defaultInit(Loc loc); - MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL); - int isZeroInit(Loc loc); -@@ -570,8 +587,9 @@ struct TypeAArray : TypeArray - type *toCtype(); - }; - --struct TypePointer : TypeNext -+class TypePointer : public TypeNext - { -+public: - TypePointer(Type *t); - const char *kind(); - Type *syntaxCopy(); -@@ -594,8 +612,9 @@ struct TypePointer : TypeNext - type *toCtype(); - }; - --struct TypeReference : TypeNext -+class TypeReference : public TypeNext - { -+public: - TypeReference(Type *t); - const char *kind(); - Type *syntaxCopy(); -@@ -603,7 +622,7 @@ struct TypeReference : TypeNext - d_uns64 size(Loc loc); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - Expression *defaultInit(Loc loc); - int isZeroInit(Loc loc); - #if CPP_MANGLE -@@ -634,8 +653,9 @@ enum PURE - PUREfwdref = 4, // it's pure, but not known which level yet - }; - --struct TypeFunction : TypeNext -+class TypeFunction : public TypeNext - { -+public: - // .next is the return type - - Parameters *parameters; // function parameters -@@ -644,21 +664,19 @@ struct TypeFunction : TypeNext - bool isnothrow; // true: nothrow - bool isproperty; // can be called without parentheses - bool isref; // true: returns a reference -- enum LINK linkage; // calling convention -- enum TRUST trust; // level of trust -- enum PURE purity; // PURExxxx -+ LINK linkage; // calling convention -+ TRUST trust; // level of trust -+ PURE purity; // PURExxxx - bool iswild; // is inout function - Expressions *fargs; // function arguments - - int inuse; - -- TypeFunction(Parameters *parameters, Type *treturn, int varargs, enum LINK linkage, StorageClass stc = 0); -+ TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc = 0); - const char *kind(); -- TypeFunction *copy(); - Type *syntaxCopy(); - Type *semantic(Loc loc, Scope *sc); - void purityLevel(); -- bool hasMutableIndirectionParams(); - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); - void toCBufferWithAttributes(OutBuffer *buf, Identifier *ident, HdrGenState* hgs, TypeFunction *attrs, TemplateDeclaration *td); -@@ -675,17 +693,19 @@ struct TypeFunction : TypeNext - bool parameterEscapes(Parameter *p); - Type *addStorageClass(StorageClass stc); - -- MATCH callMatch(Expression *ethis, Expressions *toargs, int flag = 0); -+ Type *substWildTo(unsigned mod); -+ MATCH callMatch(Type *tthis, Expressions *toargs, int flag = 0); - type *toCtype(); -- enum RET retStyle(); -+ RET retStyle(); - - unsigned totym(); - - Expression *defaultInit(Loc loc); - }; - --struct TypeDelegate : TypeNext -+class TypeDelegate : public TypeNext - { -+public: - // .next is a TypeFunction - - TypeDelegate(Type *t); -@@ -701,7 +721,7 @@ struct TypeDelegate : TypeNext - int isZeroInit(Loc loc); - int checkBoolean(); - TypeInfoDeclaration *getTypeInfoDeclaration(); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - int hasPointers(); - TypeTuple *toArgTypes(); - #if CPP_MANGLE -@@ -711,23 +731,27 @@ struct TypeDelegate : TypeNext - type *toCtype(); - }; - --struct TypeQualified : Type -+class TypeQualified : public Type - { -+public: - Loc loc; -- Identifiers idents; // array of Identifier's representing ident.ident.ident etc. -+ Objects idents; // array of Identifier and TypeInstance, -+ // representing ident.ident!tiargs.ident. ... etc. - - TypeQualified(TY ty, Loc loc); - void syntaxCopyHelper(TypeQualified *t); - void addIdent(Identifier *ident); -+ void addInst(TemplateInstance *inst); - void toCBuffer2Helper(OutBuffer *buf, HdrGenState *hgs); - void toJson(JsonOut *json); - d_uns64 size(Loc loc); - void resolveHelper(Loc loc, Scope *sc, Dsymbol *s, Dsymbol *scopesym, -- Expression **pe, Type **pt, Dsymbol **ps); -+ Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - }; - --struct TypeIdentifier : TypeQualified -+class TypeIdentifier : public TypeQualified - { -+public: - Identifier *ident; - Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution - -@@ -738,7 +762,7 @@ struct TypeIdentifier : TypeQualified - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - Dsymbol *toDsymbol(Scope *sc); - Type *semantic(Loc loc, Scope *sc); - MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL); -@@ -748,8 +772,9 @@ struct TypeIdentifier : TypeQualified - - /* Similar to TypeIdentifier, but with a TemplateInstance as the root - */ --struct TypeInstance : TypeQualified -+class TypeInstance : public TypeQualified - { -+public: - TemplateInstance *tempinst; - - TypeInstance(Loc loc, TemplateInstance *tempinst); -@@ -759,15 +784,17 @@ struct TypeInstance : TypeQualified - //void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - Type *semantic(Loc loc, Scope *sc); - Dsymbol *toDsymbol(Scope *sc); - Type *reliesOnTident(TemplateParameters *tparams = NULL); - MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL); -+ Expression *toExpression(); - }; - --struct TypeTypeof : TypeQualified -+class TypeTypeof : public TypeQualified - { -+public: - Expression *exp; - int inuse; - -@@ -777,24 +804,39 @@ struct TypeTypeof : TypeQualified - Dsymbol *toDsymbol(Scope *sc); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - Type *semantic(Loc loc, Scope *sc); - d_uns64 size(Loc loc); - }; - --struct TypeReturn : TypeQualified -+class TypeReturn : public TypeQualified - { -+public: - TypeReturn(Loc loc); - const char *kind(); - Type *syntaxCopy(); - Dsymbol *toDsymbol(Scope *sc); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - Type *semantic(Loc loc, Scope *sc); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); - }; - --struct TypeStruct : Type -+// Whether alias this dependency is recursive or not. -+enum AliasThisRec -+{ -+ RECno = 0, // no alias this recursion -+ RECyes = 1, // alias this has recursive dependency -+ RECfwdref = 2, // not yet known -+ -+ RECtracing = 0x4, // mark in progress of implicitConvTo/wildConvTo -+}; -+ -+class TypeStruct : public Type - { -+public: - StructDeclaration *sym; -+ AliasThisRec att; - - TypeStruct(StructDeclaration *sym); - const char *kind(); -@@ -807,7 +849,7 @@ struct TypeStruct : Type - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - structalign_t alignment(); - Expression *defaultInit(Loc loc); - Expression *defaultInitLiteral(Loc loc); -@@ -833,8 +875,9 @@ struct TypeStruct : Type - type *toCtype(); - }; - --struct TypeEnum : Type -+class TypeEnum : public Type - { -+public: - EnumDeclaration *sym; - - TypeEnum(EnumDeclaration *sym); -@@ -848,8 +891,8 @@ struct TypeEnum : Type - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -- Expression *getProperty(Loc loc, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); -+ Expression *getProperty(Loc loc, Identifier *ident, int flag); - int isintegral(); - int isfloating(); - int isreal(); -@@ -858,6 +901,7 @@ struct TypeEnum : Type - int isscalar(); - int isunsigned(); - int checkBoolean(); -+ int isString(); - int isAssignable(); - int needsDestruction(); - bool needsNested(); -@@ -870,6 +914,7 @@ struct TypeEnum : Type - TypeInfoDeclaration *getTypeInfoDeclaration(); - int hasPointers(); - TypeTuple *toArgTypes(); -+ Type *nextOf(); - #if CPP_MANGLE - void toCppMangle(OutBuffer *buf, CppMangleState *cms); - #endif -@@ -877,8 +922,9 @@ struct TypeEnum : Type - type *toCtype(); - }; - --struct TypeTypedef : Type -+class TypeTypedef : public Type - { -+public: - TypedefDeclaration *sym; - - TypeTypedef(TypedefDeclaration *sym); -@@ -892,9 +938,9 @@ struct TypeTypedef : Type - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - structalign_t alignment(); -- Expression *getProperty(Loc loc, Identifier *ident); -+ Expression *getProperty(Loc loc, Identifier *ident, int flag); - int isintegral(); - int isfloating(); - int isreal(); -@@ -927,9 +973,11 @@ struct TypeTypedef : Type - type *toCParamtype(); - }; - --struct TypeClass : Type -+class TypeClass : public Type - { -+public: - ClassDeclaration *sym; -+ AliasThisRec att; - - TypeClass(ClassDeclaration *sym); - const char *kind(); -@@ -941,7 +989,7 @@ struct TypeClass : Type - void toDecoBuffer(OutBuffer *buf, int flag); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); -- Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); -+ Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); - ClassDeclaration *isClassHandle(); - int isBaseOf(Type *t, int *poffset); - MATCH implicitConvTo(Type *to); -@@ -966,8 +1014,9 @@ struct TypeClass : Type - Symbol *toSymbol(); - }; - --struct TypeTuple : Type -+class TypeTuple : public Type - { -+public: - Parameters *arguments; // types making up the tuple - - TypeTuple(Parameters *arguments); -@@ -978,18 +1027,19 @@ struct TypeTuple : Type - const char *kind(); - Type *syntaxCopy(); - Type *semantic(Loc loc, Scope *sc); -- int equals(Object *o); -+ bool equals(RootObject *o); - Type *reliesOnTident(TemplateParameters *tparams = NULL); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toDecoBuffer(OutBuffer *buf, int flag); - void toJson(JsonOut *json); -- Expression *getProperty(Loc loc, Identifier *ident); -+ Expression *getProperty(Loc loc, Identifier *ident, int flag); - Expression *defaultInit(Loc loc); - TypeInfoDeclaration *getTypeInfoDeclaration(); - }; - --struct TypeSlice : TypeNext -+class TypeSlice : public TypeNext - { -+public: - Expression *lwr; - Expression *upr; - -@@ -997,13 +1047,14 @@ struct TypeSlice : TypeNext - const char *kind(); - Type *syntaxCopy(); - Type *semantic(Loc loc, Scope *sc); -- void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); -+ void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toJson(JsonOut *json); - }; - --struct TypeNull : Type -+class TypeNull : public Type - { -+public: - TypeNull(); - const char *kind(); - -@@ -1016,18 +1067,16 @@ struct TypeNull : Type - void toJson(JsonOut *json); - - d_uns64 size(Loc loc); -- //Expression *getProperty(Loc loc, Identifier *ident); -- //Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); - Expression *defaultInit(Loc loc); -- //Expression *defaultInitLiteral(Loc loc); - }; - - /**************************************************************/ - - //enum InOut { None, In, Out, InOut, Lazy }; - --struct Parameter : Object -+class Parameter : public RootObject - { -+public: - //enum InOut inout; - StorageClass storageClass; - Type *type; -@@ -1039,10 +1088,11 @@ struct Parameter : Object - Type *isLazyArray(); - void toDecoBuffer(OutBuffer *buf); - int dyncast() { return DYNCAST_PARAMETER; } // kludge for template.isType() -- void toJson(JsonOut *json); - static Parameters *arraySyntaxCopy(Parameters *args); - static char *argsTypesToChars(Parameters *args, int varargs); -+#if CPP_MANGLE - static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs); -+#endif - static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *arguments, int varargs); - static void argsToDecoBuffer(OutBuffer *buf, Parameters *arguments); - static int isTPL(Parameters *arguments); ---- a/src/gcc/d/dfrontend/object.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/object.c 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,45 @@ -+ -+// Copyright (c) 1999-2012 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#include -+ -+#include "object.h" -+#include "outbuffer.h" -+ -+/****************************** Object ********************************/ -+ -+bool RootObject::equals(RootObject *o) -+{ -+ return o == this; -+} -+ -+int RootObject::compare(RootObject *obj) -+{ -+ return this - obj; -+} -+ -+void RootObject::print() -+{ -+ printf("%s %p\n", toChars(), this); -+} -+ -+char *RootObject::toChars() -+{ -+ return (char *)"Object"; -+} -+ -+int RootObject::dyncast() -+{ -+ return 0; -+} -+ -+void RootObject::toBuffer(OutBuffer *b) -+{ -+ b->writestring("Object"); -+} ---- a/src/gcc/d/dfrontend/object.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/object.h 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,57 @@ -+ -+// Copyright (c) 1999-2011 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#ifndef OBJECT_H -+#define OBJECT_H -+ -+#define POSIX (linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun) -+ -+#if __DMC__ -+#pragma once -+#endif -+ -+#include -+ -+typedef size_t hash_t; -+ -+struct OutBuffer; -+ -+/* -+ * Root of our class library. -+ */ -+class RootObject -+{ -+public: -+ RootObject() { } -+ virtual ~RootObject() { } -+ -+ virtual bool equals(RootObject *o); -+ -+ /** -+ * Return <0, ==0, or >0 if this is less than, equal to, or greater than obj. -+ * Useful for sorting Objects. -+ */ -+ virtual int compare(RootObject *obj); -+ -+ /** -+ * Pretty-print an Object. Useful for debugging the old-fashioned way. -+ */ -+ virtual void print(); -+ -+ virtual char *toChars(); -+ virtual void toBuffer(OutBuffer *buf); -+ -+ /** -+ * Used as a replacement for dynamic_cast. Returns a unique number -+ * defined by the library user. For Object, the return value is 0. -+ */ -+ virtual int dyncast(); -+}; -+ -+#endif ---- a/src/gcc/d/dfrontend/opover.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/opover.c 2014-04-01 16:32:51.000000000 +0100 -@@ -39,7 +39,6 @@ - static Dsymbol *inferApplyArgTypesX(Expression *ethis, FuncDeclaration *fstart, Parameters *arguments); - static void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments); - static int inferApplyArgTypesY(TypeFunction *tf, Parameters *arguments, int flags = 0); --static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments); - - /******************************** Expression **************************/ - -@@ -182,7 +181,7 @@ AggregateDeclaration *isAggregate(Type * - /******************************************* - * Helper function to turn operator into template argument list - */ --Objects *opToArg(Scope *sc, enum TOK op) -+Objects *opToArg(Scope *sc, TOK op) - { - /* Remove the = from op= - */ -@@ -202,11 +201,11 @@ Objects *opToArg(Scope *sc, enum TOK op) - case TOKcatass: op = TOKcat; break; - case TOKpowass: op = TOKpow; break; - } -- Expression *e = new StringExp(0, (char *)Token::toChars(op)); -+ Expression *e = new StringExp(Loc(), (char *)Token::toChars(op)); - e = e->semantic(sc); -- Objects *targsi = new Objects(); -- targsi->push(e); -- return targsi; -+ Objects *tiargs = new Objects(); -+ tiargs->push(e); -+ return tiargs; - } - - /************************************ -@@ -236,27 +235,31 @@ Expression *UnaExp::op_overload(Scope *s - Dsymbol *fd = search_function(ad, Id::opIndexUnary); - if (fd) - { -- ae = resolveOpDollar(sc, ae); -- Objects *targsi = opToArg(sc, op); -- Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, targsi); -+ Expression *e0 = resolveOpDollar(sc, ae); -+ Objects *tiargs = opToArg(sc, op); -+ Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, tiargs); - e = new CallExp(loc, e, ae->arguments); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } - - // Didn't find it. Forward to aliasthis -- if (ad->aliasthis) -+ if (ad->aliasthis && ae->e1->type != att1) - { - /* Rewrite op(a[arguments]) as: - * op(a.aliasthis[arguments]) - */ - Expression *e1 = ae->copy(); - ((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident); -- Expression *e = copy(); -- ((UnaExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ UnaExp *ue = (UnaExp *)copy(); -+ if (!ue->att1 && ae->e1->type->checkAliasThisRec()) -+ ue->att1 = ae->e1->type; -+ ue->e1 = e1; -+ if (Expression *e = ue->trySemantic(sc)) -+ return e; - } -+ att1 = NULL; - } - } - else if (e1->op == TOKslice) -@@ -274,33 +277,38 @@ Expression *UnaExp::op_overload(Scope *s - Dsymbol *fd = search_function(ad, Id::opSliceUnary); - if (fd) - { -- se = resolveOpDollar(sc, se); -+ Expression *e0 = resolveOpDollar(sc, se); - Expressions *a = new Expressions(); - assert(!se->lwr || se->upr); - if (se->lwr) -- { a->push(se->lwr); -+ { -+ a->push(se->lwr); - a->push(se->upr); - } -- Objects *targsi = opToArg(sc, op); -- Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, targsi); -+ Objects *tiargs = opToArg(sc, op); -+ Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, tiargs); - e = new CallExp(loc, e, a); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } - - // Didn't find it. Forward to aliasthis -- if (ad->aliasthis) -+ if (ad->aliasthis && se->e1->type != att1) - { - /* Rewrite op(a[lwr..upr]) as: - * op(a.aliasthis[lwr..upr]) - */ - Expression *e1 = se->copy(); - ((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident); -- Expression *e = copy(); -- ((UnaExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ UnaExp *ue = (UnaExp *)copy(); -+ if (!ue->att1 && se->e1->type->checkAliasThisRec()) -+ ue->att1 = se->e1->type; -+ ue->e1 = e1; -+ if (Expression *e = ue->trySemantic(sc)) -+ return e; - } -+ att1 = NULL; - } - } - #endif -@@ -344,24 +352,26 @@ Expression *UnaExp::op_overload(Scope *s - fd = search_function(ad, Id::opUnary); - if (fd) - { -- Objects *targsi = opToArg(sc, op); -- Expression *e = new DotTemplateInstanceExp(loc, e1, fd->ident, targsi); -+ Objects *tiargs = opToArg(sc, op); -+ Expression *e = new DotTemplateInstanceExp(loc, e1, fd->ident, tiargs); - e = new CallExp(loc, e); - e = e->semantic(sc); - return e; - } - - // Didn't find it. Forward to aliasthis -- if (ad->aliasthis) -+ if (ad->aliasthis && this->e1->type != att1) - { - /* Rewrite op(e1) as: - * op(e1.aliasthis) - */ -+ //printf("att una %s e1 = %s\n", Token::toChars(op), this->e1->type->toChars()); - Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident); -- Expression *e = copy(); -- ((UnaExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ UnaExp *ue = (UnaExp *)copy(); -+ if (!ue->att1 && this->e1->type->checkAliasThisRec()) -+ ue->att1 = this->e1->type; -+ ue->e1 = e1; -+ return ue->trySemantic(sc); - } - #endif - } -@@ -380,24 +390,27 @@ Expression *ArrayExp::op_overload(Scope - /* Rewrite op e1[arguments] as: - * e1.opIndex(arguments) - */ -- ArrayExp *ae = resolveOpDollar(sc, this); -- Expression *e = new DotIdExp(loc, ae->e1, fd->ident); -- e = new CallExp(loc, e, ae->arguments); -+ Expression *e0 = resolveOpDollar(sc, this); -+ Expression *e = new DotIdExp(loc, e1, fd->ident); -+ e = new CallExp(loc, e, arguments); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } - - // Didn't find it. Forward to aliasthis -- if (ad->aliasthis) -+ if (ad->aliasthis && this->e1->type != att1) - { - /* Rewrite op(e1) as: - * op(e1.aliasthis) - */ -+ //printf("att arr e1 = %s\n", this->e1->type->toChars()); - Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident); -- Expression *e = copy(); -- ((UnaExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ UnaExp *ue = (UnaExp *)copy(); -+ if (!ue->att1 && this->e1->type->checkAliasThisRec()) -+ ue->att1 = this->e1->type; -+ ue->e1 = e1; -+ return ue->trySemantic(sc); - } - } - return NULL; -@@ -426,9 +439,9 @@ Expression *CastExp::op_overload(Scope * - return build_overload(loc, sc, e1, NULL, fd); - } - #endif -- Objects *targsi = new Objects(); -- targsi->push(to); -- Expression *e = new DotTemplateInstanceExp(loc, e1, fd->ident, targsi); -+ Objects *tiargs = new Objects(); -+ tiargs->push(to); -+ Expression *e = new DotTemplateInstanceExp(loc, e1, fd->ident, tiargs); - e = new CallExp(loc, e); - e = e->semantic(sc); - return e; -@@ -487,7 +500,7 @@ Expression *BinExp::op_overload(Scope *s - } - #endif - -- Objects *targsi = NULL; -+ Objects *tiargs = NULL; - #if DMDV2 - if (op == TOKplusplus || op == TOKminusminus) - { // Bug4099 fix -@@ -500,16 +513,28 @@ Expression *BinExp::op_overload(Scope *s - /* Try the new D2 scheme, opBinary and opBinaryRight - */ - if (ad1) -+ { - s = search_function(ad1, Id::opBinary); -+ if (s && !s->isTemplateDeclaration()) -+ { e1->error("%s.opBinary isn't a template", e1->toChars()); -+ return new ErrorExp(); -+ } -+ } - if (ad2) -+ { - s_r = search_function(ad2, Id::opBinaryRight); -+ if (s_r && !s_r->isTemplateDeclaration()) -+ { e2->error("%s.opBinaryRight isn't a template", e2->toChars()); -+ return new ErrorExp(); -+ } -+ } - -- // Set targsi, the template argument list, which will be the operator string -+ // Set tiargs, the template argument list, which will be the operator string - if (s || s_r) - { - id = Id::opBinary; - id_r = Id::opBinaryRight; -- targsi = opToArg(sc, op); -+ tiargs = opToArg(sc, op); - } - } - #endif -@@ -524,8 +549,10 @@ Expression *BinExp::op_overload(Scope *s - - args1.setDim(1); - args1[0] = e1; -+ expandTuples(&args1); - args2.setDim(1); - args2[0] = e2; -+ expandTuples(&args2); - argsset = 1; - - Match m; -@@ -533,32 +560,12 @@ Expression *BinExp::op_overload(Scope *s - m.last = MATCHnomatch; - - if (s) -- { -- FuncDeclaration *fd = s->isFuncDeclaration(); -- if (fd) -- { -- overloadResolveX(&m, fd, NULL, &args2); -- } -- else -- { TemplateDeclaration *td = s->isTemplateDeclaration(); -- templateResolve(&m, td, sc, loc, targsi, e1, &args2); -- } -- } -+ functionResolve(&m, s, loc, sc, tiargs, e1->type, &args2); - - FuncDeclaration *lastf = m.lastf; - - if (s_r) -- { -- FuncDeclaration *fd = s_r->isFuncDeclaration(); -- if (fd) -- { -- overloadResolveX(&m, fd, NULL, &args1); -- } -- else -- { TemplateDeclaration *td = s_r->isTemplateDeclaration(); -- templateResolve(&m, td, sc, loc, targsi, e2, &args1); -- } -- } -+ functionResolve(&m, s_r, loc, sc, tiargs, e2->type, &args1); - - if (m.count > 1) - { -@@ -571,7 +578,7 @@ Expression *BinExp::op_overload(Scope *s - else if (m.last == MATCHnomatch) - { - m.lastf = m.anyf; -- if (targsi) -+ if (tiargs) - goto L1; - } - -@@ -593,7 +600,7 @@ Expression *BinExp::op_overload(Scope *s - - L1: - #if 1 // Retained for D1 compatibility -- if (isCommutative() && !targsi) -+ if (isCommutative() && !tiargs) - { - s = NULL; - s_r = NULL; -@@ -615,10 +622,13 @@ L1: - */ - - if (!argsset) -- { args1.setDim(1); -+ { -+ args1.setDim(1); - args1[0] = e1; -+ expandTuples(&args1); - args2.setDim(1); - args2[0] = e2; -+ expandTuples(&args2); - } - - Match m; -@@ -626,31 +636,12 @@ L1: - m.last = MATCHnomatch; - - if (s_r) -- { -- FuncDeclaration *fd = s_r->isFuncDeclaration(); -- if (fd) -- { -- overloadResolveX(&m, fd, NULL, &args2); -- } -- else -- { TemplateDeclaration *td = s_r->isTemplateDeclaration(); -- templateResolve(&m, td, sc, loc, targsi, e1, &args2); -- } -- } -+ functionResolve(&m, s_r, loc, sc, tiargs, e1->type, &args2); -+ - FuncDeclaration *lastf = m.lastf; - - if (s) -- { -- FuncDeclaration *fd = s->isFuncDeclaration(); -- if (fd) -- { -- overloadResolveX(&m, fd, NULL, &args1); -- } -- else -- { TemplateDeclaration *td = s->isTemplateDeclaration(); -- templateResolve(&m, td, sc, loc, targsi, e2, &args1); -- } -- } -+ functionResolve(&m, s, loc, sc, tiargs, e2->type, &args1); - - if (m.count > 1) - { -@@ -709,11 +700,15 @@ L1: - /* Rewrite (e1 op e2) as: - * (e1.aliasthis op e2) - */ -+ if (att1 && this->e1->type == att1) -+ return NULL; -+ //printf("att bin e1 = %s\n", this->e1->type->toChars()); - Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident); -- Expression *e = copy(); -- ((BinExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att1 && this->e1->type->checkAliasThisRec()) -+ be->att1 = this->e1->type; -+ be->e1 = e1; -+ return be->trySemantic(sc); - } - - // Try alias this on second operand -@@ -726,11 +721,15 @@ L1: - /* Rewrite (e1 op e2) as: - * (e1 op e2.aliasthis) - */ -+ if (att2 && this->e2->type == att2) -+ return NULL; -+ //printf("att bin e2 = %s\n", this->e2->type->toChars()); - Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident); -- Expression *e = copy(); -- ((BinExp *)e)->e2 = e2; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att2 && this->e2->type->checkAliasThisRec()) -+ be->att2 = this->e2->type; -+ be->e2 = e2; -+ return be->trySemantic(sc); - } - #endif - return NULL; -@@ -760,7 +759,7 @@ Expression *BinExp::compare_overload(Sco - s_r = NULL; - } - -- Objects *targsi = NULL; -+ Objects *tiargs = NULL; - - if (s || s_r) - { -@@ -775,8 +774,10 @@ Expression *BinExp::compare_overload(Sco - - args1.setDim(1); - args1[0] = e1; -+ expandTuples(&args1); - args2.setDim(1); - args2[0] = e2; -+ expandTuples(&args2); - - Match m; - memset(&m, 0, sizeof(m)); -@@ -789,33 +790,13 @@ Expression *BinExp::compare_overload(Sco - } - - if (s) -- { -- FuncDeclaration *fd = s->isFuncDeclaration(); -- if (fd) -- { -- overloadResolveX(&m, fd, NULL, &args2); -- } -- else -- { TemplateDeclaration *td = s->isTemplateDeclaration(); -- templateResolve(&m, td, sc, loc, targsi, e1, &args2); -- } -- } -+ functionResolve(&m, s, loc, sc, tiargs, e1->type, &args2); - - FuncDeclaration *lastf = m.lastf; - int count = m.count; - - if (s_r) -- { -- FuncDeclaration *fd = s_r->isFuncDeclaration(); -- if (fd) -- { -- overloadResolveX(&m, fd, NULL, &args1); -- } -- else -- { TemplateDeclaration *td = s_r->isTemplateDeclaration(); -- templateResolve(&m, td, sc, loc, targsi, e2, &args1); -- } -- } -+ functionResolve(&m, s_r, loc, sc, tiargs, e2->type, &args1); - - if (m.count > 1) - { -@@ -882,11 +863,15 @@ Expression *BinExp::compare_overload(Sco - /* Rewrite (e1 op e2) as: - * (e1.aliasthis op e2) - */ -+ if (att1 && this->e1->type == att1) -+ return NULL; -+ //printf("att cmp_bin e1 = %s\n", this->e1->type->toChars()); - Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident); -- Expression *e = copy(); -- ((BinExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att1 && this->e1->type->checkAliasThisRec()) -+ be->att1 = this->e1->type; -+ be->e1 = e1; -+ return be->trySemantic(sc); - } - - // Try alias this on second operand -@@ -895,11 +880,15 @@ Expression *BinExp::compare_overload(Sco - /* Rewrite (e1 op e2) as: - * (e1 op e2.aliasthis) - */ -+ if (att2 && this->e2->type == att2) -+ return NULL; -+ //printf("att cmp_bin e2 = %s\n", this->e2->type->toChars()); - Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident); -- Expression *e = copy(); -- ((BinExp *)e)->e2 = e2; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att2 && this->e2->type->checkAliasThisRec()) -+ be->att2 = this->e2->type; -+ be->e2 = e2; -+ return be->trySemantic(sc); - } - - return NULL; -@@ -915,7 +904,7 @@ Expression *EqualExp::op_overload(Scope - { ClassDeclaration *cd1 = t1->isClassHandle(); - ClassDeclaration *cd2 = t2->isClassHandle(); - -- if (!(cd1->isCPPinterface() || cd2->isCPPinterface())) -+ if (!(cd1->cpp || cd2->cpp)) - { - /* Rewrite as: - * .object.opEquals(e1, e2) -@@ -975,30 +964,34 @@ Expression *BinAssignExp::op_overload(Sc - Dsymbol *fd = search_function(ad, Id::opIndexOpAssign); - if (fd) - { -- ae = resolveOpDollar(sc, ae); -+ Expression *e0 = resolveOpDollar(sc, ae); - Expressions *a = (Expressions *)ae->arguments->copy(); - a->insert(0, e2); - -- Objects *targsi = opToArg(sc, op); -- Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, targsi); -+ Objects *tiargs = opToArg(sc, op); -+ Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, tiargs); - e = new CallExp(loc, e, a); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } - - // Didn't find it. Forward to aliasthis -- if (ad->aliasthis) -+ if (ad->aliasthis && ae->e1->type != att1) - { - /* Rewrite a[arguments] op= e2 as: - * a.aliasthis[arguments] op= e2 - */ - Expression *e1 = ae->copy(); - ((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident); -- Expression *e = copy(); -- ((UnaExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att1 && ae->e1->type->checkAliasThisRec()) -+ be->att1 = ae->e1->type; -+ be->e1 = e1; -+ if (Expression *e = be->trySemantic(sc)) -+ return e; - } -+ att1 = NULL; - } - } - else if (e1->op == TOKslice) -@@ -1016,35 +1009,40 @@ Expression *BinAssignExp::op_overload(Sc - Dsymbol *fd = search_function(ad, Id::opSliceOpAssign); - if (fd) - { -- se = resolveOpDollar(sc, se); -+ Expression *e0 = resolveOpDollar(sc, se); - Expressions *a = new Expressions(); - a->push(e2); - assert(!se->lwr || se->upr); - if (se->lwr) -- { a->push(se->lwr); -+ { -+ a->push(se->lwr); - a->push(se->upr); - } - -- Objects *targsi = opToArg(sc, op); -- Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, targsi); -+ Objects *tiargs = opToArg(sc, op); -+ Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, tiargs); - e = new CallExp(loc, e, a); -+ e = combine(e0, e); - e = e->semantic(sc); - return e; - } - - // Didn't find it. Forward to aliasthis -- if (ad->aliasthis) -+ if (ad->aliasthis && se->e1->type != att1) - { - /* Rewrite a[lwr..upr] op= e2 as: - * a.aliasthis[lwr..upr] op= e2 - */ - Expression *e1 = se->copy(); - ((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident); -- Expression *e = copy(); -- ((UnaExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att1 && se->e1->type->checkAliasThisRec()) -+ be->att1 = se->e1->type; -+ be->e1 = e1; -+ if (Expression *e = be->trySemantic(sc)) -+ return e; - } -+ att1 = NULL; - } - } - #endif -@@ -1072,19 +1070,25 @@ Expression *BinAssignExp::op_overload(Sc - } - #endif - -- Objects *targsi = NULL; -+ Objects *tiargs = NULL; - #if DMDV2 - if (!s) - { /* Try the new D2 scheme, opOpAssign - */ - if (ad1) -+ { - s = search_function(ad1, Id::opOpAssign); -+ if (s && !s->isTemplateDeclaration()) -+ { error("%s.opOpAssign isn't a template", e1->toChars()); -+ return new ErrorExp(); -+ } -+ } - -- // Set targsi, the template argument list, which will be the operator string -+ // Set tiargs, the template argument list, which will be the operator string - if (s) - { - id = Id::opOpAssign; -- targsi = opToArg(sc, op); -+ tiargs = opToArg(sc, op); - } - } - #endif -@@ -1097,23 +1101,14 @@ Expression *BinAssignExp::op_overload(Sc - - args2.setDim(1); - args2[0] = e2; -+ expandTuples(&args2); - - Match m; - memset(&m, 0, sizeof(m)); - m.last = MATCHnomatch; - - if (s) -- { -- FuncDeclaration *fd = s->isFuncDeclaration(); -- if (fd) -- { -- overloadResolveX(&m, fd, NULL, &args2); -- } -- else -- { TemplateDeclaration *td = s->isTemplateDeclaration(); -- templateResolve(&m, td, sc, loc, targsi, e1, &args2); -- } -- } -+ functionResolve(&m, s, loc, sc, tiargs, e1->type, &args2); - - if (m.count > 1) - { -@@ -1126,7 +1121,7 @@ Expression *BinAssignExp::op_overload(Sc - else if (m.last == MATCHnomatch) - { - m.lastf = m.anyf; -- if (targsi) -+ if (tiargs) - goto L1; - } - -@@ -1143,11 +1138,15 @@ L1: - /* Rewrite (e1 op e2) as: - * (e1.aliasthis op e2) - */ -+ if (att1 && this->e1->type == att1) -+ return NULL; -+ //printf("att %s e1 = %s\n", Token::toChars(op), this->e1->type->toChars()); - Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident); -- Expression *e = copy(); -- ((BinExp *)e)->e1 = e1; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att1 && this->e1->type->checkAliasThisRec()) -+ be->att1 = this->e1->type; -+ be->e1 = e1; -+ return be->trySemantic(sc); - } - - // Try alias this on second operand -@@ -1157,11 +1156,15 @@ L1: - /* Rewrite (e1 op e2) as: - * (e1 op e2.aliasthis) - */ -+ if (att2 && this->e2->type == att2) -+ return NULL; -+ //printf("att %s e2 = %s\n", Token::toChars(op), this->e2->type->toChars()); - Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident); -- Expression *e = copy(); -- ((BinExp *)e)->e2 = e2; -- e = e->trySemantic(sc); -- return e; -+ BinExp *be = (BinExp *)copy(); -+ if (!be->att2 && this->e2->type->checkAliasThisRec()) -+ be->att2 = this->e2->type; -+ be->e2 = e2; -+ return be->trySemantic(sc); - } - #endif - return NULL; -@@ -1201,7 +1204,7 @@ Dsymbol *search_function(ScopeDsymbol *a - FuncDeclaration *fd; - TemplateDeclaration *td; - -- s = ad->search(0, funcid, 0); -+ s = ad->search(Loc(), funcid, 0); - if (s) - { Dsymbol *s2; - -@@ -1228,6 +1231,8 @@ int ForeachStatement::inferAggregate(Sco - int sliced = 0; - #endif - Type *tab; -+ Type *att = NULL; -+ Expression *org_aggr = aggr; - AggregateDeclaration *ad; - - while (1) -@@ -1239,6 +1244,10 @@ int ForeachStatement::inferAggregate(Sco - goto Lerr; - - tab = aggr->type->toBasetype(); -+ if (att == tab) -+ { aggr = org_aggr; -+ goto Lerr; -+ } - switch (tab->ty) - { - case Tarray: -@@ -1277,13 +1286,15 @@ int ForeachStatement::inferAggregate(Sco - } - } - -- if (Dsymbol *shead = ad->search(0, idfront, 0)) -+ if (Dsymbol *shead = ad->search(Loc(), idfront, 0)) - { // range aggregate - break; - } - - if (ad->aliasthis) - { -+ if (!att && tab->checkAliasThisRec()) -+ att = tab; - aggr = new DotIdExp(aggr->loc, aggr, ad->aliasthis->ident); - continue; - } -@@ -1436,7 +1447,7 @@ int ForeachStatement::inferApplyArgTypes - /* Look for a front() or back() overload - */ - Identifier *id = (op == TOKforeach) ? Id::Ffront : Id::Fback; -- Dsymbol *s = ad->search(0, id, 0); -+ Dsymbol *s = ad->search(Loc(), id, 0); - FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL; - if (fd) - { -@@ -1474,47 +1485,51 @@ int ForeachStatement::inferApplyArgTypes - - static Dsymbol *inferApplyArgTypesX(Expression *ethis, FuncDeclaration *fstart, Parameters *arguments) - { -- struct Param3 -- { -- Parameters *arguments; -- int mod; -- MATCH match; -- FuncDeclaration *fd_best; -- FuncDeclaration *fd_ambig; -- -- static int fp(void *param, FuncDeclaration *f) -- { -- Param3 *p = (Param3 *)param; -- TypeFunction *tf = (TypeFunction *)f->type; -- MATCH m = MATCHexact; -- -- if (f->isThis()) -- { if (!MODimplicitConv(p->mod, tf->mod)) -- m = MATCHnomatch; -- else if (p->mod != tf->mod) -- m = MATCHconst; -- } -- if (!inferApplyArgTypesY(tf, p->arguments, 1)) -- m = MATCHnomatch; -+ struct ParamOpOver -+ { -+ Parameters *arguments; -+ int mod; -+ MATCH match; -+ FuncDeclaration *fd_best; -+ FuncDeclaration *fd_ambig; - -- if (m > p->match) -- { p->fd_best = f; -- p->fd_ambig = NULL; -- p->match = m; -- } -- else if (m == p->match) -- p->fd_ambig = f; -+ static int fp(void *param, Dsymbol *s) -+ { -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ if (!f) - return 0; -+ ParamOpOver *p = (ParamOpOver *)param; -+ TypeFunction *tf = (TypeFunction *)f->type; -+ MATCH m = MATCHexact; -+ -+ if (f->isThis()) -+ { -+ if (!MODimplicitConv(p->mod, tf->mod)) -+ m = MATCHnomatch; -+ else if (p->mod != tf->mod) -+ m = MATCHconst; - } -- }; -+ if (!inferApplyArgTypesY(tf, p->arguments, 1)) -+ m = MATCHnomatch; - -- Param3 p; -+ if (m > p->match) -+ { -+ p->fd_best = f; -+ p->fd_ambig = NULL; -+ p->match = m; -+ } -+ else if (m == p->match) -+ p->fd_ambig = f; -+ return 0; -+ } -+ }; -+ ParamOpOver p; - p.arguments = arguments; - p.mod = ethis->type->mod; - p.match = MATCHnomatch; - p.fd_best = NULL; - p.fd_ambig = NULL; -- overloadApply(fstart, &Param3::fp, &p); -+ overloadApply(fstart, &p, &ParamOpOver::fp); - if (p.fd_best) - { - inferApplyArgTypesY((TypeFunction *)p.fd_best->type, arguments); -@@ -1571,10 +1586,10 @@ static int inferApplyArgTypesY(TypeFunct - arg->type = arg->type->addStorageClass(arg->storageClass); - } - } -- Lmatch: -+Lmatch: - return 1; - -- Lnomatch: -+Lnomatch: - return 0; - } - -@@ -1610,28 +1625,3 @@ void inferApplyArgTypesZ(TemplateDeclara - } - } - #endif -- --/************************************** -- */ -- --static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments) --{ -- FuncDeclaration *fd; -- -- assert(td); -- fd = td->deduceFunctionTemplate(sc, loc, targsi, ethis, arguments, 1); -- if (!fd) -- return; -- m->anyf = fd; -- if (m->last >= MATCHexact) -- { -- m->nextf = fd; -- m->count++; -- } -- else -- { -- m->last = MATCHexact; -- m->lastf = fd; -- m->count = 1; -- } --} ---- a/src/gcc/d/dfrontend/optimize.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/optimize.c 2014-04-01 16:32:51.000000000 +0100 -@@ -23,7 +23,7 @@ - #include "declaration.h" - #include "aggregate.h" - #include "init.h" -- -+#include "enum.h" - - /************************************* - * If variable has a const initializer, -@@ -44,12 +44,10 @@ Expression *expandVar(int result, VarDec - { - if (!v->type) - { -- //error("ICE"); - return e; - } - Type *tb = v->type->toBasetype(); -- if (result & WANTinterpret || -- v->storage_class & STCmanifest || -+ if ( v->storage_class & STCmanifest || - v->type->toBasetype()->isscalar() || - ((result & WANTexpand) && (tb->ty != Tsarray && tb->ty != Tstruct)) - ) -@@ -58,25 +56,25 @@ Expression *expandVar(int result, VarDec - { - if (v->inuse) - { if (v->storage_class & STCmanifest) -+ { - v->error("recursive initialization of constant"); -+ goto Lerror; -+ } - goto L1; - } -- Expression *ei = v->init->toExpression(); -+ Expression *ei = v->getConstInitializer(); - if (!ei) - { if (v->storage_class & STCmanifest) -+ { - v->error("enum cannot be initialized with %s", v->init->toChars()); -+ goto Lerror; -+ } - goto L1; - } - if (ei->op == TOKconstruct || ei->op == TOKblit) - { AssignExp *ae = (AssignExp *)ei; - ei = ae->e2; -- if (result & WANTinterpret) -- { -- v->inuse++; -- ei = ei->optimize(result); -- v->inuse--; -- } -- else if (ei->isConst() != 1 && ei->op != TOKstring) -+ if (ei->isConst() != 1 && ei->op != TOKstring) - goto L1; - - if (ei->type == v->type) -@@ -84,24 +82,19 @@ Expression *expandVar(int result, VarDec - } - else if (ei->implicitConvTo(v->type) >= MATCHconst) - { // const var initialized with non-const expression -- ei = ei->implicitCastTo(0, v->type); -- ei = ei->semantic(0); -+ ei = ei->implicitCastTo(NULL, v->type); -+ ei = ei->semantic(NULL); - } - else - goto L1; - } -- if (v->scope) -+ else if (!(v->storage_class & STCmanifest) && -+ ei->isConst() != 1 && ei->op != TOKstring && -+ ei->op != TOKaddress) - { -- v->inuse++; -- e = ei->syntaxCopy(); -- e = e->semantic(v->scope); -- e = e->implicitCastTo(v->scope, v->type); -- // enabling this line causes test22 in test suite to fail -- //ei->type = e->type; -- v->scope = NULL; -- v->inuse--; -+ goto L1; - } -- else if (!ei->type) -+ if (!ei->type) - { - goto L1; - } -@@ -132,6 +125,9 @@ Expression *expandVar(int result, VarDec - L1: - //if (e) printf("\te = %p, %s, e->type = %d, %s\n", e, e->toChars(), e->type->ty, e->type->toChars()); - return e; -+ -+Lerror: -+ return new ErrorExp(); - } - - -@@ -163,15 +159,6 @@ Expression *fromConstInitializer(int res - else - { - e = e1; -- /* If we needed to interpret, generate an error. -- * Don't give an error if it's a template parameter -- */ -- if (v && (result & WANTinterpret) && -- !(v->storage_class & STCtemplateparameter)) -- { -- e1->error("variable %s cannot be read at compile time", v->toChars()); -- e->type = Type::terror; -- } - } - } - return e; -@@ -186,15 +173,23 @@ Expression *Expression::optimize(int res - - Expression *VarExp::optimize(int result, bool keepLvalue) - { -- return keepLvalue ? this : fromConstInitializer(result, this); -+ if (keepLvalue) -+ { -+ VarDeclaration *v = var->isVarDeclaration(); -+ if (v && !(v->storage_class & STCmanifest)) -+ return this; -+ } -+ return fromConstInitializer(result, this); - } - - Expression *TupleExp::optimize(int result, bool keepLvalue) - { -+ if (e0) -+ e0 = e0->optimize(WANTvalue); - for (size_t i = 0; i < exps->dim; i++) -- { Expression *e = (*exps)[i]; -- -- e = e->optimize(WANTvalue | (result & WANTinterpret)); -+ { -+ Expression *e = (*exps)[i]; -+ e = e->optimize(WANTvalue); - (*exps)[i] = e; - } - return this; -@@ -207,7 +202,7 @@ Expression *ArrayLiteralExp::optimize(in - for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (*elements)[i]; - -- e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); -+ e = e->optimize(WANTvalue | (result & WANTexpand)); - (*elements)[i] = e; - } - } -@@ -220,11 +215,11 @@ Expression *AssocArrayLiteralExp::optimi - for (size_t i = 0; i < keys->dim; i++) - { Expression *e = (*keys)[i]; - -- e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); -+ e = e->optimize(WANTvalue | (result & WANTexpand)); - (*keys)[i] = e; - - e = (*values)[i]; -- e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); -+ e = e->optimize(WANTvalue | (result & WANTexpand)); - (*values)[i] = e; - } - return this; -@@ -232,16 +227,20 @@ Expression *AssocArrayLiteralExp::optimi - - Expression *StructLiteralExp::optimize(int result, bool keepLvalue) - { -+ if(stageflags & stageOptimize) return this; -+ int old = stageflags; -+ stageflags |= stageOptimize; - if (elements) - { - for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (*elements)[i]; - if (!e) - continue; -- e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); -+ e = e->optimize(WANTvalue | (result & WANTexpand)); - (*elements)[i] = e; - } - } -+ stageflags = old; - return this; - } - -@@ -309,6 +308,12 @@ Expression *BoolExp::optimize(int result - return e; - } - -+Expression *SymOffExp::optimize(int result, bool keepLvalue) -+{ -+ assert(var); -+ return this; -+} -+ - Expression *AddrExp::optimize(int result, bool keepLvalue) - { Expression *e; - -@@ -325,13 +330,8 @@ Expression *AddrExp::optimize(int result - return e->optimize(result); - } - -- if (e1->op == TOKvar) -- { VarExp *ve = (VarExp *)e1; -- if (ve->var->storage_class & STCmanifest) -- e1 = e1->optimize(result); -- } -- else -- e1 = e1->optimize(result); -+ // Keep lvalue-ness -+ e1 = e1->optimize(result, true); - - // Convert &*ex to ex - if (e1->op == TOKstar) -@@ -363,7 +363,7 @@ Expression *AddrExp::optimize(int result - - if (ae->e2->op == TOKint64 && ae->e1->op == TOKvar) - { -- dinteger_t index = ae->e2->toInteger(); -+ sinteger_t index = ae->e2->toInteger(); - VarExp *ve = (VarExp *)ae->e1; - if (ve->type->ty == Tsarray - && !ve->var->isImportedSymbol()) -@@ -371,7 +371,10 @@ Expression *AddrExp::optimize(int result - TypeSArray *ts = (TypeSArray *)ve->type; - sinteger_t dim = ts->dim->toInteger(); - if (index < 0 || index >= dim) -+ { - error("array index %lld is out of bounds [0..%lld]", index, dim); -+ return new ErrorExp(); -+ } - e = new SymOffExp(loc, ve->var, index * ts->nextOf()->size()); - e->type = type; - return e; -@@ -480,10 +483,6 @@ Expression *NewExp::optimize(int result, - (*arguments)[i] = e; - } - } -- if (result & WANTinterpret) -- { -- error("cannot evaluate %s at compile time", toChars()); -- } - return this; - } - -@@ -502,12 +501,8 @@ Expression *CallExp::optimize(int result - size_t pdim = Parameter::dim(tf->parameters) - (tf->varargs == 2 ? 1 : 0); - for (size_t i = 0; i < arguments->dim; i++) - { -- bool keepLvalue = false; -- if (i < pdim) -- { -- Parameter *p = Parameter::getNth(tf->parameters, i); -- keepLvalue = ((p->storageClass & (STCref | STCout)) != 0); -- } -+ Parameter *p = Parameter::getNth(tf->parameters, i); -+ bool keepLvalue = (p ? (p->storageClass & (STCref | STCout)) != 0 : false); - Expression *e = (*arguments)[i]; - e = e->optimize(WANTvalue, keepLvalue); - (*arguments)[i] = e; -@@ -519,49 +514,19 @@ Expression *CallExp::optimize(int result - return this; - - #if 1 -- if (result & WANTinterpret) -- { -- Expression *eresult = interpret(NULL); -- if (eresult == EXP_CANT_INTERPRET) -- return e; -- if (eresult && eresult != EXP_VOID_INTERPRET) -- e = eresult; -- else -- error("cannot evaluate %s at compile time", toChars()); -- } - #else - if (e1->op == TOKvar) - { - FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); - if (fd) - { -- enum BUILTIN b = fd->isBuiltin(); -+ BUILTIN b = fd->isBuiltin(); - if (b) - { - e = eval_builtin(b, arguments); - if (!e) // failed - e = this; // evaluate at runtime - } -- else if (result & WANTinterpret) -- { -- Expression *eresult = fd->interpret(NULL, arguments); -- if (eresult && eresult != EXP_VOID_INTERPRET) -- e = eresult; -- else -- error("cannot evaluate %s at compile time", toChars()); -- } -- } -- } -- else if (e1->op == TOKdotvar && result & WANTinterpret) -- { DotVarExp *dve = (DotVarExp *)e1; -- FuncDeclaration *fd = dve->var->isFuncDeclaration(); -- if (fd) -- { -- Expression *eresult = fd->interpret(NULL, arguments, dve->e1); -- if (eresult && eresult != EXP_VOID_INTERPRET) -- e = eresult; -- else -- error("cannot evaluate %s at compile time", toChars()); - } - } - #endif -@@ -577,7 +542,7 @@ Expression *CastExp::optimize(int result - //printf("e1->type %s\n", e1->type->toChars()); - //printf("type = %p\n", type); - assert(type); -- enum TOK op1 = e1->op; -+ TOK op1 = e1->op; - #define X 0 - - Expression *e1old = e1; -@@ -596,7 +561,7 @@ Expression *CastExp::optimize(int result - - if ((e1->op == TOKstring || e1->op == TOKarrayliteral) && - (type->ty == Tpointer || type->ty == Tarray) && -- e1->type->nextOf()->size() == type->nextOf()->size() -+ e1->type->toBasetype()->nextOf()->size() == type->nextOf()->size() - ) - { - Expression *e = e1->castTo(NULL, type); -@@ -688,7 +653,7 @@ Expression *BinExp::optimize(int result, - d_uns64 sz = e1->type->size() * 8; - if (i2 < 0 || i2 >= sz) - { error("shift assign by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1); -- e2 = new IntegerExp(0); -+ return new ErrorExp(); - } - } - } -@@ -701,6 +666,10 @@ Expression *AddExp::optimize(int result, - //printf("AddExp::optimize(%s)\n", toChars()); - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() && e2->isConst()) - { - if (e1->op == TOKsymoff && e2->op == TOKsymoff) -@@ -717,6 +686,10 @@ Expression *MinExp::optimize(int result, - - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() && e2->isConst()) - { - if (e2->op == TOKsymoff) -@@ -734,6 +707,10 @@ Expression *MulExp::optimize(int result, - //printf("MulExp::optimize(result = %d) %s\n", result, toChars()); - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() == 1 && e2->isConst() == 1) - { - e = Mul(type, e1, e2); -@@ -749,6 +726,10 @@ Expression *DivExp::optimize(int result, - //printf("DivExp::optimize(%s)\n", toChars()); - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() == 1 && e2->isConst() == 1) - { - e = Div(type, e1, e2); -@@ -763,6 +744,10 @@ Expression *ModExp::optimize(int result, - - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() == 1 && e2->isConst() == 1) - { - e = Mod(type, e1, e2); -@@ -777,13 +762,17 @@ Expression *shift_optimize(int result, B - - e->e1 = e->e1->optimize(result); - e->e2 = e->e2->optimize(result); -+ if (e->e1->op == TOKerror) -+ return e->e1; -+ if (e->e2->op == TOKerror) -+ return e->e2; - if (e->e2->isConst() == 1) - { - sinteger_t i2 = e->e2->toInteger(); - d_uns64 sz = e->e1->type->size() * 8; - if (i2 < 0 || i2 >= sz) - { e->error("shift by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1); -- e->e2 = new IntegerExp(0); -+ return new ErrorExp(); - } - if (e->e1->isConst() == 1) - ex = (*shift)(e->type, e->e1, e->e2); -@@ -794,19 +783,19 @@ Expression *shift_optimize(int result, B - Expression *ShlExp::optimize(int result, bool keepLvalue) - { - //printf("ShlExp::optimize(result = %d) %s\n", result, toChars()); -- return shift_optimize(result, this, Shl); -+ return shift_optimize(result, this, &Shl); - } - - Expression *ShrExp::optimize(int result, bool keepLvalue) - { - //printf("ShrExp::optimize(result = %d) %s\n", result, toChars()); -- return shift_optimize(result, this, Shr); -+ return shift_optimize(result, this, &Shr); - } - - Expression *UshrExp::optimize(int result, bool keepLvalue) - { - //printf("UshrExp::optimize(result = %d) %s\n", result, toChars()); -- return shift_optimize(result, this, Ushr); -+ return shift_optimize(result, this, &Ushr); - } - - Expression *AndExp::optimize(int result, bool keepLvalue) -@@ -814,6 +803,10 @@ Expression *AndExp::optimize(int result, - - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() == 1 && e2->isConst() == 1) - e = And(type, e1, e2); - else -@@ -826,6 +819,10 @@ Expression *OrExp::optimize(int result, - - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() == 1 && e2->isConst() == 1) - e = Or(type, e1, e2); - else -@@ -838,6 +835,10 @@ Expression *XorExp::optimize(int result, - - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - if (e1->isConst() == 1 && e2->isConst() == 1) - e = Xor(type, e1, e2); - else -@@ -850,6 +851,10 @@ Expression *PowExp::optimize(int result, - - e1 = e1->optimize(result); - e2 = e2->optimize(result); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - - // Replace 1 ^^ x or 1.0^^x by (x, 1) - if ((e1->op == TOKint64 && e1->toInteger() == 1) || -@@ -896,7 +901,7 @@ Expression *PowExp::optimize(int result, - else - { - // If e2 *could* have been an integer, make it one. -- if (e2->op == TOKfloat64 && (e2->toReal() == (real_t)(sinteger_t)(e2->toInteger()))) -+ if (e2->op == TOKfloat64 && (e2->toReal() == (sinteger_t)(e2->toReal()))) - e2 = new IntegerExp(loc, e2->toInteger(), Type::tint64); - - if (e1->isConst() == 1 && e2->isConst() == 1) -@@ -907,6 +912,21 @@ Expression *PowExp::optimize(int result, - } - e = this; - } -+ -+ if (e1->op == TOKint64 && e1->toInteger() > 0 && -+ !((e1->toInteger() - 1) & e1->toInteger()) && // is power of two -+ e2->type->isintegral() && e2->type->isunsigned()) -+ { -+ dinteger_t i = e1->toInteger(); -+ dinteger_t mul = 1; -+ while ((i >>= 1) > 1) -+ mul++; -+ Expression *shift = new MulExp(loc, e2, new IntegerExp(loc, mul, e2->type)); -+ shift->type = Type::tshiftcnt; -+ e = new ShlExp(loc, new IntegerExp(loc, 1, e1->type), shift); -+ e->type = type; -+ } -+ - return e; - } - -@@ -920,15 +940,10 @@ Expression *CommaExp::optimize(int resul - // In particular, if the comma returns a temporary variable, it needs - // to be an lvalue (this is particularly important for struct constructors) - -- if (result & WANTinterpret) -- { // Interpreting comma needs special treatment, because it may -- // contain compiler-generated declarations. -- e = interpret(NULL); -- return (e == EXP_CANT_INTERPRET) ? this : e; -- } -- -- e1 = e1->optimize(result & WANTinterpret); -+ e1 = e1->optimize(0); - e2 = e2->optimize(result, keepLvalue); -+ if (e1->op == TOKerror) -+ return e1; - if (!e1 || e1->op == TOKint64 || e1->op == TOKfloat64 || !e1->hasSideEffect()) - { - e = e2; -@@ -945,9 +960,12 @@ Expression *ArrayLengthExp::optimize(int - { Expression *e; - - //printf("ArrayLengthExp::optimize(result = %d) %s\n", result, toChars()); -- e1 = e1->optimize(WANTvalue | WANTexpand | (result & WANTinterpret)); -+ e1 = e1->optimize(WANTvalue | WANTexpand); -+ if (e1->op == TOKerror) -+ return e1; - e = this; -- if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKassocarrayliteral) -+ if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKassocarrayliteral || -+ e1->type->toBasetype()->ty == Tsarray) - { - e = ArrayLength(type, e1); - } -@@ -957,11 +975,15 @@ Expression *ArrayLengthExp::optimize(int - Expression *EqualExp::optimize(int result, bool keepLvalue) - { - //printf("EqualExp::optimize(result = %x) %s\n", result, toChars()); -- e1 = e1->optimize(WANTvalue | (result & WANTinterpret)); -- e2 = e2->optimize(WANTvalue | (result & WANTinterpret)); -+ e1 = e1->optimize(WANTvalue); -+ e2 = e2->optimize(WANTvalue); - - Expression *e1 = fromConstInitializer(result, this->e1); - Expression *e2 = fromConstInitializer(result, this->e2); -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; - - Expression *e = Equal(op, type, e1, e2); - if (e == EXP_CANT_INTERPRET) -@@ -972,12 +994,19 @@ Expression *EqualExp::optimize(int resul - Expression *IdentityExp::optimize(int result, bool keepLvalue) - { - //printf("IdentityExp::optimize(result = %d) %s\n", result, toChars()); -- e1 = e1->optimize(WANTvalue | (result & WANTinterpret)); -- e2 = e2->optimize(WANTvalue | (result & WANTinterpret)); -+ e1 = e1->optimize(WANTvalue); -+ e2 = e2->optimize(WANTvalue); -+ -+ if (e1->op == TOKerror) -+ return e1; -+ if (e2->op == TOKerror) -+ return e2; -+ - Expression *e = this; - - if ((this->e1->isConst() && this->e2->isConst()) || -- (this->e1->op == TOKnull && this->e2->op == TOKnull)) -+ (this->e1->op == TOKnull && this->e2->op == TOKnull) -+ ) - { - e = Identity(op, type, this->e1, this->e2); - if (e == EXP_CANT_INTERPRET) -@@ -1010,8 +1039,8 @@ void setLengthVarIfKnown(VarDeclaration - return; // we don't know the length yet - } - -- Expression *dollar = new IntegerExp(0, len, Type::tsize_t); -- lengthVar->init = new ExpInitializer(0, dollar); -+ Expression *dollar = new IntegerExp(Loc(), len, Type::tsize_t); -+ lengthVar->init = new ExpInitializer(Loc(), dollar); - lengthVar->storage_class |= STCstatic | STCconst; - } - -@@ -1020,25 +1049,16 @@ Expression *IndexExp::optimize(int resul - { Expression *e; - - //printf("IndexExp::optimize(result = %d) %s\n", result, toChars()); -- Expression *e1 = this->e1->optimize( -- WANTvalue | (result & (WANTinterpret| WANTexpand))); -- e1 = fromConstInitializer(result, e1); -- if (this->e1->op == TOKvar) -- { VarExp *ve = (VarExp *)this->e1; -- if (ve->var->storage_class & STCmanifest) -- { /* We generally don't want to have more than one copy of an -- * array literal, but if it's an enum we have to because the -- * enum isn't stored elsewhere. See Bugzilla 2559 -- */ -- this->e1 = e1; -- } -- } -+ e1 = e1->optimize(WANTvalue | (result & WANTexpand)); -+ -+ Expression *ex = fromConstInitializer(result, e1); -+ - // We might know $ now -- setLengthVarIfKnown(lengthVar, e1); -- e2 = e2->optimize(WANTvalue | (result & WANTinterpret)); -+ setLengthVarIfKnown(lengthVar, ex); -+ e2 = e2->optimize(WANTvalue); - if (keepLvalue) - return this; -- e = Index(type, e1, e2); -+ e = Index(type, ex, e2); - if (e == EXP_CANT_INTERPRET) - e = this; - return e; -@@ -1050,7 +1070,7 @@ Expression *SliceExp::optimize(int resul - - //printf("SliceExp::optimize(result = %d) %s\n", result, toChars()); - e = this; -- e1 = e1->optimize(WANTvalue | (result & (WANTinterpret|WANTexpand))); -+ e1 = e1->optimize(WANTvalue | (result & WANTexpand)); - if (!lwr) - { if (e1->op == TOKstring) - { // Convert slice of string literal into dynamic array -@@ -1063,8 +1083,8 @@ Expression *SliceExp::optimize(int resul - e1 = fromConstInitializer(result, e1); - // We might know $ now - setLengthVarIfKnown(lengthVar, e1); -- lwr = lwr->optimize(WANTvalue | (result & WANTinterpret)); -- upr = upr->optimize(WANTvalue | (result & WANTinterpret)); -+ lwr = lwr->optimize(WANTvalue); -+ upr = upr->optimize(WANTvalue); - e = Slice(type, e1, lwr, upr); - if (e == EXP_CANT_INTERPRET) - e = this; -@@ -1076,7 +1096,9 @@ Expression *AndAndExp::optimize(int resu - { Expression *e; - - //printf("AndAndExp::optimize(%d) %s\n", result, toChars()); -- e1 = e1->optimize(WANTflags | (result & WANTinterpret)); -+ e1 = e1->optimize(WANTflags); -+ if (e1->op == TOKerror) -+ return e1; - e = this; - if (e1->isBool(FALSE)) - { -@@ -1090,9 +1112,12 @@ Expression *AndAndExp::optimize(int resu - } - else - { -- e2 = e2->optimize(WANTflags | (result & WANTinterpret)); -+ e2 = e2->optimize(WANTflags); - if (result && e2->type->toBasetype()->ty == Tvoid && !global.errors) -+ { - error("void has no value"); -+ return new ErrorExp(); -+ } - if (e1->isConst()) - { - if (e2->isConst()) -@@ -1115,7 +1140,9 @@ Expression *AndAndExp::optimize(int resu - Expression *OrOrExp::optimize(int result, bool keepLvalue) - { Expression *e; - -- e1 = e1->optimize(WANTflags | (result & WANTinterpret)); -+ e1 = e1->optimize(WANTflags); -+ if (e1->op == TOKerror) -+ return e1; - e = this; - if (e1->isBool(TRUE)) - { // Replace with (e1, 1) -@@ -1125,9 +1152,12 @@ Expression *OrOrExp::optimize(int result - } - else - { -- e2 = e2->optimize(WANTflags | (result & WANTinterpret)); -+ e2 = e2->optimize(WANTflags); - if (result && e2->type->toBasetype()->ty == Tvoid && !global.errors) -+ { - error("void has no value"); -+ return new ErrorExp(); -+ } - if (e1->isConst()) - { - if (e2->isConst()) -@@ -1152,8 +1182,8 @@ Expression *CmpExp::optimize(int result, - { Expression *e; - - //printf("CmpExp::optimize() %s\n", toChars()); -- e1 = e1->optimize(WANTvalue | (result & WANTinterpret)); -- e2 = e2->optimize(WANTvalue | (result & WANTinterpret)); -+ e1 = e1->optimize(WANTvalue); -+ e2 = e2->optimize(WANTvalue); - - Expression *e1 = fromConstInitializer(result, this->e1); - Expression *e2 = fromConstInitializer(result, this->e2); -@@ -1180,7 +1210,7 @@ Expression *CatExp::optimize(int result, - Expression *CondExp::optimize(int result, bool keepLvalue) - { Expression *e; - -- econd = econd->optimize(WANTflags | (result & WANTinterpret)); -+ econd = econd->optimize(WANTflags); - if (econd->isBool(TRUE)) - e = e1->optimize(result, keepLvalue); - else if (econd->isBool(FALSE)) ---- a/src/gcc/d/dfrontend/outbuffer.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/outbuffer.c 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,412 @@ -+ -+// Copyright (c) 1999-2012 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "outbuffer.h" -+#include "object.h" -+#include "rmem.h" -+ -+OutBuffer::OutBuffer() -+{ -+ data = NULL; -+ offset = 0; -+ size = 0; -+ -+ doindent = 0; -+ level = 0; -+ notlinehead = 0; -+} -+ -+OutBuffer::~OutBuffer() -+{ -+ mem.free(data); -+} -+ -+char *OutBuffer::extractData() -+{ -+ char *p; -+ -+ p = (char *)data; -+ data = NULL; -+ offset = 0; -+ size = 0; -+ return p; -+} -+ -+void OutBuffer::reserve(size_t nbytes) -+{ -+ //printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes); -+ if (size - offset < nbytes) -+ { -+ size = (offset + nbytes) * 2; -+ size = (size + 15) & ~15; -+ data = (utf8_t *)mem.realloc(data, size); -+ } -+} -+ -+void OutBuffer::reset() -+{ -+ offset = 0; -+} -+ -+void OutBuffer::setsize(size_t size) -+{ -+ offset = size; -+} -+ -+void OutBuffer::write(const void *data, size_t nbytes) -+{ -+ if (doindent && !notlinehead) -+ { -+ if (level) -+ { -+ reserve(level); -+ for (size_t i=0; idata[offset] = '\t'; -+ offset++; -+ } -+ } -+ notlinehead = 1; -+ } -+ reserve(nbytes); -+ memcpy(this->data + offset, data, nbytes); -+ offset += nbytes; -+} -+ -+void OutBuffer::writebstring(utf8_t *string) -+{ -+ write(string,*string + 1); -+} -+ -+void OutBuffer::writestring(const char *string) -+{ -+ write(string,strlen(string)); -+} -+ -+void OutBuffer::prependstring(const char *string) -+{ -+ size_t len = strlen(string); -+ reserve(len); -+ memmove(data + len, data, offset); -+ memcpy(data, string, len); -+ offset += len; -+} -+ -+void OutBuffer::writenl() -+{ -+#if _WIN32 -+ writeword(0x0A0D); // newline is CR,LF on Microsoft OS's -+#else -+ writeByte('\n'); -+#endif -+ if (doindent) -+ notlinehead = 0; -+} -+ -+void OutBuffer::writeByte(unsigned b) -+{ -+ if (doindent && !notlinehead -+ && b != '\n') -+ { -+ if (level) -+ { -+ reserve(level); -+ for (size_t i=0; idata[offset] = '\t'; -+ offset++; -+ } -+ } -+ notlinehead = 1; -+ } -+ reserve(1); -+ this->data[offset] = (unsigned char)b; -+ offset++; -+} -+ -+void OutBuffer::writeUTF8(unsigned b) -+{ -+ reserve(6); -+ if (b <= 0x7F) -+ { -+ this->data[offset] = (unsigned char)b; -+ offset++; -+ } -+ else if (b <= 0x7FF) -+ { -+ this->data[offset + 0] = (unsigned char)((b >> 6) | 0xC0); -+ this->data[offset + 1] = (unsigned char)((b & 0x3F) | 0x80); -+ offset += 2; -+ } -+ else if (b <= 0xFFFF) -+ { -+ this->data[offset + 0] = (unsigned char)((b >> 12) | 0xE0); -+ this->data[offset + 1] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -+ this->data[offset + 2] = (unsigned char)((b & 0x3F) | 0x80); -+ offset += 3; -+ } -+ else if (b <= 0x1FFFFF) -+ { -+ this->data[offset + 0] = (unsigned char)((b >> 18) | 0xF0); -+ this->data[offset + 1] = (unsigned char)(((b >> 12) & 0x3F) | 0x80); -+ this->data[offset + 2] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -+ this->data[offset + 3] = (unsigned char)((b & 0x3F) | 0x80); -+ offset += 4; -+ } -+ else if (b <= 0x3FFFFFF) -+ { -+ this->data[offset + 0] = (unsigned char)((b >> 24) | 0xF8); -+ this->data[offset + 1] = (unsigned char)(((b >> 18) & 0x3F) | 0x80); -+ this->data[offset + 2] = (unsigned char)(((b >> 12) & 0x3F) | 0x80); -+ this->data[offset + 3] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -+ this->data[offset + 4] = (unsigned char)((b & 0x3F) | 0x80); -+ offset += 5; -+ } -+ else if (b <= 0x7FFFFFFF) -+ { -+ this->data[offset + 0] = (unsigned char)((b >> 30) | 0xFC); -+ this->data[offset + 1] = (unsigned char)(((b >> 24) & 0x3F) | 0x80); -+ this->data[offset + 2] = (unsigned char)(((b >> 18) & 0x3F) | 0x80); -+ this->data[offset + 3] = (unsigned char)(((b >> 12) & 0x3F) | 0x80); -+ this->data[offset + 4] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -+ this->data[offset + 5] = (unsigned char)((b & 0x3F) | 0x80); -+ offset += 6; -+ } -+ else -+ assert(0); -+} -+ -+void OutBuffer::prependbyte(unsigned b) -+{ -+ reserve(1); -+ memmove(data + 1, data, offset); -+ data[0] = (unsigned char)b; -+ offset++; -+} -+ -+void OutBuffer::writewchar(unsigned w) -+{ -+#if _WIN32 -+ writeword(w); -+#else -+ write4(w); -+#endif -+} -+ -+void OutBuffer::writeword(unsigned w) -+{ -+#if _WIN32 -+ unsigned newline = 0x0A0D; -+#else -+ unsigned newline = '\n'; -+#endif -+ if (doindent && !notlinehead -+ && w != newline) -+ { -+ if (level) -+ { -+ reserve(level); -+ for (size_t i=0; idata[offset] = '\t'; -+ offset++; -+ } -+ } -+ notlinehead = 1; -+ } -+ reserve(2); -+ *(unsigned short *)(this->data + offset) = (unsigned short)w; -+ offset += 2; -+} -+ -+void OutBuffer::writeUTF16(unsigned w) -+{ -+ reserve(4); -+ if (w <= 0xFFFF) -+ { -+ *(unsigned short *)(this->data + offset) = (unsigned short)w; -+ offset += 2; -+ } -+ else if (w <= 0x10FFFF) -+ { -+ *(unsigned short *)(this->data + offset) = (unsigned short)((w >> 10) + 0xD7C0); -+ *(unsigned short *)(this->data + offset + 2) = (unsigned short)((w & 0x3FF) | 0xDC00); -+ offset += 4; -+ } -+ else -+ assert(0); -+} -+ -+void OutBuffer::write4(unsigned w) -+{ -+#if _WIN32 -+ bool notnewline = w != 0x000A000D; -+#else -+ bool notnewline = true; -+#endif -+ if (doindent && !notlinehead && notnewline) -+ { -+ if (level) -+ { -+ reserve(level); -+ for (size_t i=0; idata[offset] = '\t'; -+ offset++; -+ } -+ } -+ notlinehead = 1; -+ } -+ reserve(4); -+ *(unsigned *)(this->data + offset) = w; -+ offset += 4; -+} -+ -+void OutBuffer::write(OutBuffer *buf) -+{ -+ if (buf) -+ { reserve(buf->offset); -+ memcpy(data + offset, buf->data, buf->offset); -+ offset += buf->offset; -+ } -+} -+ -+void OutBuffer::write(RootObject *obj) -+{ -+ if (obj) -+ { -+ writestring(obj->toChars()); -+ } -+} -+ -+void OutBuffer::fill0(size_t nbytes) -+{ -+ reserve(nbytes); -+ memset(data + offset,0,nbytes); -+ offset += nbytes; -+} -+ -+void OutBuffer::align(size_t size) -+{ -+ size_t nbytes = ((offset + size - 1) & ~(size - 1)) - offset; -+ fill0(nbytes); -+} -+ -+void OutBuffer::vprintf(const char *format, va_list args) -+{ -+ char buffer[128]; -+ char *p; -+ unsigned psize; -+ int count; -+ -+ p = buffer; -+ psize = sizeof(buffer); -+ for (;;) -+ { -+#if _WIN32 -+ count = _vsnprintf(p,psize,format,args); -+ if (count != -1) -+ break; -+ psize *= 2; -+#elif POSIX -+ va_list va; -+ va_copy(va, args); -+/* -+ The functions vprintf(), vfprintf(), vsprintf(), vsnprintf() -+ are equivalent to the functions printf(), fprintf(), sprintf(), -+ snprintf(), respectively, except that they are called with a -+ va_list instead of a variable number of arguments. These -+ functions do not call the va_end macro. Consequently, the value -+ of ap is undefined after the call. The application should call -+ va_end(ap) itself afterwards. -+ */ -+ count = vsnprintf(p,psize,format,va); -+ va_end(va); -+ if (count == -1) -+ psize *= 2; -+ else if (count >= psize) -+ psize = count + 1; -+ else -+ break; -+#else -+ assert(0); -+#endif -+ p = (char *) alloca(psize); // buffer too small, try again with larger size -+ } -+ write(p,count); -+} -+ -+void OutBuffer::printf(const char *format, ...) -+{ -+ va_list ap; -+ va_start(ap, format); -+ vprintf(format,ap); -+ va_end(ap); -+} -+ -+void OutBuffer::bracket(char left, char right) -+{ -+ reserve(2); -+ memmove(data + 1, data, offset); -+ data[0] = left; -+ data[offset + 1] = right; -+ offset += 2; -+} -+ -+/****************** -+ * Insert left at i, and right at j. -+ * Return index just past right. -+ */ -+ -+size_t OutBuffer::bracket(size_t i, const char *left, size_t j, const char *right) -+{ -+ size_t leftlen = strlen(left); -+ size_t rightlen = strlen(right); -+ reserve(leftlen + rightlen); -+ insert(i, left, leftlen); -+ insert(j + leftlen, right, rightlen); -+ return j + leftlen + rightlen; -+} -+ -+void OutBuffer::spread(size_t offset, size_t nbytes) -+{ -+ reserve(nbytes); -+ memmove(data + offset + nbytes, data + offset, -+ this->offset - offset); -+ this->offset += nbytes; -+} -+ -+/**************************************** -+ * Returns: offset + nbytes -+ */ -+ -+size_t OutBuffer::insert(size_t offset, const void *p, size_t nbytes) -+{ -+ spread(offset, nbytes); -+ memmove(data + offset, p, nbytes); -+ return offset + nbytes; -+} -+ -+void OutBuffer::remove(size_t offset, size_t nbytes) -+{ -+ memmove(data + offset, data + offset + nbytes, this->offset - (offset + nbytes)); -+ this->offset -= nbytes; -+} -+ -+char *OutBuffer::toChars() -+{ -+ writeByte(0); -+ return (char *)data; -+} ---- a/src/gcc/d/dfrontend/outbuffer.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/outbuffer.h 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,70 @@ -+ -+// Copyright (c) 1999-2011 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#ifndef OUTBUFFER_H -+#define OUTBUFFER_H -+ -+#include -+#include -+#include -+#include -+#include "port.h" -+ -+#if __DMC__ -+#pragma once -+#endif -+ -+class RootObject; -+ -+struct OutBuffer -+{ -+ unsigned char *data; -+ size_t offset; -+ size_t size; -+ -+ int doindent; -+ int level; -+ int notlinehead; -+ -+ OutBuffer(); -+ ~OutBuffer(); -+ char *extractData(); -+ -+ void reserve(size_t nbytes); -+ void setsize(size_t size); -+ void reset(); -+ void write(const void *data, size_t nbytes); -+ void writebstring(utf8_t *string); -+ void writestring(const char *string); -+ void prependstring(const char *string); -+ void writenl(); // write newline -+ void writeByte(unsigned b); -+ void writebyte(unsigned b) { writeByte(b); } -+ void writeUTF8(unsigned b); -+ void prependbyte(unsigned b); -+ void writewchar(unsigned w); -+ void writeword(unsigned w); -+ void writeUTF16(unsigned w); -+ void write4(unsigned w); -+ void write(OutBuffer *buf); -+ void write(RootObject *obj); -+ void fill0(size_t nbytes); -+ void align(size_t size); -+ void vprintf(const char *format, va_list args); -+ void printf(const char *format, ...); -+ void bracket(char left, char right); -+ size_t bracket(size_t i, const char *left, size_t j, const char *right); -+ void spread(size_t offset, size_t nbytes); -+ size_t insert(size_t offset, const void *data, size_t nbytes); -+ void remove(size_t offset, size_t nbytes); -+ char *toChars(); -+ char *extractString(); -+}; -+ -+#endif ---- a/src/gcc/d/dfrontend/parse.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/parse.c 2014-04-01 16:32:51.000000000 +0100 -@@ -55,15 +55,15 @@ - // Support D1 inout - #define D1INOUT 0 - --Parser::Parser(Module *module, unsigned char *base, size_t length, int doDocComment) -+Parser::Parser(Module *module, utf8_t *base, size_t length, int doDocComment) - : Lexer(module, base, 0, length, doDocComment, 0) - { - //printf("Parser::Parser()\n"); - md = NULL; - linkage = LINKd; -- endloc = 0; -+ endloc = Loc(); - inBrackets = 0; -- lookingForElse = 0; -+ lookingForElse = Loc(); - //nextToken(); // start up the scanner - } - -@@ -74,7 +74,8 @@ Dsymbols *Parser::parseModule() - // ModuleDeclation leads off - if (token.value == TOKmodule) - { -- unsigned char *comment = token.blockComment; -+ Loc loc = token.loc; -+ utf8_t *comment = token.blockComment; - bool safe = FALSE; - - nextToken(); -@@ -120,7 +121,7 @@ Dsymbols *Parser::parseModule() - id = token.ident; - } - -- md = new ModuleDeclaration(a, id, safe); -+ md = new ModuleDeclaration(loc, a, id, safe); - - if (token.value != TOKsemicolon) - error("';' expected following module declaration instead of %s", token.toChars()); -@@ -131,7 +132,8 @@ Dsymbols *Parser::parseModule() - - decldefs = parseDeclDefs(0); - if (token.value != TOKeof) -- { error(loc, "unrecognized declaration"); -+ { -+ error(token.loc, "unrecognized declaration"); - goto Lerr; - } - return decldefs; -@@ -143,16 +145,19 @@ Lerr: - return new Dsymbols(); - } - --Dsymbols *Parser::parseDeclDefs(int once) -+Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl) - { Dsymbol *s; - Dsymbols *decldefs; - Dsymbols *a; - Dsymbols *aelse; -- enum PROT prot; -+ PROT prot; - StorageClass stc; - StorageClass storageClass; - Condition *condition; -- unsigned char *comment; -+ utf8_t *comment; -+ Dsymbol *lastDecl = NULL; // used to link unittest to its previous declaration -+ if (!pLastDecl) -+ pLastDecl = &lastDecl; - - //printf("Parser::parseDeclDefs()\n"); - decldefs = new Dsymbols(); -@@ -192,7 +197,8 @@ Dsymbols *Parser::parseDeclDefs(int once - break; - - case TOKmixin: -- { Loc loc = this->loc; -+ { -+ Loc loc = token.loc; - switch (peekNext()) - { - case TOKlparen: -@@ -232,6 +238,7 @@ Dsymbols *Parser::parseDeclDefs(int once - case TOKinterface: - Ldeclaration: - a = parseDeclarations(STCundefined, NULL); -+ if (a->dim) *pLastDecl = (*a)[a->dim-1]; - decldefs->append(a); - continue; - -@@ -260,7 +267,7 @@ Dsymbols *Parser::parseDeclDefs(int once - } - else - { -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - stc = STCimmutable; - goto Lstc; - } -@@ -269,20 +276,7 @@ Dsymbols *Parser::parseDeclDefs(int once - - case TOKunittest: - s = parseUnitTest(); -- if (decldefs && decldefs->dim) -- { -- Dsymbol *ds = (*decldefs)[decldefs->dim-1]; -- AttribDeclaration *ad; -- while ((ad = ds->isAttribDeclaration()) != NULL) -- { -- if (ad->decl && ad->decl->dim) -- ds = (*ad->decl)[ad->decl->dim-1]; -- else -- break; -- } -- -- ds->unittest = (UnitTestDeclaration *)s; -- } -+ if (*pLastDecl) (*pLastDecl)->ddocUnittest = (UnitTestDeclaration *)s; - break; - - case TOKnew: -@@ -308,17 +302,23 @@ Dsymbols *Parser::parseDeclDefs(int once - else if (token.value == TOKassert) - s = parseStaticAssert(); - else if (token.value == TOKif) -- { condition = parseStaticIfCondition(); -- Loc lookingForElseSave = lookingForElse; -- lookingForElse = loc; -- a = parseBlock(); -- lookingForElse = lookingForElseSave; -+ { -+ condition = parseStaticIfCondition(); -+ if (token.value == TOKcolon) -+ a = parseBlock(pLastDecl); -+ else -+ { -+ Loc lookingForElseSave = lookingForElse; -+ lookingForElse = token.loc; -+ a = parseBlock(pLastDecl); -+ lookingForElse = lookingForElseSave; -+ } - aelse = NULL; - if (token.value == TOKelse) - { -- Loc elseloc = this->loc; -+ Loc elseloc = token.loc; - nextToken(); -- aelse = parseBlock(); -+ aelse = parseBlock(pLastDecl); - checkDanglingElse(elseloc); - } - s = new StaticIfDeclaration(condition, a, aelse); -@@ -381,7 +381,6 @@ Dsymbols *Parser::parseDeclDefs(int once - case TOKnothrow: stc = STCnothrow; goto Lstc; - case TOKpure: stc = STCpure; goto Lstc; - case TOKref: stc = STCref; goto Lstc; -- case TOKtls: stc = STCtls; goto Lstc; - case TOKgshared: stc = STCgshared; goto Lstc; - //case TOKmanifest: stc = STCmanifest; goto Lstc; - case TOKat: -@@ -390,7 +389,7 @@ Dsymbols *Parser::parseDeclDefs(int once - stc = parseAttribute(&exps); - if (stc) - goto Lstc; // it's a predefined attribute -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new UserAttributeDeclaration(exps, a); - break; - } -@@ -398,7 +397,7 @@ Dsymbols *Parser::parseDeclDefs(int once - - Lstc: - if (storageClass & stc) -- error("redundant storage class %s", Token::toChars(token.value)); -+ error("redundant storage class '%s'", Token::toChars(token.value)); - composeStorageClass(storageClass | stc); - nextToken(); - Lstc2: -@@ -428,7 +427,7 @@ Dsymbols *Parser::parseDeclDefs(int once - else - { - if (token.value == TOKinvariant) -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - stc = STCimmutable; - } - goto Lstc; -@@ -446,7 +445,6 @@ Dsymbols *Parser::parseDeclDefs(int once - case TOKnothrow: stc = STCnothrow; goto Lstc; - case TOKpure: stc = STCpure; goto Lstc; - case TOKref: stc = STCref; goto Lstc; -- case TOKtls: stc = STCtls; goto Lstc; - case TOKgshared: stc = STCgshared; goto Lstc; - //case TOKmanifest: stc = STCmanifest; goto Lstc; - case TOKat: -@@ -468,6 +466,7 @@ Dsymbols *Parser::parseDeclDefs(int once - peek(&token)->value == TOKassign) - { - a = parseAutoDeclarations(storageClass, comment); -+ if (a->dim) *pLastDecl = (*a)[a->dim-1]; - decldefs->append(a); - continue; - } -@@ -488,10 +487,11 @@ Dsymbols *Parser::parseDeclDefs(int once - ) - { - a = parseDeclarations(storageClass, comment); -+ if (a->dim) *pLastDecl = (*a)[a->dim-1]; - decldefs->append(a); - continue; - } -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new StorageClassDeclaration(storageClass, a); - break; - -@@ -506,16 +506,16 @@ Dsymbols *Parser::parseDeclDefs(int once - check(TOKlparen); - Expression *e = parseAssignExp(); - check(TOKrparen); -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new DeprecatedDeclaration(e, a); - break; - } - - case TOKlbracket: - { -- warning(loc, "use @(attributes) instead of [attributes]"); -+ warning(token.loc, "use @(attributes) instead of [attributes]"); - Expressions *exps = parseArguments(); -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new UserAttributeDeclaration(exps, a); - break; - } -@@ -526,9 +526,9 @@ Dsymbols *Parser::parseDeclDefs(int once - goto Lstc; - } - { -- enum LINK linksave = linkage; -+ LINK linksave = linkage; - linkage = parseLinkage(); -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new LinkDeclaration(linkage, a); - linkage = linksave; - break; -@@ -552,7 +552,7 @@ Dsymbols *Parser::parseDeclDefs(int once - break; - default: break; - } -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new ProtDeclaration(prot, a); - break; - -@@ -578,16 +578,17 @@ Dsymbols *Parser::parseDeclDefs(int once - check(TOKrparen); - } - else -- n = global.structalign; // default -+ n = STRUCTALIGN_DEFAULT; // default - -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new AlignDeclaration(n, a); - break; - } - - case TOKpragma: -- { Identifier *ident; -+ { - Expressions *args = NULL; -+ Loc loc = token.loc; - - nextToken(); - check(TOKlparen); -@@ -595,7 +596,7 @@ Dsymbols *Parser::parseDeclDefs(int once - { error("pragma(identifier) expected"); - goto Lerror; - } -- ident = token.ident; -+ Identifier *ident = token.ident; - nextToken(); - if (token.value == TOKcomma && peekNext() != TOKrparen) - args = parseArguments(); // pragma(identifier, args...) -@@ -605,7 +606,7 @@ Dsymbols *Parser::parseDeclDefs(int once - if (token.value == TOKsemicolon) - a = NULL; - else -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - s = new PragmaDeclaration(loc, ident, args, a); - break; - } -@@ -616,9 +617,9 @@ Dsymbols *Parser::parseDeclDefs(int once - { - nextToken(); - if (token.value == TOKidentifier) -- s = new DebugSymbol(loc, token.ident); -+ s = new DebugSymbol(token.loc, token.ident); - else if (token.value == TOKint32v || token.value == TOKint64v) -- s = new DebugSymbol(loc, (unsigned)token.uns64value); -+ s = new DebugSymbol(token.loc, (unsigned)token.uns64value); - else - { error("identifier or integer expected, not %s", token.toChars()); - s = NULL; -@@ -639,9 +640,9 @@ Dsymbols *Parser::parseDeclDefs(int once - { - nextToken(); - if (token.value == TOKidentifier) -- s = new VersionSymbol(loc, token.ident); -+ s = new VersionSymbol(token.loc, token.ident); - else if (token.value == TOKint32v || token.value == TOKint64v) -- s = new VersionSymbol(loc, (unsigned)token.uns64value); -+ s = new VersionSymbol(token.loc, (unsigned)token.uns64value); - else - { error("identifier or integer expected, not %s", token.toChars()); - s = NULL; -@@ -658,21 +659,21 @@ Dsymbols *Parser::parseDeclDefs(int once - Lcondition: - { - if (token.value == TOKcolon) -- a = parseBlock(); -+ a = parseBlock(pLastDecl); - else - { - Loc lookingForElseSave = lookingForElse; -- lookingForElse = loc; -- a = parseBlock(); -+ lookingForElse = token.loc; -+ a = parseBlock(pLastDecl); - lookingForElse = lookingForElseSave; - } - } - aelse = NULL; - if (token.value == TOKelse) - { -- Loc elseloc = this->loc; -+ Loc elseloc = token.loc; - nextToken(); -- aelse = parseBlock(); -+ aelse = parseBlock(pLastDecl); - checkDanglingElse(elseloc); - } - s = new ConditionalDeclaration(condition, a, aelse); -@@ -695,6 +696,8 @@ Dsymbols *Parser::parseDeclDefs(int once - if (s) - { decldefs->push(s); - addComment(s, comment); -+ if (!s->isAttribDeclaration()) -+ *pLastDecl = s; - } - } while (!once); - return decldefs; -@@ -755,7 +758,10 @@ StorageClass Parser::parseAttribute(Expr - { // Allow identifier, template instantiation, or function call - Expression *exp = parsePrimaryExp(); - if (token.value == TOKlparen) -+ { -+ Loc loc = token.loc; - exp = new CallExp(loc, exp, parseArguments()); -+ } - - udas = new Expressions(); - udas->push(exp); -@@ -798,7 +804,7 @@ StorageClass Parser::parsePostfix() - { - case TOKconst: stc |= STCconst; break; - case TOKinvariant: -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - case TOKimmutable: stc |= STCimmutable; break; - case TOKshared: stc |= STCshared; break; - case TOKwild: stc |= STCwild; break; -@@ -832,7 +838,7 @@ StorageClass Parser::parseTypeCtor() - { - case TOKconst: stc |= STCconst; break; - case TOKinvariant: -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - case TOKimmutable: stc |= STCimmutable; break; - case TOKshared: stc |= STCshared; break; - case TOKwild: stc |= STCwild; break; -@@ -848,7 +854,7 @@ StorageClass Parser::parseTypeCtor() - * Parse declarations after an align, protection, or extern decl. - */ - --Dsymbols *Parser::parseBlock() -+Dsymbols *Parser::parseBlock(Dsymbol **pLastDecl) - { - Dsymbols *a = NULL; - -@@ -867,10 +873,10 @@ Dsymbols *Parser::parseBlock() - case TOKlcurly: - { - Loc lookingForElseSave = lookingForElse; -- lookingForElse = 0; -+ lookingForElse = Loc(); - - nextToken(); -- a = parseDeclDefs(0); -+ a = parseDeclDefs(0, pLastDecl); - if (token.value != TOKrcurly) - { /* { */ - error("matching '}' expected, not %s", token.toChars()); -@@ -886,12 +892,12 @@ Dsymbols *Parser::parseBlock() - #if 0 - a = NULL; - #else -- a = parseDeclDefs(0); // grab declarations up to closing curly bracket -+ a = parseDeclDefs(0, pLastDecl); // grab declarations up to closing curly bracket - #endif - break; - - default: -- a = parseDeclDefs(1); -+ a = parseDeclDefs(1, pLastDecl); - break; - } - return a; -@@ -903,7 +909,7 @@ Dsymbols *Parser::parseBlock() - - StaticAssert *Parser::parseStaticAssert() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - Expression *exp; - Expression *msg = NULL; - -@@ -927,8 +933,9 @@ StaticAssert *Parser::parseStaticAssert( - - #if DMDV2 - TypeQualified *Parser::parseTypeof() --{ TypeQualified *t; -- Loc loc = this->loc; -+{ -+ TypeQualified *t; -+ Loc loc = token.loc; - - nextToken(); - check(TOKlparen); -@@ -938,7 +945,8 @@ TypeQualified *Parser::parseTypeof() - t = new TypeReturn(loc); - } - else -- { Expression *exp = parseExpression(); // typeof(expression) -+ { -+ Expression *exp = parseExpression(); // typeof(expression) - t = new TypeTypeof(loc, exp); - } - check(TOKrparen); -@@ -954,7 +962,7 @@ TypeQualified *Parser::parseTypeof() - #if DMDV2 - Type *Parser::parseVector() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - nextToken(); - check(TOKlparen); - Type *tb = parseType(); -@@ -968,9 +976,9 @@ Type *Parser::parseVector() - * The parser is on the 'extern' token. - */ - --enum LINK Parser::parseLinkage() -+LINK Parser::parseLinkage() - { -- enum LINK link = LINKdefault; -+ LINK link = LINKdefault; - nextToken(); - assert(token.value == TOKlparen); - nextToken(); -@@ -1089,9 +1097,10 @@ Condition *Parser::parseVersionCondition - */ - - Condition *Parser::parseStaticIfCondition() --{ Expression *exp; -+{ -+ Expression *exp; - Condition *condition; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - if (token.value == TOKlparen) -@@ -1101,7 +1110,8 @@ Condition *Parser::parseStaticIfConditio - check(TOKrparen); - } - else -- { error("(expression) expected following static if"); -+ { -+ error("(expression) expected following static if"); - exp = NULL; - } - condition = new StaticIfCondition(loc, exp); -@@ -1121,16 +1131,17 @@ Condition *Parser::parseStaticIfConditio - - Dsymbol *Parser::parseCtor() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); -- if (token.value == TOKlparen && peek(&token)->value == TOKthis) -- { // this(this) { ... } -+ if (token.value == TOKlparen && peekNext() == TOKthis && peekNext2() == TOKrparen) -+ { -+ // this(this) { ... } - nextToken(); - nextToken(); - check(TOKrparen); - StorageClass stc = parsePostfix(); -- PostBlitDeclaration *f = new PostBlitDeclaration(loc, 0, stc, Id::_postblit); -+ PostBlitDeclaration *f = new PostBlitDeclaration(loc, Loc(), stc, Id::_postblit); - parseContracts(f); - return f; - } -@@ -1141,7 +1152,8 @@ Dsymbol *Parser::parseCtor() - */ - TemplateParameters *tpl = NULL; - if (token.value == TOKlparen && peekPastParen(&token)->value == TOKlparen) -- { tpl = parseTemplateParameterList(); -+ { -+ tpl = parseTemplateParameterList(); - - int varargs; - Parameters *parameters = parseParameters(&varargs); -@@ -1152,7 +1164,7 @@ Dsymbol *Parser::parseCtor() - Type *tf = new TypeFunction(parameters, NULL, varargs, linkage, stc); // RetrunType -> auto - tf = tf->addSTC(stc); - -- CtorDeclaration *f = new CtorDeclaration(loc, 0, stc, tf); -+ CtorDeclaration *f = new CtorDeclaration(loc, Loc(), stc, tf); - parseContracts(f); - - // Wrap a template around it -@@ -1171,7 +1183,7 @@ Dsymbol *Parser::parseCtor() - Type *tf = new TypeFunction(parameters, NULL, varargs, linkage, stc); // RetrunType -> auto - tf = tf->addSTC(stc); - -- CtorDeclaration *f = new CtorDeclaration(loc, 0, stc, tf); -+ CtorDeclaration *f = new CtorDeclaration(loc, Loc(), stc, tf); - parseContracts(f); - return f; - } -@@ -1185,14 +1197,15 @@ Dsymbol *Parser::parseCtor() - DtorDeclaration *Parser::parseDtor() - { - DtorDeclaration *f; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - check(TOKthis); - check(TOKlparen); - check(TOKrparen); - -- f = new DtorDeclaration(loc, 0); -+ StorageClass stc = parsePostfix(); -+ f = new DtorDeclaration(loc, Loc(), stc, Id::dtor); - parseContracts(f); - return f; - } -@@ -1205,13 +1218,13 @@ DtorDeclaration *Parser::parseDtor() - - StaticCtorDeclaration *Parser::parseStaticCtor() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - check(TOKlparen); - check(TOKrparen); - -- StaticCtorDeclaration *f = new StaticCtorDeclaration(loc, 0); -+ StaticCtorDeclaration *f = new StaticCtorDeclaration(loc, Loc()); - parseContracts(f); - return f; - } -@@ -1224,7 +1237,7 @@ StaticCtorDeclaration *Parser::parseStat - - SharedStaticCtorDeclaration *Parser::parseSharedStaticCtor() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - nextToken(); -@@ -1232,7 +1245,7 @@ SharedStaticCtorDeclaration *Parser::par - check(TOKlparen); - check(TOKrparen); - -- SharedStaticCtorDeclaration *f = new SharedStaticCtorDeclaration(loc, 0); -+ SharedStaticCtorDeclaration *f = new SharedStaticCtorDeclaration(loc, Loc()); - parseContracts(f); - return f; - } -@@ -1245,14 +1258,17 @@ SharedStaticCtorDeclaration *Parser::par - - StaticDtorDeclaration *Parser::parseStaticDtor() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - check(TOKthis); - check(TOKlparen); - check(TOKrparen); -+ StorageClass stc = parsePostfix(); -+ if (stc & STCshared) -+ error("to create a 'shared' static destructor, move 'shared' in front of the declaration"); - -- StaticDtorDeclaration *f = new StaticDtorDeclaration(loc, 0); -+ StaticDtorDeclaration *f = new StaticDtorDeclaration(loc, Loc(), stc); - parseContracts(f); - return f; - } -@@ -1265,7 +1281,7 @@ StaticDtorDeclaration *Parser::parseStat - - SharedStaticDtorDeclaration *Parser::parseSharedStaticDtor() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - nextToken(); -@@ -1273,8 +1289,11 @@ SharedStaticDtorDeclaration *Parser::par - check(TOKthis); - check(TOKlparen); - check(TOKrparen); -+ StorageClass stc = parsePostfix(); -+ if (stc & STCshared) -+ error("static destructor is 'shared' already"); - -- SharedStaticDtorDeclaration *f = new SharedStaticDtorDeclaration(loc, 0); -+ SharedStaticDtorDeclaration *f = new SharedStaticDtorDeclaration(loc, Loc(), stc); - parseContracts(f); - return f; - } -@@ -1288,7 +1307,7 @@ SharedStaticDtorDeclaration *Parser::par - InvariantDeclaration *Parser::parseInvariant() - { - InvariantDeclaration *f; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - if (token.value == TOKlparen) // optional () -@@ -1297,7 +1316,7 @@ InvariantDeclaration *Parser::parseInvar - check(TOKrparen); - } - -- f = new InvariantDeclaration(loc, 0); -+ f = new InvariantDeclaration(loc, Loc(), STCundefined); - f->fbody = parseStatement(PScurly); - return f; - } -@@ -1312,13 +1331,36 @@ UnitTestDeclaration *Parser::parseUnitTe - { - UnitTestDeclaration *f; - Statement *body; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); -+ utf8_t *begPtr = token.ptr + 1; // skip '{' -+ utf8_t *endPtr = NULL; -+ body = parseStatement(PScurly, &endPtr); - -- body = parseStatement(PScurly); -+ /** Extract unittest body as a string. Must be done eagerly since memory -+ will be released by the lexer before doc gen. */ -+ char *docline = NULL; -+ if (global.params.doDocComments && endPtr > begPtr) -+ { -+ /* Remove trailing whitespaces */ -+ for (utf8_t *p = endPtr - 1; -+ begPtr <= p && (*p == ' ' || *p == '\n' || *p == '\t'); --p) -+ { -+ endPtr = p; -+ } - -- f = new UnitTestDeclaration(loc, this->loc); -+ size_t len = endPtr - begPtr; -+ if (len > 0) -+ { -+ docline = (char *)mem.malloc(len + 2); -+ memcpy(docline, begPtr, len); -+ docline[len ] = '\n'; // Terminate all lines by LF -+ docline[len+1] = '\0'; -+ } -+ } -+ -+ f = new UnitTestDeclaration(loc, token.loc, docline); - f->fbody = body; - return f; - } -@@ -1334,11 +1376,11 @@ NewDeclaration *Parser::parseNew() - NewDeclaration *f; - Parameters *arguments; - int varargs; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - arguments = parseParameters(&varargs); -- f = new NewDeclaration(loc, 0, arguments, varargs); -+ f = new NewDeclaration(loc, Loc(), arguments, varargs); - parseContracts(f); - return f; - } -@@ -1354,13 +1396,13 @@ DeleteDeclaration *Parser::parseDelete() - DeleteDeclaration *f; - Parameters *arguments; - int varargs; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - arguments = parseParameters(&varargs); - if (varargs) - error("... not allowed in delete function parameter list"); -- f = new DeleteDeclaration(loc, 0, arguments); -+ f = new DeleteDeclaration(loc, Loc(), arguments); - parseContracts(f); - return f; - } -@@ -1408,7 +1450,7 @@ Parameters *Parser::parseParameters(int - if (peek(&token)->value == TOKlparen) - goto Ldefault; - if (token.value == TOKinvariant) -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - stc = STCimmutable; - goto L2; - -@@ -1439,7 +1481,7 @@ Parameters *Parser::parseParameters(int - (storageClass & STCin && stc & (STCconst | STCscope)) || - (stc & STCin && storageClass & (STCconst | STCscope)) - ) -- error("redundant storage class %s", Token::toChars(token.value)); -+ error("redundant storage class '%s'", Token::toChars(token.value)); - storageClass |= stc; - composeStorageClass(storageClass); - continue; -@@ -1477,10 +1519,6 @@ Parameters *Parser::parseParameters(int - if (stc & (stc - 1) && // if stc is not a power of 2 - !(stc == (STCin | STCref))) - error("incompatible parameter storage classes"); -- if ((storageClass & (STCconst | STCout)) == (STCconst | STCout)) -- error("out cannot be const"); -- if ((storageClass & (STCimmutable | STCout)) == (STCimmutable | STCout)) -- error("out cannot be immutable"); - if ((storageClass & STCscope) && (storageClass & (STCref | STCout))) - error("scope cannot be ref or out"); - -@@ -1494,7 +1532,9 @@ Parameters *Parser::parseParameters(int - t->value == TOKrparen || - t->value == TOKdotdotdot))) - #endif -- { Identifier *id = Lexer::uniqueId("__T"); -+ { -+ Identifier *id = Lexer::uniqueId("__T"); -+ Loc loc = token.loc; - at = new TypeIdentifier(loc, id); - if (!*tpl) - *tpl = new TemplateParameters(); -@@ -1531,7 +1571,6 @@ Parameters *Parser::parseParameters(int - nextToken(); - break; - } -- L3: - a = new Parameter(storageClass, at, ai, ae); - arguments->push(a); - if (token.value == TOKcomma) -@@ -1557,15 +1596,17 @@ Parameters *Parser::parseParameters(int - */ - - EnumDeclaration *Parser::parseEnum() --{ EnumDeclaration *e; -+{ -+ EnumDeclaration *e; - Identifier *id; - Type *memtype; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - //printf("Parser::parseEnum()\n"); - nextToken(); - if (token.value == TOKidentifier) -- { id = token.ident; -+ { -+ id = token.ident; - nextToken(); - } - else -@@ -1588,7 +1629,7 @@ EnumDeclaration *Parser::parseEnum() - //printf("enum definition\n"); - e->members = new Dsymbols(); - nextToken(); -- unsigned char *comment = token.blockComment; -+ utf8_t *comment = token.blockComment; - while (token.value != TOKrcurly) - { - /* Can take the following forms: -@@ -1597,7 +1638,7 @@ EnumDeclaration *Parser::parseEnum() - * 3. type ident = value - */ - -- loc = this->loc; -+ loc = token.loc; - - Type *type = NULL; - Identifier *ident; -@@ -1660,15 +1701,16 @@ EnumDeclaration *Parser::parseEnum() - */ - - Dsymbol *Parser::parseAggregate() --{ AggregateDeclaration *a = NULL; -+{ -+ AggregateDeclaration *a = NULL; - int anon = 0; -- enum TOK tok; - Identifier *id; - TemplateParameters *tpl = NULL; - Expression *constraint = NULL; -+ Loc loc = token.loc; -+ TOK tok = token.value; - - //printf("Parser::parseAggregate()\n"); -- tok = token.value; - nextToken(); - if (token.value != TOKidentifier) - { id = NULL; -@@ -1686,9 +1728,9 @@ Dsymbol *Parser::parseAggregate() - } - } - -- Loc loc = this->loc; - switch (tok) -- { case TOKclass: -+ { -+ case TOKclass: - case TOKinterface: - { - if (!id) -@@ -1701,12 +1743,27 @@ Dsymbol *Parser::parseAggregate() - nextToken(); - baseclasses = parseBaseClasses(); - -+ if (tpl) -+ { -+ Expression *tempCons = parseConstraint(); -+ if (tempCons) -+ { -+ if (constraint) -+ error("members expected"); -+ else -+ constraint = tempCons; -+ } -+ } -+ - if (token.value != TOKlcurly) - error("members expected"); - } - - if (tok == TOKclass) -- a = new ClassDeclaration(loc, id, baseclasses); -+ { -+ bool inObject = md && !md->packages && md->id == Id::object; -+ a = new ClassDeclaration(loc, id, baseclasses, inObject); -+ } - else - a = new InterfaceDeclaration(loc, id, baseclasses); - break; -@@ -1745,7 +1802,7 @@ Dsymbol *Parser::parseAggregate() - { - /* Anonymous structs/unions are more like attributes. - */ -- return new AnonDeclaration(loc, anon - 1, decl); -+ return new AnonDeclaration(loc, anon == 2, decl); - } - else - a->members = decl; -@@ -1779,7 +1836,7 @@ BaseClasses *Parser::parseBaseClasses() - for (; 1; nextToken()) - { - bool prot = false; -- enum PROT protection = PROTpublic; -+ PROT protection = PROTpublic; - switch (token.value) - { - case TOKprivate: -@@ -1846,7 +1903,7 @@ TemplateDeclaration *Parser::parseTempla - TemplateParameters *tpl; - Dsymbols *decldefs; - Expression *constraint = NULL; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - if (token.value != TOKidentifier) -@@ -1902,10 +1959,12 @@ TemplateParameters *Parser::parseTemplat - - // Get array of TemplateParameters - if (flag || token.value != TOKrparen) -- { int isvariadic = 0; -- -+ { -+ int isvariadic = 0; - while (token.value != TOKrparen) -- { TemplateParameter *tp; -+ { -+ TemplateParameter *tp; -+ Loc loc; - Identifier *tp_ident = NULL; - Type *tp_spectype = NULL; - Type *tp_valtype = NULL; -@@ -1921,6 +1980,7 @@ TemplateParameters *Parser::parseTemplat - if (token.value == TOKalias) - { // AliasParameter - nextToken(); -+ loc = token.loc; // todo - Type *spectype = NULL; - if (isDeclaration(&token, 2, TOKreserved, NULL)) - { -@@ -1929,13 +1989,14 @@ TemplateParameters *Parser::parseTemplat - else - { - if (token.value != TOKidentifier) -- { error("identifier expected for template alias parameter"); -+ { -+ error("identifier expected for template alias parameter"); - goto Lerr; - } - tp_ident = token.ident; - nextToken(); - } -- Object *spec = NULL; -+ RootObject *spec = NULL; - if (token.value == TOKcolon) // : Type - { - nextToken(); -@@ -1944,7 +2005,7 @@ TemplateParameters *Parser::parseTemplat - else - spec = parseCondExp(); - } -- Object *def = NULL; -+ RootObject *def = NULL; - if (token.value == TOKassign) // = Type - { - nextToken(); -@@ -1953,15 +2014,18 @@ TemplateParameters *Parser::parseTemplat - else - def = parseCondExp(); - } -- tp = new TemplateAliasParameter(loc, tp_ident, spectype, spec, def); -+ tp = new TemplateAliasParameter(loc/*todo*/, tp_ident, spectype, spec, def); - } - else if (t->value == TOKcolon || t->value == TOKassign || - t->value == TOKcomma || t->value == TOKrparen) -- { // TypeParameter -+ { -+ // TypeParameter - if (token.value != TOKidentifier) -- { error("identifier expected for template type parameter"); -+ { -+ error("identifier expected for template type parameter"); - goto Lerr; - } -+ loc = token.loc; - tp_ident = token.ident; - nextToken(); - if (token.value == TOKcolon) // : Type -@@ -1977,10 +2041,12 @@ TemplateParameters *Parser::parseTemplat - tp = new TemplateTypeParameter(loc, tp_ident, tp_spectype, tp_defaulttype); - } - else if (token.value == TOKidentifier && t->value == TOKdotdotdot) -- { // ident... -+ { -+ // ident... - if (isvariadic) - error("variadic template parameter must be last"); - isvariadic = 1; -+ loc = token.loc; - tp_ident = token.ident; - nextToken(); - nextToken(); -@@ -1988,12 +2054,15 @@ TemplateParameters *Parser::parseTemplat - } - #if DMDV2 - else if (token.value == TOKthis) -- { // ThisParameter -+ { -+ // ThisParameter - nextToken(); - if (token.value != TOKidentifier) -- { error("identifier expected for template this parameter"); -+ { -+ error("identifier expected for template this parameter"); - goto Lerr; - } -+ loc = token.loc; - tp_ident = token.ident; - nextToken(); - if (token.value == TOKcolon) // : Type -@@ -2010,7 +2079,9 @@ TemplateParameters *Parser::parseTemplat - } - #endif - else -- { // ValueParameter -+ { -+ // ValueParameter -+ loc = token.loc; // todo - tp_valtype = parseType(&tp_ident); - if (!tp_ident) - { -@@ -2027,7 +2098,7 @@ TemplateParameters *Parser::parseTemplat - nextToken(); - tp_defaultvalue = parseDefaultInitExp(); - } -- tp = new TemplateValueParameter(loc, tp_ident, tp_valtype, tp_specvalue, tp_defaultvalue); -+ tp = new TemplateValueParameter(loc/*todo*/, tp_ident, tp_valtype, tp_specvalue, tp_defaultvalue); - } - tpl->push(tp); - if (token.value != TOKcomma) -@@ -2053,13 +2124,14 @@ Dsymbol *Parser::parseMixin() - { - TemplateMixin *tm; - Identifier *id; -- Type *tqual; - Objects *tiargs; -- Identifiers *idents; - - //printf("parseMixin()\n"); -- nextToken(); -- tqual = NULL; -+ Loc locMixin = token.loc; -+ nextToken(); // skip 'mixin' -+ -+ Loc loc = token.loc; -+ TypeQualified *tqual = NULL; - if (token.value == TOKdot) - { - id = Id::empty; -@@ -2071,11 +2143,6 @@ Dsymbol *Parser::parseMixin() - tqual = parseTypeof(); - check(TOKdot); - } -- else if (token.value == TOKvector) -- { -- tqual = parseVector(); -- check(TOKdot); -- } - if (token.value != TOKidentifier) - { - error("identifier expected, not %s", token.toChars()); -@@ -2086,7 +2153,6 @@ Dsymbol *Parser::parseMixin() - nextToken(); - } - -- idents = new Identifiers(); - while (1) - { - tiargs = NULL; -@@ -2099,26 +2165,37 @@ Dsymbol *Parser::parseMixin() - tiargs = parseTemplateArgument(); - } - -- if (token.value != TOKdot) -- break; -- -- if (tiargs) -- { TemplateInstance *tempinst = new TemplateInstance(loc, id); -+ if (tiargs && token.value == TOKdot) -+ { -+ TemplateInstance *tempinst = new TemplateInstance(loc, id); - tempinst->tiargs = tiargs; -- id = (Identifier *)tempinst; -+ if (!tqual) -+ tqual = new TypeInstance(loc, tempinst); -+ else -+ tqual->addInst(tempinst); - tiargs = NULL; - } -- idents->push(id); -+ else -+ { -+ if (!tqual) -+ tqual = new TypeIdentifier(loc, id); -+ else -+ tqual->addIdent(id); -+ } -+ -+ if (token.value != TOKdot) -+ break; - - nextToken(); - if (token.value != TOKidentifier) -- { error("identifier expected following '.' instead of '%s'", token.toChars()); -+ { -+ error("identifier expected following '.' instead of '%s'", token.toChars()); - break; - } -+ loc = token.loc; - id = token.ident; - nextToken(); - } -- idents->push(id); - - if (token.value == TOKidentifier) - { -@@ -2128,7 +2205,7 @@ Dsymbol *Parser::parseMixin() - else - id = NULL; - -- tm = new TemplateMixin(loc, id, tqual, idents, tiargs); -+ tm = new TemplateMixin(locMixin, id, tqual, tiargs); - if (token.value != TOKsemicolon) - error("';' expected after mixin"); - nextToken(); -@@ -2158,7 +2235,7 @@ Objects *Parser::parseTemplateArgumentLi - { - //printf("Parser::parseTemplateArgumentList2()\n"); - Objects *tiargs = new Objects(); -- enum TOK endtok = TOKrparen; -+ TOK endtok = TOKrparen; - nextToken(); - - // Get TemplateArgumentList -@@ -2198,7 +2275,7 @@ Objects *Parser::parseTemplateArgument() - switch (token.value) - { - case TOKidentifier: -- ta = new TypeIdentifier(loc, token.ident); -+ ta = new TypeIdentifier(token.loc, token.ident); - goto LabelX; - - case TOKvector: -@@ -2229,6 +2306,9 @@ Objects *Parser::parseTemplateArgument() - case TOKstring: - case TOKfile: - case TOKline: -+ case TOKmodulestring: -+ case TOKfuncstring: -+ case TOKprettyfunc: - case TOKthis: - { // Template argument is an expression - Expression *ea = parsePrimaryExp(); -@@ -2242,7 +2322,7 @@ Objects *Parser::parseTemplateArgument() - } - if (token.value == TOKnot) - { -- enum TOK tok = peekNext(); -+ TOK tok = peekNext(); - if (tok != TOKis && tok != TOKin) - error("multiple ! arguments are not allowed"); - } -@@ -2250,11 +2330,8 @@ Objects *Parser::parseTemplateArgument() - } - - Import *Parser::parseImport(Dsymbols *decldefs, int isstatic) --{ Import *s; -- Identifier *id; -+{ - Identifier *aliasid = NULL; -- Identifiers *a; -- Loc loc; - - //printf("Parser::parseImport()\n"); - do -@@ -2266,9 +2343,9 @@ Import *Parser::parseImport(Dsymbols *de - break; - } - -- loc = this->loc; -- a = NULL; -- id = token.ident; -+ Loc loc = token.loc; -+ Identifier *id = token.ident; -+ Identifiers *a = NULL; - nextToken(); - if (!aliasid && token.value == TOKassign) - { -@@ -2289,7 +2366,7 @@ Import *Parser::parseImport(Dsymbols *de - nextToken(); - } - -- s = new Import(loc, a, id, aliasid, isstatic); -+ Import *s = new Import(loc, a, id, aliasid, isstatic); - decldefs->push(s); - - /* Look for -@@ -2416,7 +2493,9 @@ Type *Parser::parseType(Identifier **pid - #endif - - Type *Parser::parseBasicType() --{ Type *t; -+{ -+ Type *t; -+ Loc loc; - Identifier *id; - TypeQualified *tid; - -@@ -2430,10 +2509,12 @@ Type *Parser::parseBasicType() - case TOKthis: - case TOKsuper: - case TOKidentifier: -+ loc = token.loc; - id = token.ident; - nextToken(); - if (token.value == TOKnot) -- { // ident!(template_arguments) -+ { -+ // ident!(template_arguments) - TemplateInstance *tempinst = new TemplateInstance(loc, id); - nextToken(); - if (token.value == TOKlparen) -@@ -2449,11 +2530,14 @@ Type *Parser::parseBasicType() - tid = new TypeIdentifier(loc, id); - Lident2: - while (token.value == TOKdot) -- { nextToken(); -+ { -+ nextToken(); - if (token.value != TOKidentifier) -- { error("identifier expected following '.' instead of '%s'", token.toChars()); -+ { -+ error("identifier expected following '.' instead of '%s'", token.toChars()); - break; - } -+ loc = token.loc; - id = token.ident; - nextToken(); - if (token.value == TOKnot) -@@ -2466,7 +2550,7 @@ Type *Parser::parseBasicType() - else - // ident!template_argument - tempinst->tiargs = parseTemplateArgument(); -- tid->addIdent((Identifier *)tempinst); -+ tid->addInst(tempinst); - } - else - tid->addIdent(id); -@@ -2476,6 +2560,7 @@ Type *Parser::parseBasicType() - - case TOKdot: - // Leading . as in .foo -+ loc = token.loc; - id = Id::empty; - goto Lident; - -@@ -2503,7 +2588,7 @@ Type *Parser::parseBasicType() - break; - - case TOKinvariant: -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - case TOKimmutable: - // invariant(type) - nextToken(); -@@ -2617,7 +2702,7 @@ Type *Parser::parseBasicType2(Type *t) - // t function(parameter list) nothrow pure - Parameters *arguments; - int varargs; -- enum TOK save = token.value; -+ TOK save = token.value; - - nextToken(); - arguments = parseParameters(&varargs); -@@ -2690,7 +2775,8 @@ Type *Parser::parseDeclarator(Type *t, I - * Improve error messages for the common bug of a missing return type - * by looking to see if (a) looks like a parameter list. - */ -- if (isParameters(&peekt)) { -+ if (isParameters(&peekt)) -+ { - error("function declaration without return type. " - "(Note that constructors are always named 'this')"); - } -@@ -2807,7 +2893,7 @@ Type *Parser::parseDeclarator(Type *t, I - * Return array of Declaration *'s. - */ - --Dsymbols *Parser::parseDeclarations(StorageClass storage_class, unsigned char *comment) -+Dsymbols *Parser::parseDeclarations(StorageClass storage_class, utf8_t *comment) - { - StorageClass stc; - int disable; -@@ -2816,10 +2902,10 @@ Dsymbols *Parser::parseDeclarations(Stor - Type *tfirst; - Identifier *ident; - Dsymbols *a; -- enum TOK tok = TOKreserved; -- enum LINK link = linkage; -+ TOK tok = TOKreserved; -+ LINK link = linkage; - unsigned structalign = 0; -- Loc loc = this->loc; -+ Loc loc = token.loc; - Expressions *udas = NULL; - - //printf("parseDeclarations() %s\n", token.toChars()); -@@ -2834,6 +2920,7 @@ Dsymbols *Parser::parseDeclarations(Stor - switch (token.value) - { - case TOKalias: -+ { - /* Look for: - * alias identifier this; - */ -@@ -2869,32 +2956,116 @@ Dsymbols *Parser::parseDeclarations(Stor - #endif - /* Look for: - * alias identifier = type; -+ * alias identifier(...) = type; - */ -- if (token.value == TOKidentifier && peekNext() == TOKassign) -+ Token *tk = &token; -+ if (tk->value == TOKidentifier && -+ ((tk = peek(tk))->value == TOKlparen -+ ? skipParens(tk, &tk) && (tk = peek(tk), 1) : 1) && -+ tk->value == TOKassign) - { - a = new Dsymbols(); - while (1) - { - ident = token.ident; - nextToken(); -+ TemplateParameters *tpl = NULL; -+ if (token.value == TOKlparen) -+ tpl = parseTemplateParameterList(); - check(TOKassign); - t = parseType(); -- Declaration *v = new AliasDeclaration(loc, ident, t); -- a->push(v); -+ Dsymbol *s = new AliasDeclaration(loc, ident, t); -+ if (tpl) -+ { -+ Dsymbols *a2 = new Dsymbols(); -+ a2->push(s); -+ TemplateDeclaration *tempdecl = -+ new TemplateDeclaration(loc, ident, tpl, NULL/*constraint*/, a2, 0); -+ s = tempdecl; -+ } -+ a->push(s); - switch (token.value) -- { case TOKsemicolon: -+ { -+ case TOKsemicolon: - nextToken(); -- addComment(v, comment); -+ addComment(s, comment); - break; - case TOKcomma: - nextToken(); -- addComment(v, comment); -+ addComment(s, comment); - if (token.value != TOKidentifier) -- { error("Identifier expected following comma, not %s", token.toChars()); -+ { -+ error("Identifier expected following comma, not %s", token.toChars()); - break; - } -- else if (peek(&token)->value != TOKassign) -- { error("= expected following identifier"); -+ if (peekNext() != TOKassign && peekNext() != TOKlparen) -+ { -+ error("= expected following identifier"); -+ nextToken(); -+ break; -+ } -+ continue; -+ default: -+ error("semicolon expected to close %s declaration", Token::toChars(tok)); -+ break; -+ } -+ break; -+ } -+ return a; -+ } -+ break; -+ } -+ case TOKenum: -+ { -+ /* Look for: -+ * enum identifier(...) = type; -+ */ -+ tok = token.value; -+ Token *tk = peek(&token); -+ if (tk->value == TOKidentifier && -+ (tk = peek(tk))->value == TOKlparen && skipParens(tk, &tk) && -+ (tk = peek(tk))->value == TOKassign) -+ { -+ nextToken(); -+ a = new Dsymbols(); -+ while (1) -+ { -+ ident = token.ident; -+ nextToken(); -+ TemplateParameters *tpl = NULL; -+ if (token.value == TOKlparen) -+ tpl = parseTemplateParameterList(); -+ check(TOKassign); -+ Initializer *init = parseInitializer(); -+ VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init); -+ v->storage_class = STCmanifest; -+ Dsymbol *s = v; -+ if (tpl) -+ { -+ Dsymbols *a2 = new Dsymbols(); -+ a2->push(s); -+ TemplateDeclaration *tempdecl = -+ new TemplateDeclaration(loc, ident, tpl, NULL/*constraint*/, a2, 0); -+ s = tempdecl; -+ } -+ a->push(s); -+ switch (token.value) -+ { -+ case TOKsemicolon: -+ nextToken(); -+ addComment(s, comment); -+ break; -+ case TOKcomma: -+ nextToken(); -+ addComment(s, comment); -+ if (token.value != TOKidentifier) -+ { -+ error("Identifier expected following comma, not %s", token.toChars()); -+ break; -+ } -+ if (peekNext() != TOKassign && peekNext() != TOKlparen) -+ { -+ error("= expected following identifier"); - nextToken(); - break; - } -@@ -2907,8 +3078,8 @@ Dsymbols *Parser::parseDeclarations(Stor - } - return a; - } -- - break; -+ } - case TOKtypedef: - deprecation("use of typedef is deprecated; use alias instead"); - tok = token.value; -@@ -2933,7 +3104,7 @@ Dsymbols *Parser::parseDeclarations(Stor - if (peek(&token)->value == TOKlparen) - break; - if (token.value == TOKinvariant) -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - stc = STCimmutable; - goto L1; - -@@ -2961,7 +3132,6 @@ Dsymbols *Parser::parseDeclarations(Stor - case TOKnothrow: stc = STCnothrow; goto L1; - case TOKpure: stc = STCpure; goto L1; - case TOKref: stc = STCref; goto L1; -- case TOKtls: stc = STCtls; goto L1; - case TOKgshared: stc = STCgshared; goto L1; - case TOKenum: stc = STCmanifest; goto L1; - case TOKat: -@@ -3005,7 +3175,7 @@ Dsymbols *Parser::parseDeclarations(Stor - check(TOKrparen); - } - else -- structalign = global.structalign; // default -+ structalign = STRUCTALIGN_DEFAULT; // default - continue; - } - default: -@@ -3100,7 +3270,7 @@ L2: - - while (1) - { -- loc = this->loc; -+ loc = token.loc; - TemplateParameters *tpl = NULL; - - ident = NULL; -@@ -3111,11 +3281,13 @@ L2: - else if (t != tfirst) - error("multiple declarations must have the same type, not %s and %s", - tfirst->toChars(), t->toChars()); -- if (!ident) -+ bool isThis = (t->ty == Tident && ((TypeIdentifier *)t)->ident == Id::This); -+ if (!isThis && !ident) - error("no identifier for declarator %s", t->toChars()); - - if (tok == TOKtypedef || tok == TOKalias) -- { Declaration *v; -+ { -+ Declaration *v; - Initializer *init = NULL; - - /* Aliases can no longer have multiple declarators, storage classes, -@@ -3132,12 +3304,20 @@ L2: - init = parseInitializer(); - } - if (tok == TOKtypedef) -- { v = new TypedefDeclaration(loc, ident, t, init); -- deprecation("use of typedef is deprecated; use alias instead"); -+ { -+ v = new TypedefDeclaration(loc, ident, t, init); - } - else -- { if (init) -- error("alias cannot have initializer"); -+ { -+ if (init) -+ { -+ if (isThis) -+ error("Cannot use syntax 'alias this = %s', use 'alias %s this' instead", -+ init->toChars(), init->toChars()); -+ else -+ error("alias cannot have initializer"); -+ } -+ - v = new AliasDeclaration(loc, ident, t); - } - v->storage_class = storage_class; -@@ -3181,7 +3361,7 @@ L2: - //printf("%s funcdecl t = %s, storage_class = x%lx\n", loc.toChars(), t->toChars(), storage_class); - - FuncDeclaration *f = -- new FuncDeclaration(loc, 0, ident, storage_class | (disable ? STCdisable : 0), t); -+ new FuncDeclaration(loc, Loc(), ident, storage_class | (disable ? STCdisable : 0), t); - addComment(f, comment); - if (tpl) - constraint = parseConstraint(); -@@ -3269,12 +3449,13 @@ L2: - */ - - #if DMDV2 --Dsymbols *Parser::parseAutoDeclarations(StorageClass storageClass, unsigned char *comment) -+Dsymbols *Parser::parseAutoDeclarations(StorageClass storageClass, utf8_t *comment) - { - Dsymbols *a = new Dsymbols; - - while (1) - { -+ Loc loc = token.loc; - Identifier *ident = token.ident; - nextToken(); // skip over ident - assert(token.value == TOKassign); -@@ -3314,7 +3495,7 @@ Dsymbols *Parser::parseAutoDeclarations( - - void Parser::parseContracts(FuncDeclaration *f) - { -- enum LINK linksave = linkage; -+ LINK linksave = linkage; - - // The following is irrelevant, as it is overridden by sc->linkage in - // TypeFunction::semantic -@@ -3413,7 +3594,7 @@ Initializer *Parser::parseInitializer() - Identifier *id; - Initializer *value; - int comma; -- Loc loc = this->loc; -+ Loc loc = token.loc; - Token *t; - int braces; - int brackets; -@@ -3626,23 +3807,32 @@ Initializer *Parser::parseInitializer() - - /***************************************** - * Parses default argument initializer expression that is an assign expression, -- * with special handling for __FILE__ and __LINE__. -+ * with special handling for __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__. - */ - - #if DMDV2 - Expression *Parser::parseDefaultInitExp() - { - if (token.value == TOKfile || -- token.value == TOKline) -+ token.value == TOKline || -+ token.value == TOKmodulestring || -+ token.value == TOKfuncstring || -+ token.value == TOKprettyfunc) - { - Token *t = peek(&token); - if (t->value == TOKcomma || t->value == TOKrparen) -- { Expression *e; -- -+ { -+ Expression *e; - if (token.value == TOKfile) -- e = new FileInitExp(loc); -- else -- e = new LineInitExp(loc); -+ e = new FileInitExp(token.loc); -+ else if (token.value == TOKline) -+ e = new LineInitExp(token.loc); -+ else if (token.value == TOKmodulestring) -+ e = new ModuleInitExp(token.loc); -+ else if (token.value == TOKfuncstring) -+ e = new FuncInitExp(token.loc); -+ else if (token.value == TOKprettyfunc) -+ e = new PrettyFuncInitExp(token.loc); - nextToken(); - return e; - } -@@ -3672,13 +3862,14 @@ void Parser::checkDanglingElse(Loc elsel - * flags PSxxxx - */ - --Statement *Parser::parseStatement(int flags) --{ Statement *s; -+Statement *Parser::parseStatement(int flags, utf8_t** endPtr) -+{ -+ Statement *s; - Condition *condition; - Statement *ifbody; - Statement *elsebody; - bool isfinal; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - //printf("parseStatement()\n"); - -@@ -3753,6 +3944,9 @@ Statement *Parser::parseStatement(int fl - case TOKtraits: - case TOKfile: - case TOKline: -+ case TOKmodulestring: -+ case TOKfuncstring: -+ case TOKprettyfunc: - #endif - Lexp: - { -@@ -3818,7 +4012,6 @@ Statement *Parser::parseStatement(int fl - case TOKnothrow: - case TOKpure: - case TOKref: -- case TOKtls: - case TOKgshared: - case TOKat: - #endif -@@ -3906,7 +4099,7 @@ Statement *Parser::parseStatement(int fl - case TOKlcurly: - { - Loc lookingForElseSave = lookingForElse; -- lookingForElse = 0; -+ lookingForElse = Loc(); - - nextToken(); - //if (token.value == TOKsemicolon) -@@ -3916,7 +4109,8 @@ Statement *Parser::parseStatement(int fl - { - statements->push(parseStatement(PSsemi | PScurlyscope)); - } -- endloc = this->loc; -+ if (endPtr) *endPtr = token.ptr; -+ endloc = token.loc; - s = new CompoundStatement(loc, statements); - if (flags & (PSscope | PScurlyscope)) - s = new ScopeStatement(loc, s); -@@ -3956,7 +4150,7 @@ Statement *Parser::parseStatement(int fl - - nextToken(); - Loc lookingForElseSave = lookingForElse; -- lookingForElse = 0; -+ lookingForElse = Loc(); - body = parseStatement(PSscope); - lookingForElse = lookingForElseSave; - check(TOKwhile); -@@ -3987,7 +4181,7 @@ Statement *Parser::parseStatement(int fl - else - { - Loc lookingForElseSave = lookingForElse; -- lookingForElse = 0; -+ lookingForElse = Loc(); - init = parseStatement(0); - lookingForElse = lookingForElseSave; - } -@@ -4011,15 +4205,13 @@ Statement *Parser::parseStatement(int fl - } - body = parseStatement(PSscope); - s = new ForStatement(loc, init, condition, increment, body); -- if (init) -- s = new ScopeStatement(loc, s); - break; - } - - case TOKforeach: - case TOKforeach_reverse: - { -- enum TOK op = token.value; -+ TOK op = token.value; - - nextToken(); - check(TOKlparen); -@@ -4032,22 +4224,29 @@ Statement *Parser::parseStatement(int fl - Type *at; - - StorageClass storageClass = 0; -+ StorageClass stc = 0; - Lagain: -+ if (stc) -+ { -+ if (storageClass & stc) -+ error("redundant storage class '%s'", Token::toChars(token.value)); -+ storageClass |= stc; -+ composeStorageClass(storageClass); -+ nextToken(); -+ } - switch (token.value) - { - case TOKref: - #if D1INOUT - case TOKinout: - #endif -- storageClass |= STCref; -- nextToken(); -+ stc = STCref; - goto Lagain; - - case TOKconst: - if (peekNext() != TOKlparen) - { -- storageClass |= STCconst; -- nextToken(); -+ stc = STCconst; - goto Lagain; - } - break; -@@ -4055,26 +4254,23 @@ Statement *Parser::parseStatement(int fl - case TOKimmutable: - if (peekNext() != TOKlparen) - { -- storageClass |= STCimmutable; -+ stc = STCimmutable; - if (token.value == TOKinvariant) -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -- nextToken(); -+ error("use 'immutable' instead of 'invariant'"); - goto Lagain; - } - break; - case TOKshared: - if (peekNext() != TOKlparen) - { -- storageClass |= STCshared; -- nextToken(); -+ stc = STCshared; - goto Lagain; - } - break; - case TOKwild: - if (peekNext() != TOKlparen) - { -- storageClass |= STCwild; -- nextToken(); -+ stc = STCwild; - goto Lagain; - } - break; -@@ -4126,7 +4322,8 @@ Statement *Parser::parseStatement(int fl - } - - case TOKif: -- { Parameter *arg = NULL; -+ { -+ Parameter *arg = NULL; - Expression *condition; - Statement *ifbody; - Statement *elsebody; -@@ -4134,52 +4331,91 @@ Statement *Parser::parseStatement(int fl - nextToken(); - check(TOKlparen); - -- if (token.value == TOKauto) -+ StorageClass storageClass = 0; -+ StorageClass stc = 0; -+ LagainStc: -+ if (stc) - { -+ if (storageClass & stc) -+ error("redundant storage class '%s'", Token::toChars(token.value)); -+ storageClass |= stc; -+ composeStorageClass(storageClass); - nextToken(); -- if (token.value == TOKidentifier) -- { -- Token *t = peek(&token); -- if (t->value == TOKassign) -+ } -+ switch (token.value) -+ { -+ case TOKref: -+ stc = STCref; -+ goto LagainStc; -+ case TOKauto: -+ stc = STCauto; -+ goto LagainStc; -+ case TOKconst: -+ if (peekNext() != TOKlparen) - { -- arg = new Parameter(0, NULL, token.ident, NULL); -- nextToken(); -- nextToken(); -+ stc = STCconst; -+ goto LagainStc; - } -- else -- { error("= expected following auto identifier"); -- goto Lerror; -+ break; -+ case TOKinvariant: -+ case TOKimmutable: -+ if (peekNext() != TOKlparen) -+ { -+ stc = STCimmutable; -+ if (token.value == TOKinvariant) -+ error("use 'immutable' instead of 'invariant'"); -+ goto LagainStc; - } -- } -- else -- { error("identifier expected following auto"); -- goto Lerror; -- } -+ break; -+ case TOKshared: -+ if (peekNext() != TOKlparen) -+ { -+ stc = STCshared; -+ goto LagainStc; -+ } -+ break; -+ case TOKwild: -+ if (peekNext() != TOKlparen) -+ { -+ stc = STCwild; -+ goto LagainStc; -+ } -+ break; -+ default: -+ break; - } -- else if (isDeclaration(&token, 2, TOKassign, NULL)) -- { -- Type *at; -- Identifier *ai; - -- at = parseType(&ai); -+ if (storageClass != 0 && -+ token.value == TOKidentifier && -+ peek(&token)->value == TOKassign) -+ { -+ Identifier *ai = token.ident; -+ Type *at = NULL; // infer argument type -+ nextToken(); - check(TOKassign); -- arg = new Parameter(0, at, ai, NULL); -+ arg = new Parameter(storageClass, at, ai, NULL); - } -- - // Check for " ident;" -- else if (token.value == TOKidentifier) -+ else if (storageClass == 0 && -+ token.value == TOKidentifier && -+ peek(&token)->value == TOKsemicolon) - { -- Token *t = peek(&token); -- if (t->value == TOKsemicolon) -- { -- arg = new Parameter(0, NULL, token.ident, NULL); -- nextToken(); -- nextToken(); -- error("if (v; e) is deprecated, use if (auto v = e)"); -- } -+ arg = new Parameter(0, NULL, token.ident, NULL); -+ nextToken(); -+ nextToken(); -+ error("if (v; e) is deprecated, use if (auto v = e)"); -+ } -+ else if (isDeclaration(&token, 2, TOKassign, NULL)) -+ { -+ Identifier *ai; -+ Type *at = parseType(&ai); -+ check(TOKassign); -+ arg = new Parameter(storageClass, at, ai, NULL); - } - - condition = parseExpression(); -+ if (condition->op == TOKassign) -+ error("assignment cannot be used as a condition, perhaps == was meant?"); - check(TOKrparen); - { - Loc lookingForElseSave = lookingForElse; -@@ -4189,7 +4425,7 @@ Statement *Parser::parseStatement(int fl - } - if (token.value == TOKelse) - { -- Loc elseloc = this->loc; -+ Loc elseloc = token.loc; - nextToken(); - elsebody = parseStatement(PSscope); - checkDanglingElse(elseloc); -@@ -4251,7 +4487,7 @@ Statement *Parser::parseStatement(int fl - elsebody = NULL; - if (token.value == TOKelse) - { -- Loc elseloc = this->loc; -+ Loc elseloc = token.loc; - nextToken(); - elsebody = parseStatement(0 /*PSsemi*/); - checkDanglingElse(elseloc); -@@ -4509,7 +4745,7 @@ Statement *Parser::parseStatement(int fl - - nextToken(); - Loc lookingForElseSave = lookingForElse; -- lookingForElse = 0; -+ lookingForElse = Loc(); - body = parseStatement(PSscope); - lookingForElse = lookingForElseSave; - while (token.value == TOKcatch) -@@ -4518,7 +4754,7 @@ Statement *Parser::parseStatement(int fl - Catch *c; - Type *t; - Identifier *id; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - if (token.value == TOKlcurly || token.value != TOKlparen) -@@ -4604,7 +4840,7 @@ Statement *Parser::parseStatement(int fl - if (t->value == TOKcolon) - { // It's a label - label = token.ident; -- labelloc = this->loc; -+ labelloc = token.loc; - nextToken(); - nextToken(); - continue; -@@ -4635,8 +4871,9 @@ Statement *Parser::parseStatement(int fl - - s = NULL; - if (toklist || label) -- { // Create AsmStatement from list of tokens we've saved -- s = new AsmStatement(this->loc, toklist); -+ { -+ // Create AsmStatement from list of tokens we've saved -+ s = new AsmStatement(token.loc, toklist); - toklist = NULL; - ptoklist = &toklist; - if (label) -@@ -4693,8 +4930,10 @@ Statement *Parser::parseStatement(int fl - } - - case TOKtemplate: -- error("template definitions aren't allowed inside functions"); -- goto Lerror; -+ { Dsymbol *d = parseTemplateDeclaration(0); -+ s = new ExpStatement(loc, d); -+ break; -+ } - - default: - error("found '%s' instead of statement", token.toChars()); -@@ -4723,7 +4962,6 @@ Statement *Parser::parseExtAsm() - Expressions *constraints = NULL; - int outputargs = 0; - Expressions *clobbers = NULL; -- Dsymbols *labels = NULL; - bool isInputPhase = false; // Output operands first, then input. - - insn = parseExpression(); -@@ -4824,24 +5062,24 @@ Statement *Parser::parseExtAsm() - Ldone: - check(TOKsemicolon); - -- return new ExtAsmStatement(loc, insn, args, names, constraints, -- outputargs, clobbers, labels); -+ return new ExtAsmStatement(token.loc, insn, args, names, -+ constraints, outputargs, clobbers); - } - #endif - --void Parser::check(enum TOK value) -+void Parser::check(TOK value) - { -- check(loc, value); -+ check(token.loc, value); - } - --void Parser::check(Loc loc, enum TOK value) -+void Parser::check(Loc loc, TOK value) - { - if (token.value != value) - error(loc, "found '%s' when expecting '%s'", token.toChars(), Token::toChars(value)); - nextToken(); - } - --void Parser::check(enum TOK value, const char *string) -+void Parser::check(TOK value, const char *string) - { - if (token.value != value) - error("found '%s' when expecting '%s' following %s", -@@ -4849,10 +5087,10 @@ void Parser::check(enum TOK value, const - nextToken(); - } - --void Parser::checkParens(enum TOK value, Expression *e) -+void Parser::checkParens(TOK value, Expression *e) - { - if (precedence[e->op] == PREC_rel && !e->parens) -- error(loc, "%s must be parenthesized when next to operator %s", e->toChars(), Token::toChars(value)); -+ error(e->loc, "%s must be parenthesized when next to operator %s", e->toChars(), Token::toChars(value)); - } - - /************************************ -@@ -4865,10 +5103,11 @@ void Parser::checkParens(enum TOK value, - * if *pt is not NULL, it is set to the ending token, which would be endtok - */ - --int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt) -+int Parser::isDeclaration(Token *t, int needId, TOK endtok, Token **pt) - { - //printf("isDeclaration(needId = %d)\n", needId); - int haveId = 0; -+ int haveTpl = 0; - - #if DMDV2 - while (1) -@@ -4895,7 +5134,7 @@ int Parser::isDeclaration(Token *t, int - { - goto Lisnot; - } -- if (!isDeclarator(&t, &haveId, endtok)) -+ if (!isDeclarator(&t, &haveId, &haveTpl, endtok)) - goto Lisnot; - if ( needId == 1 || - (needId == 0 && !haveId) || -@@ -4920,7 +5159,6 @@ int Parser::isBasicType(Token **pt) - { - // This code parallels parseBasicType() - Token *t = *pt; -- int haveId = 0; - - switch (t->value) - { -@@ -4983,6 +5221,9 @@ int Parser::isBasicType(Token **pt) - case TOKstring: - case TOKfile: - case TOKline: -+ case TOKmodulestring: -+ case TOKfuncstring: -+ case TOKprettyfunc: - goto L2; - default: - goto Lfalse; -@@ -5036,7 +5277,7 @@ Lfalse: - return FALSE; - } - --int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok) -+int Parser::isDeclarator(Token **pt, int *haveId, int *haveTpl, TOK endtok) - { // This code parallels parseDeclarator() - Token *t = *pt; - int parens; -@@ -5109,7 +5350,7 @@ int Parser::isDeclarator(Token **pt, int - } - - -- if (!isDeclarator(&t, haveId, TOKrparen)) -+ if (!isDeclarator(&t, haveId, NULL, TOKrparen)) - return FALSE; - t = peek(t); - parens = TRUE; -@@ -5157,6 +5398,13 @@ int Parser::isDeclarator(Token **pt, int - - case TOKlparen: - parens = FALSE; -+ if (Token *tk = peekPastParen(t)) -+ { if (tk->value == TOKlparen) -+ { if (!haveTpl) return FALSE; -+ *haveTpl = 1; -+ t = tk; -+ } -+ } - if (!isParameters(&t)) - return FALSE; - #if DMDV2 -@@ -5202,6 +5450,8 @@ int Parser::isDeclarator(Token **pt, int - return TRUE; - } - return FALSE; -+ case TOKif: -+ return haveTpl ? TRUE : FALSE; - - default: - return FALSE; -@@ -5280,7 +5530,7 @@ int Parser::isParameters(Token **pt) - L2: - int tmp = FALSE; - if (t->value != TOKdotdotdot && -- !isDeclarator(&t, &tmp, TOKreserved)) -+ !isDeclarator(&t, &tmp, NULL, TOKreserved)) - return FALSE; - if (t->value == TOKassign) - { t = peek(t); -@@ -5459,7 +5709,6 @@ int Parser::skipAttributes(Token *t, Tok - case TOKnothrow: - case TOKpure: - case TOKref: -- case TOKtls: - case TOKgshared: - //case TOKmanifest: - break; -@@ -5538,11 +5787,12 @@ int Parser::skipAttributes(Token *t, Tok - /********************************* Expression Parser ***************************/ - - Expression *Parser::parsePrimaryExp() --{ Expression *e; -+{ -+ Expression *e; - Type *t; - Identifier *id; -- enum TOK save; -- Loc loc = this->loc; -+ TOK save; -+ Loc loc = token.loc; - - //printf("parsePrimaryExp(): loc = %d\n", loc.linnum); - switch (token.value) -@@ -5660,6 +5910,24 @@ Expression *Parser::parsePrimaryExp() - e = new IntegerExp(loc, loc.linnum, Type::tint32); - nextToken(); - break; -+ -+ case TOKmodulestring: -+ { -+ const char *s = md ? md->toChars() : mod->toChars(); -+ e = new StringExp(loc, (char *)s, strlen(s), 0); -+ nextToken(); -+ break; -+ } -+ -+ case TOKfuncstring: -+ e = new FuncInitExp(loc); -+ nextToken(); -+ break; -+ -+ case TOKprettyfunc: -+ e = new PrettyFuncInitExp(loc); -+ nextToken(); -+ break; - #endif - - case TOKtrue: -@@ -5690,7 +5958,7 @@ Expression *Parser::parsePrimaryExp() - case TOKstring: - { - // cat adjacent strings -- unsigned char *s = token.ustring; -+ utf8_t *s = token.ustring; - size_t len = token.len; - unsigned char postfix = token.postfix; - while (1) -@@ -5707,9 +5975,9 @@ Expression *Parser::parsePrimaryExp() - size_t len1 = len; - size_t len2 = token.len; - len = len1 + len2; -- unsigned char *s2 = (unsigned char *)mem.malloc((len + 1) * sizeof(unsigned char)); -- memcpy(s2, s, len1 * sizeof(unsigned char)); -- memcpy(s2 + len1, token.ustring, (len2 + 1) * sizeof(unsigned char)); -+ utf8_t *s2 = (utf8_t *)mem.malloc((len + 1) * sizeof(utf8_t)); -+ memcpy(s2, s, len1 * sizeof(utf8_t)); -+ memcpy(s2 + len1, token.ustring, (len2 + 1) * sizeof(utf8_t)); - s = s2; - } - else -@@ -5748,7 +6016,7 @@ Expression *Parser::parsePrimaryExp() - { - nextToken(); - check(TOKlparen, "typeid"); -- Object *o; -+ RootObject *o; - if (isDeclaration(&token, 0, TOKreserved, NULL)) - { // argument is a type - o = parseType(); -@@ -5788,13 +6056,14 @@ Expression *Parser::parsePrimaryExp() - #endif - - case TOKis: -- { Type *targ; -+ { -+ Type *targ; - Identifier *ident = NULL; - Type *tspec = NULL; -- enum TOK tok = TOKreserved; -- enum TOK tok2 = TOKreserved; -+ TOK tok = TOKreserved; -+ TOK tok2 = TOKreserved; - TemplateParameters *tpl = NULL; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - if (token.value == TOKlparen) -@@ -5826,9 +6095,12 @@ Expression *Parser::parsePrimaryExp() - token.value == TOKdelegate || - token.value == TOKreturn)) - { -- if (token.value == TOKinvariant) -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); - tok2 = token.value; -+ if (token.value == TOKinvariant) -+ { -+ error("use 'immutable' instead of 'invariant'"); -+ tok2 = TOKimmutable; -+ } - nextToken(); - } - else -@@ -5836,7 +6108,7 @@ Expression *Parser::parsePrimaryExp() - tspec = parseType(); - } - } -- if (ident && tspec) -+ if (tspec) - { - if (token.value == TOKcomma) - tpl = parseTemplateParameterList(1); -@@ -5844,8 +6116,6 @@ Expression *Parser::parsePrimaryExp() - { tpl = new TemplateParameters(); - check(TOKrparen); - } -- TemplateParameter *tp = new TemplateTypeParameter(loc, ident, NULL, NULL); -- tpl->insert(0, tp); - } - else - check(TOKrparen); -@@ -5893,11 +6163,15 @@ Expression *Parser::parsePrimaryExp() - break; - } - -+ case TOKnew: -+ e = parseNewExp(NULL); -+ break; -+ - case TOKlparen: - { Token *tk = peekPastParen(&token); - if (skipAttributes(tk, &tk)) - { -- enum TOK past = tk->value; -+ TOK past = tk->value; - if (past == TOKgoesto) - { // (arguments) => expression - goto case_delegate; -@@ -5963,8 +6237,8 @@ Expression *Parser::parsePrimaryExp() - int varargs = 0; - Type *tret = NULL; - StorageClass stc = 0; -- enum TOK save = TOKreserved; -- Loc loc = this->loc; -+ TOK save = TOKreserved; -+ Loc loc = token.loc; - - switch (token.value) - { -@@ -5991,7 +6265,6 @@ Expression *Parser::parsePrimaryExp() - /* fall through to TOKlparen */ - - case TOKlparen: -- Lparen: - { // (parameters) => expression - // (parameters) { statements... } - parameters = parseParameters(&varargs, &tpl); -@@ -6025,15 +6298,15 @@ Expression *Parser::parsePrimaryExp() - if (!parameters) - parameters = new Parameters(); - TypeFunction *tf = new TypeFunction(parameters, tret, varargs, linkage, stc); -- FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, save, NULL); -+ FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, Loc(), tf, save, NULL); - - if (token.value == TOKgoesto) - { - check(TOKgoesto); -- Loc loc = this->loc; -+ Loc loc = token.loc; - Expression *ae = parseAssignExp(); - fd->fbody = new ReturnStatement(loc, ae); -- fd->endloc = this->loc; -+ fd->endloc = token.loc; - } - else - { -@@ -6070,7 +6343,7 @@ Expression *Parser::parsePostExp(Express - - while (1) - { -- loc = this->loc; -+ loc = token.loc; - switch (token.value) - { - case TOKdot: -@@ -6081,7 +6354,6 @@ Expression *Parser::parsePostExp(Express - nextToken(); - if (token.value == TOKnot && peekNext() != TOKis && peekNext() != TOKin) - { // identifier!(template-argument-list) -- TemplateInstance *tempinst = new TemplateInstance(loc, id); - Objects *tiargs; - nextToken(); - if (token.value == TOKlparen) -@@ -6174,8 +6446,9 @@ Expression *Parser::parsePostExp(Express - } - - Expression *Parser::parseUnaryExp() --{ Expression *e; -- Loc loc = this->loc; -+{ -+ Expression *e; -+ Loc loc = token.loc; - - switch (token.value) - { -@@ -6235,10 +6508,6 @@ Expression *Parser::parseUnaryExp() - e = new DeleteExp(loc, e); - break; - -- case TOKnew: -- e = parseNewExp(NULL); -- break; -- - case TOKcast: // cast(type) expression - { - nextToken(); -@@ -6260,7 +6529,7 @@ Expression *Parser::parseUnaryExp() - else if ((token.value == TOKimmutable || token.value == TOKinvariant) && peekNext() == TOKrparen) - { - if (token.value == TOKinvariant) -- deprecation("use of 'invariant' rather than 'immutable' is deprecated"); -+ error("use 'immutable' instead of 'invariant'"); - m = MODimmutable; - goto Lmod2; - } -@@ -6307,13 +6576,25 @@ Expression *Parser::parseUnaryExp() - case TOKshared: - case TOKconst: - case TOKinvariant: -- case TOKimmutable: // immutable(type)(arguments) -+ case TOKimmutable: // immutable(type)(arguments) / immutable(type).init - { - StorageClass stc = parseTypeCtor(); - Type *t = parseBasicType(); - t = t->addSTC(stc); - e = new TypeExp(loc, t); -- if (token.value != TOKlparen) -+ if (stc == 0 && token.value == TOKdot) -+ { -+ nextToken(); -+ if (token.value != TOKidentifier) -+ { error("Identifier expected following (type)."); -+ return NULL; -+ } -+ e = typeDotIdExp(loc, t, token.ident); -+ nextToken(); -+ e = parsePostExp(e); -+ break; -+ } -+ else if (token.value != TOKlparen) - { - error("(arguments) expected following %s", t->toChars()); - return e; -@@ -6378,6 +6659,9 @@ Expression *Parser::parseUnaryExp() - #if DMDV2 - case TOKfile: - case TOKline: -+ case TOKmodulestring: -+ case TOKfuncstring: -+ case TOKprettyfunc: - #endif - case BASIC_TYPES: // (type)int.size - { // (type) una_exp -@@ -6388,15 +6672,15 @@ Expression *Parser::parseUnaryExp() - check(TOKrparen); - - // if .identifier -+ // or .identifier!( ... ) - if (token.value == TOKdot) - { -- nextToken(); -- if (token.value != TOKidentifier) -- { error("Identifier expected following (type)."); -+ if (peekNext() != TOKidentifier && peekNext() != TOKnew) -+ { -+ error("identifier or new keyword expected following (...)."); - return NULL; - } -- e = typeDotIdExp(loc, t, token.ident); -- nextToken(); -+ e = new TypeExp(loc, t); - e = parsePostExp(e); - } - else -@@ -6407,6 +6691,8 @@ Expression *Parser::parseUnaryExp() - } - return e; - } -+ default: -+ break; - } - } - #endif -@@ -6433,9 +6719,10 @@ Expression *Parser::parseUnaryExp() - } - - Expression *Parser::parseMulExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseUnaryExp(); - while (1) -@@ -6455,9 +6742,10 @@ Expression *Parser::parseMulExp() - } - - Expression *Parser::parseAddExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseMulExp(); - while (1) -@@ -6477,9 +6765,10 @@ Expression *Parser::parseAddExp() - } - - Expression *Parser::parseShiftExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseAddExp(); - while (1) -@@ -6500,10 +6789,11 @@ Expression *Parser::parseShiftExp() - - #if DMDV1 - Expression *Parser::parseRelExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; -- enum TOK op; -- Loc loc = this->loc; -+ TOK op; -+ Loc loc = token.loc; - - e = parseShiftExp(); - while (1) -@@ -6557,14 +6847,15 @@ Expression *Parser::parseRelExp() - - #if DMDV1 - Expression *Parser::parseEqualExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; - Token *t; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseRelExp(); - while (1) -- { enum TOK value = token.value; -+ { TOK value = token.value; - - switch (value) - { -@@ -6612,13 +6903,14 @@ Expression *Parser::parseEqualExp() - #endif - - Expression *Parser::parseCmpExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; - Token *t; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseShiftExp(); -- enum TOK op = token.value; -+ TOK op = token.value; - - switch (op) - { -@@ -6688,7 +6980,7 @@ Expression *Parser::parseCmpExp() - - Expression *Parser::parseAndExp() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - Expression *e = parseCmpExp(); - while (token.value == TOKand) -@@ -6698,14 +6990,14 @@ Expression *Parser::parseAndExp() - Expression *e2 = parseCmpExp(); - checkParens(TOKand, e2); - e = new AndExp(loc,e,e2); -- loc = this->loc; -+ loc = token.loc; - } - return e; - } - - Expression *Parser::parseXorExp() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - Expression *e = parseAndExp(); - while (token.value == TOKxor) -@@ -6721,7 +7013,7 @@ Expression *Parser::parseXorExp() - - Expression *Parser::parseOrExp() - { -- Loc loc = this->loc; -+ Loc loc = token.loc; - - Expression *e = parseXorExp(); - while (token.value == TOKor) -@@ -6736,9 +7028,10 @@ Expression *Parser::parseOrExp() - } - - Expression *Parser::parseAndAndExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseOrExp(); - while (token.value == TOKandand) -@@ -6751,9 +7044,10 @@ Expression *Parser::parseAndAndExp() - } - - Expression *Parser::parseOrOrExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseAndAndExp(); - while (token.value == TOKoror) -@@ -6766,10 +7060,11 @@ Expression *Parser::parseOrOrExp() - } - - Expression *Parser::parseCondExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e1; - Expression *e2; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - e = parseOrOrExp(); - if (token.value == TOKquestion) -@@ -6784,14 +7079,15 @@ Expression *Parser::parseCondExp() - } - - Expression *Parser::parseAssignExp() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; - Loc loc; - - e = parseCondExp(); - while (1) - { -- loc = this->loc; -+ loc = token.loc; - switch (token.value) - { - #define X(tok,ector) \ -@@ -6822,9 +7118,10 @@ Expression *Parser::parseAssignExp() - } - - Expression *Parser::parseExpression() --{ Expression *e; -+{ -+ Expression *e; - Expression *e2; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - //printf("Parser::parseExpression() loc = %d\n", loc.linnum); - e = parseAssignExp(); -@@ -6833,7 +7130,7 @@ Expression *Parser::parseExpression() - nextToken(); - e2 = parseAssignExp(); - e = new CommaExp(loc, e, e2); -- loc = this->loc; -+ loc = token.loc; - } - return e; - } -@@ -6848,7 +7145,7 @@ Expressions *Parser::parseArguments() - { // function call - Expressions *arguments; - Expression *arg; -- enum TOK endtok; -+ TOK endtok; - - arguments = new Expressions(); - if (token.value == TOKlbracket) -@@ -6875,11 +7172,12 @@ Expressions *Parser::parseArguments() - */ - - Expression *Parser::parseNewExp(Expression *thisexp) --{ Type *t; -+{ -+ Type *t; - Expressions *newargs; - Expressions *arguments = NULL; - Expression *e; -- Loc loc = this->loc; -+ Loc loc = token.loc; - - nextToken(); - newargs = NULL; -@@ -6961,7 +7259,7 @@ Expression *Parser::parseNewExp(Expressi - /********************************************** - */ - --void Parser::addComment(Dsymbol *s, unsigned char *blockComment) -+void Parser::addComment(Dsymbol *s, utf8_t *blockComment) - { - s->addComment(combineComments(blockComment, token.lineComment)); - token.lineComment = NULL; -@@ -6972,7 +7270,7 @@ void Parser::addComment(Dsymbol *s, unsi - * Set operator precedence for each operator. - */ - --enum PREC precedence[TOKMAX]; -+PREC precedence[TOKMAX]; - - void initPrecedence() - { -@@ -6997,9 +7295,13 @@ void initPrecedence() - precedence[TOKstring] = PREC_primary; - precedence[TOKarrayliteral] = PREC_primary; - precedence[TOKassocarrayliteral] = PREC_primary; -+ precedence[TOKclassreference] = PREC_primary; - #if DMDV2 - precedence[TOKfile] = PREC_primary; - precedence[TOKline] = PREC_primary; -+ precedence[TOKmodulestring] = PREC_primary; -+ precedence[TOKfuncstring] = PREC_primary; -+ precedence[TOKprettyfunc] = PREC_primary; - #endif - precedence[TOKtypeid] = PREC_primary; - precedence[TOKis] = PREC_primary; ---- a/src/gcc/d/dfrontend/parse.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/parse.h 2014-04-01 16:32:51.000000000 +0100 -@@ -19,32 +19,32 @@ - #include "lexer.h" - #include "enum.h" - --struct Type; --struct TypeQualified; --struct Expression; --struct Declaration; --struct Statement; --struct Import; --struct Initializer; --struct FuncDeclaration; --struct CtorDeclaration; --struct PostBlitDeclaration; --struct DtorDeclaration; --struct StaticCtorDeclaration; --struct StaticDtorDeclaration; --struct SharedStaticCtorDeclaration; --struct SharedStaticDtorDeclaration; --struct ConditionalDeclaration; --struct InvariantDeclaration; --struct UnitTestDeclaration; --struct NewDeclaration; --struct DeleteDeclaration; --struct Condition; --struct Module; -+class Type; -+class TypeQualified; -+class Expression; -+class Declaration; -+class Statement; -+class Import; -+class Initializer; -+class FuncDeclaration; -+class CtorDeclaration; -+class PostBlitDeclaration; -+class DtorDeclaration; -+class StaticCtorDeclaration; -+class StaticDtorDeclaration; -+class SharedStaticCtorDeclaration; -+class SharedStaticDtorDeclaration; -+class ConditionalDeclaration; -+class InvariantDeclaration; -+class UnitTestDeclaration; -+class NewDeclaration; -+class DeleteDeclaration; -+class Condition; -+class Module; - struct ModuleDeclaration; --struct TemplateDeclaration; --struct TemplateInstance; --struct StaticAssert; -+class TemplateDeclaration; -+class TemplateInstance; -+class StaticAssert; - - /************************************ - * These control how parseStatement() works. -@@ -60,20 +60,21 @@ enum ParseStatementFlags - }; - - --struct Parser : Lexer -+class Parser : public Lexer - { -+public: - ModuleDeclaration *md; -- enum LINK linkage; -+ LINK linkage; - Loc endloc; // set to location of last right curly - int inBrackets; // inside [] of array index or slice - Loc lookingForElse; // location of lonely if looking for an else - -- Parser(Module *module, unsigned char *base, size_t length, int doDocComment); -+ Parser(Module *module, utf8_t *base, size_t length, int doDocComment); - - Dsymbols *parseModule(); -- Dsymbols *parseDeclDefs(int once); -- Dsymbols *parseAutoDeclarations(StorageClass storageClass, unsigned char *comment); -- Dsymbols *parseBlock(); -+ Dsymbols *parseDeclDefs(int once, Dsymbol **pLastDecl = NULL); -+ Dsymbols *parseAutoDeclarations(StorageClass storageClass, utf8_t *comment); -+ Dsymbols *parseBlock(Dsymbol **pLastDecl); - void composeStorageClass(StorageClass stc); - StorageClass parseAttribute(Expressions **pexps); - StorageClass parsePostfix(); -@@ -88,7 +89,7 @@ struct Parser : Lexer - StaticAssert *parseStaticAssert(); - TypeQualified *parseTypeof(); - Type *parseVector(); -- enum LINK parseLinkage(); -+ LINK parseLinkage(); - Condition *parseDebugCondition(); - Condition *parseVersionCondition(); - Condition *parseStaticIfCondition(); -@@ -111,22 +112,23 @@ struct Parser : Lexer - Type *parseBasicType(); - Type *parseBasicType2(Type *t); - Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL, StorageClass storage_class = 0, int* pdisable = NULL); -- Dsymbols *parseDeclarations(StorageClass storage_class, unsigned char *comment); -+ Dsymbols *parseDeclarations(StorageClass storage_class, utf8_t *comment); - void parseContracts(FuncDeclaration *f); - void checkDanglingElse(Loc elseloc); -- Statement *parseStatement(int flags); -+ /** endPtr used for documented unittests */ -+ Statement *parseStatement(int flags, utf8_t** endPtr = NULL); - #ifdef IN_GCC - Statement *parseExtAsm(); - #endif - Initializer *parseInitializer(); - Expression *parseDefaultInitExp(); -- void check(Loc loc, enum TOK value); -- void check(enum TOK value); -- void check(enum TOK value, const char *string); -- void checkParens(enum TOK value, Expression *e); -- int isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt); -+ void check(Loc loc, TOK value); -+ void check(TOK value); -+ void check(TOK value, const char *string); -+ void checkParens(TOK value, Expression *e); -+ int isDeclaration(Token *t, int needId, TOK endtok, Token **pt); - int isBasicType(Token **pt); -- int isDeclarator(Token **pt, int *haveId, enum TOK endtok); -+ int isDeclarator(Token **pt, int *haveId, int *haveTpl, TOK endtok); - int isParameters(Token **pt); - int isExpression(Token **pt); - int skipParens(Token *t, Token **pt); -@@ -156,7 +158,7 @@ struct Parser : Lexer - - Expression *parseNewExp(Expression *thisexp); - -- void addComment(Dsymbol *s, unsigned char *blockComment); -+ void addComment(Dsymbol *s, utf8_t *blockComment); - }; - - // Operator precedence - greater values are higher precedence -@@ -182,7 +184,7 @@ enum PREC - PREC_primary, - }; - --extern enum PREC precedence[TOKMAX]; -+extern PREC precedence[TOKMAX]; - - void initPrecedence(); - ---- a/src/gcc/d/dfrontend/port.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/port.h 2014-04-01 16:32:51.000000000 +0100 -@@ -10,37 +10,13 @@ - // Portable wrapper around compiler/system specific things. - // The idea is to minimize #ifdef's in the app code. - -+#include // for alloca - #include - - #include "longdouble.h" - --// Be careful not to care about sign when using dinteger_t --//typedef uint64_t integer_t; --typedef uint64_t dinteger_t; // use this instead of integer_t to -- // avoid conflicts with system #include's -- --// Signed and unsigned variants --typedef int64_t sinteger_t; --typedef uint64_t uinteger_t; -- --typedef int8_t d_int8; --typedef uint8_t d_uns8; --typedef int16_t d_int16; --typedef uint16_t d_uns16; --typedef int32_t d_int32; --typedef uint32_t d_uns32; --typedef int64_t d_int64; --typedef uint64_t d_uns64; -- --typedef float d_float32; --typedef double d_float64; --typedef longdouble d_float80; -- --typedef d_uns8 d_char; --typedef d_uns16 d_wchar; --typedef d_uns32 d_dchar; -- - #if _MSC_VER -+#include - typedef __int64 longlong; - typedef unsigned __int64 ulonglong; - #else -@@ -48,11 +24,14 @@ typedef long long longlong; - typedef unsigned long long ulonglong; - #endif - -+typedef unsigned char utf8_t; -+ - struct Port - { -- static longdouble nan; -+ static longdouble ldbl_nan; - static longdouble snan; -- static longdouble infinity; -+ static longdouble ldbl_infinity; -+ static longdouble ldbl_max; - - static void init(); - -@@ -61,11 +40,16 @@ struct Port - static int isInfinity(longdouble); - - static longdouble fmodl(longdouble x, longdouble y); -+ static int fequal(longdouble x, longdouble y); - - static char *strupr(char *); - - static int memicmp(const char *s1, const char *s2, int n); - static int stricmp(const char *s1, const char *s2); -+ -+ static longdouble strtof(const char *p, char **endp); -+ static longdouble strtod(const char *p, char **endp); -+ static longdouble strtold(const char *p, char **endp); - }; - - #endif ---- a/src/gcc/d/dfrontend/readme.txt 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/readme.txt 2014-04-01 16:32:51.000000000 +0100 -@@ -1,15 +1,15 @@ - - The D Programming Language - Compiler Front End Source -- Copyright (c) 1999-2009, by Digital Mars -- http://www.digitalmars.com -+ Copyright (c) 1999-2013, by Digital Mars -+ http://www.digitalmars.com/ - All Rights Reserved - - - This is the source code to the front end Digital Mars D compiler. - It covers the lexical analysis, parsing, and semantic analysis - of the D Programming Language defined in the documents at --http://www.digitalmars.com/d/ -+http://dlang.org/ - - These sources are free, they are redistributable and modifiable - under the terms of the GNU General Public License as published by ---- a/src/gcc/d/dfrontend/rmem.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/rmem.c 2014-04-01 16:32:51.000000000 +0100 -@@ -11,15 +11,7 @@ - #include - #include - --#ifdef IN_GCC --#include "rmem.h" --#else --#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4 --#include "../root/rmem.h" --#else - #include "rmem.h" --#endif --#endif - - /* This implementation of the storage allocator uses the standard C allocation package. - */ -@@ -30,6 +22,23 @@ void Mem::init() - { - } - -+#ifdef IN_GCC -+void *mem_malloc(size_t size) -+{ -+ return mem.malloc(size); -+} -+ -+void *mem_realloc(void *p, size_t size) -+{ -+ return mem.realloc(p, size); -+} -+ -+void mem_free(void *p) -+{ -+ mem.free(p); -+} -+#endif -+ - char *Mem::strdup(const char *s) - { - char *p; -@@ -146,6 +155,61 @@ void Mem::addroots(char* pStart, char* p - - /* =================================================== */ - -+#if 1 -+ -+/* Allocate, but never release -+ */ -+ -+// Allocate a little less than 64kB because the C runtime adds some overhead that -+// causes the actual memory block to be larger than 64kB otherwise. E.g. the dmc -+// runtime rounds the size up to 128kB, but the remaining space in the chunk is less -+// than 64kB, so it cannot be used by another chunk. -+#define CHUNK_SIZE (4096 * 16 - 64) -+ -+static size_t heapleft = 0; -+static void *heapp; -+ -+void * operator new(size_t m_size) -+{ -+ // 16 byte alignment is better (and sometimes needed) for doubles -+ m_size = (m_size + 15) & ~15; -+ -+ // The layout of the code is selected so the most common case is straight through -+ if (m_size <= heapleft) -+ { -+ L1: -+ heapleft -= m_size; -+ void *p = heapp; -+ heapp = (void *)((char *)heapp + m_size); -+ return p; -+ } -+ -+ if (m_size > CHUNK_SIZE) -+ { -+ void *p = malloc(m_size); -+ if (p) -+ return p; -+ printf("Error: out of memory\n"); -+ exit(EXIT_FAILURE); -+ return p; -+ } -+ -+ heapleft = CHUNK_SIZE; -+ heapp = malloc(CHUNK_SIZE); -+ if (!heapp) -+ { -+ printf("Error: out of memory\n"); -+ exit(EXIT_FAILURE); -+ } -+ goto L1; -+} -+ -+void operator delete(void *p) -+{ -+} -+ -+#else -+ - void * operator new(size_t m_size) - { - void *p = malloc(m_size); -@@ -161,4 +225,4 @@ void operator delete(void *p) - free(p); - } - -- -+#endif ---- a/src/gcc/d/dfrontend/root.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/root.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,1972 +0,0 @@ -- --// Copyright (c) 1999-2012 by Digital Mars --// All Rights Reserved --// written by Walter Bright --// http://www.digitalmars.com --// License for redistribution is by either the Artistic License --// in artistic.txt, or the GNU General Public License in gnu.txt. --// See the included readme.txt for details. -- --#define POSIX (linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun) -- --#include --#include --#include --#include --#include --#include --#include --#include -- --#if defined (__sun) --#include --#endif -- --#if _MSC_VER ||__MINGW32__ --#include --#include --#endif -- --#if _WIN32 --#include --#include --#include --#endif -- --#if POSIX --#include --#include --#include --#include --#include --#include --#endif -- --#include "port.h" --#include "root.h" --#include "rmem.h" -- --#if 0 //__SC__ //def DEBUG --extern "C" void __cdecl _assert(void *e, void *f, unsigned line) --{ -- printf("Assert('%s','%s',%d)\n",e,f,line); -- fflush(stdout); -- *(char *)0 = 0; --} --#endif -- --#ifdef IN_GCC --#include "config.h" --#include "errors.h" --#else --/************************************** -- * Print error message and exit. -- */ -- --void error(const char *format, ...) --{ -- va_list ap; -- -- va_start(ap, format); -- fprintf(stderr, "Error: "); -- vfprintf(stderr, format, ap); -- va_end( ap ); -- printf("\n"); -- fflush(stderr); -- -- exit(EXIT_FAILURE); --} -- --/************************************** -- * Print warning message. -- */ -- --void warning(const char *format, ...) --{ -- va_list ap; -- -- va_start(ap, format); -- fprintf(stderr, "Warning: "); -- vfprintf(stderr, format, ap); -- va_end( ap ); -- printf("\n"); -- fflush(stderr); --} --#endif -- --/****************************** Object ********************************/ -- --int Object::equals(Object *o) --{ -- return o == this; --} -- --hash_t Object::hashCode() --{ -- return (hash_t) this; --} -- --int Object::compare(Object *obj) --{ -- return this - obj; --} -- --void Object::print() --{ -- fprintf(stderr, "%s %p\n", toChars(), this); --} -- --char *Object::toChars() --{ -- return (char *)"Object"; --} -- --int Object::dyncast() --{ -- return 0; --} -- --void Object::toBuffer(OutBuffer *b) --{ -- b->writestring("Object"); --} -- --void Object::mark() --{ --} -- --/****************************** String ********************************/ -- --String::String(const char *str) -- : str(mem.strdup(str)) --{ --} -- --String::~String() --{ -- mem.free((void *)str); --} -- --void String::mark() --{ -- mem.mark((void *)str); --} -- --hash_t String::calcHash(const char *str, size_t len) --{ -- hash_t hash = 0; -- -- for (;;) -- { -- switch (len) -- { -- case 0: -- return hash; -- -- case 1: -- hash *= 37; -- hash += *(uint8_t *)str; -- return hash; -- -- case 2: -- hash *= 37; -- hash += *(uint16_t *)str; -- return hash; -- -- case 3: -- hash *= 37; -- hash += (*(uint16_t *)str << 8) + -- ((uint8_t *)str)[2]; -- return hash; -- -- default: -- hash *= 37; -- hash += *(uint32_t *)str; -- str += 4; -- len -= 4; -- break; -- } -- } --} -- --hash_t String::calcHash(const char *str) --{ -- return calcHash(str, strlen(str)); --} -- --hash_t String::hashCode() --{ -- return calcHash(str, strlen(str)); --} -- --size_t String::len() --{ -- return strlen(str); --} -- --int String::equals(Object *obj) --{ -- return strcmp(str,((String *)obj)->str) == 0; --} -- --int String::compare(Object *obj) --{ -- return strcmp(str,((String *)obj)->str); --} -- --char *String::toChars() --{ -- return (char *)str; // toChars() should really be const --} -- --void String::print() --{ -- fprintf(stderr, "String '%s'\n",str); --} -- -- --/****************************** FileName ********************************/ -- --FileName::FileName(const char *str) -- : String(str) --{ --} -- --const char *FileName::combine(const char *path, const char *name) --{ char *f; -- size_t pathlen; -- size_t namelen; -- -- if (!path || !*path) -- return (char *)name; -- pathlen = strlen(path); -- namelen = strlen(name); -- f = (char *)mem.malloc(pathlen + 1 + namelen + 1); -- memcpy(f, path, pathlen); --#if POSIX -- if (path[pathlen - 1] != '/') -- { f[pathlen] = '/'; -- pathlen++; -- } --#elif _WIN32 -- if (path[pathlen - 1] != '\\' && -- path[pathlen - 1] != '/' && -- path[pathlen - 1] != ':') -- { f[pathlen] = '\\'; -- pathlen++; -- } --#else -- assert(0); --#endif -- memcpy(f + pathlen, name, namelen + 1); -- return f; --} -- --// Split a path into an Array of paths --Strings *FileName::splitPath(const char *path) --{ -- char c = 0; // unnecessary initializer is for VC /W4 -- const char *p; -- OutBuffer buf; -- Strings *array; -- -- array = new Strings(); -- if (path) -- { -- p = path; -- do -- { char instring = 0; -- -- while (isspace((unsigned char)*p)) // skip leading whitespace -- p++; -- buf.reserve(strlen(p) + 1); // guess size of path -- for (; ; p++) -- { -- c = *p; -- switch (c) -- { -- case '"': -- instring ^= 1; // toggle inside/outside of string -- continue; -- --#if MACINTOSH -- case ',': --#endif --#if _WIN32 -- case ';': --#endif --#if POSIX -- case ':': --#endif -- p++; -- break; // note that ; cannot appear as part -- // of a path, quotes won't protect it -- -- case 0x1A: // ^Z means end of file -- case 0: -- break; -- -- case '\r': -- continue; // ignore carriage returns -- --#if POSIX -- case '~': -- buf.writestring(getenv("HOME")); -- continue; --#endif -- --#if 0 -- case ' ': -- case '\t': // tabs in filenames? -- if (!instring) // if not in string -- break; // treat as end of path --#endif -- default: -- buf.writeByte(c); -- continue; -- } -- break; -- } -- if (buf.offset) // if path is not empty -- { -- buf.writeByte(0); // to asciiz -- array->push(buf.extractData()); -- } -- } while (c); -- } -- return array; --} -- --hash_t FileName::hashCode() --{ --#if _WIN32 -- // We need a different hashCode because it must be case-insensitive -- size_t len = strlen(str); -- hash_t hash = 0; -- unsigned char *s = (unsigned char *)str; -- -- for (;;) -- { -- switch (len) -- { -- case 0: -- return hash; -- -- case 1: -- hash *= 37; -- hash += *(uint8_t *)s | 0x20; -- return hash; -- -- case 2: -- hash *= 37; -- hash += *(uint16_t *)s | 0x2020; -- return hash; -- -- case 3: -- hash *= 37; -- hash += ((*(uint16_t *)s << 8) + -- ((uint8_t *)s)[2]) | 0x202020; -- break; -- -- default: -- hash *= 37; -- hash += *(uint32_t *)s | 0x20202020; -- s += 4; -- len -= 4; -- break; -- } -- } --#else -- // darwin HFS is case insensitive, though... -- return String::hashCode(); --#endif --} -- --int FileName::compare(Object *obj) --{ -- return compare(str, ((FileName *)obj)->str); --} -- --int FileName::compare(const char *name1, const char *name2) --{ --#if _WIN32 -- return stricmp(name1, name2); --#else -- return strcmp(name1, name2); --#endif --} -- --int FileName::equals(Object *obj) --{ -- return compare(obj) == 0; --} -- --int FileName::equals(const char *name1, const char *name2) --{ -- return compare(name1, name2) == 0; --} -- --/************************************ -- * Return !=0 if absolute path name. -- */ -- --int FileName::absolute(const char *name) --{ --#if _WIN32 -- return (*name == '\\') || -- (*name == '/') || -- (*name && name[1] == ':'); --#elif POSIX -- return (*name == '/'); --#else -- assert(0); --#endif --} -- --/******************************** -- * Return filename extension (read-only). -- * Points past '.' of extension. -- * If there isn't one, return NULL. -- */ -- --const char *FileName::ext(const char *str) --{ -- size_t len = strlen(str); -- -- const char *e = str + len; -- for (;;) -- { -- switch (*e) -- { case '.': -- return e + 1; --#if POSIX -- case '/': -- break; --#endif --#if _WIN32 -- case '\\': -- case ':': -- case '/': -- break; --#endif -- default: -- if (e == str) -- break; -- e--; -- continue; -- } -- return NULL; -- } --} -- --const char *FileName::ext() --{ -- return ext(str); --} -- --/******************************** -- * Return mem.malloc'd filename with extension removed. -- */ -- --const char *FileName::removeExt(const char *str) --{ -- const char *e = ext(str); -- if (e) -- { size_t len = (e - str) - 1; -- char *n = (char *)mem.malloc(len + 1); -- memcpy(n, str, len); -- n[len] = 0; -- return n; -- } -- return mem.strdup(str); --} -- --/******************************** -- * Return filename name excluding path (read-only). -- */ -- --const char *FileName::name(const char *str) --{ -- size_t len = strlen(str); -- -- const char *e = str + len; -- for (;;) -- { -- switch (*e) -- { --#if POSIX -- case '/': -- return e + 1; --#endif --#if _WIN32 -- case '/': -- case '\\': -- return e + 1; -- case ':': -- /* The ':' is a drive letter only if it is the second -- * character or the last character, -- * otherwise it is an ADS (Alternate Data Stream) separator. -- * Consider ADS separators as part of the file name. -- */ -- if (e == str + 1 || e == str + len - 1) -- return e + 1; --#endif -- default: -- if (e == str) -- break; -- e--; -- continue; -- } -- return e; -- } --} -- --const char *FileName::name() --{ -- return name(str); --} -- --/************************************** -- * Return path portion of str. -- * Path will does not include trailing path separator. -- */ -- --const char *FileName::path(const char *str) --{ -- const char *n = name(str); -- size_t pathlen; -- -- if (n > str) -- { --#if POSIX -- if (n[-1] == '/') -- n--; --#elif _WIN32 -- if (n[-1] == '\\' || n[-1] == '/') -- n--; --#else -- assert(0); --#endif -- } -- pathlen = n - str; -- char *path = (char *)mem.malloc(pathlen + 1); -- memcpy(path, str, pathlen); -- path[pathlen] = 0; -- return path; --} -- --/************************************** -- * Replace filename portion of path. -- */ -- --const char *FileName::replaceName(const char *path, const char *name) --{ -- size_t pathlen; -- size_t namelen; -- -- if (absolute(name)) -- return name; -- -- const char *n = FileName::name(path); -- if (n == path) -- return name; -- pathlen = n - path; -- namelen = strlen(name); -- char *f = (char *)mem.malloc(pathlen + 1 + namelen + 1); -- memcpy(f, path, pathlen); --#if POSIX -- if (path[pathlen - 1] != '/') -- { f[pathlen] = '/'; -- pathlen++; -- } --#elif _WIN32 -- if (path[pathlen - 1] != '\\' && -- path[pathlen - 1] != '/' && -- path[pathlen - 1] != ':') -- { f[pathlen] = '\\'; -- pathlen++; -- } --#else -- assert(0); --#endif -- memcpy(f + pathlen, name, namelen + 1); -- return f; --} -- --/*************************** -- * Free returned value with FileName::free() -- */ -- --const char *FileName::defaultExt(const char *name, const char *ext) --{ -- const char *e = FileName::ext(name); -- if (e) // if already has an extension -- return mem.strdup(name); -- -- size_t len = strlen(name); -- size_t extlen = strlen(ext); -- char *s = (char *)mem.malloc(len + 1 + extlen + 1); -- memcpy(s,name,len); -- s[len] = '.'; -- memcpy(s + len + 1, ext, extlen + 1); -- return s; --} -- --/*************************** -- * Free returned value with FileName::free() -- */ -- --const char *FileName::forceExt(const char *name, const char *ext) --{ -- const char *e = FileName::ext(name); -- if (e) // if already has an extension -- { -- size_t len = e - name; -- size_t extlen = strlen(ext); -- -- char *s = (char *)mem.malloc(len + extlen + 1); -- memcpy(s,name,len); -- memcpy(s + len, ext, extlen + 1); -- return s; -- } -- else -- return defaultExt(name, ext); // doesn't have one --} -- --/****************************** -- * Return !=0 if extensions match. -- */ -- --int FileName::equalsExt(const char *ext) --{ -- return equalsExt(str, ext); --} -- --int FileName::equalsExt(const char *name, const char *ext) --{ -- const char *e = FileName::ext(name); -- if (!e && !ext) -- return 1; -- if (!e || !ext) -- return 0; -- return FileName::compare(e, ext) == 0; --} -- --/************************************* -- * Copy file from this to to. -- */ -- --void FileName::CopyTo(FileName *to) --{ -- File file(this); -- --#if _WIN32 -- file.touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); // keep same file time --#elif POSIX -- file.touchtime = mem.malloc(sizeof(struct stat)); // keep same file time --#else -- assert(0); --#endif -- file.readv(); -- file.name = to; -- file.writev(); --} -- --/************************************* -- * Search Path for file. -- * Input: -- * cwd if !=0, search current directory before searching path -- */ -- --const char *FileName::searchPath(Strings *path, const char *name, int cwd) --{ -- if (absolute(name)) -- { -- return exists(name) ? name : NULL; -- } -- if (cwd) -- { -- if (exists(name)) -- return name; -- } -- if (path) -- { -- -- for (size_t i = 0; i < path->dim; i++) -- { -- const char *p = path->tdata()[i]; -- const char *n = combine(p, name); -- -- if (exists(n)) -- return n; -- } -- } -- return NULL; --} -- -- --/************************************* -- * Search Path for file in a safe manner. -- * -- * Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory -- * ('Path Traversal') attacks. -- * http://cwe.mitre.org/data/definitions/22.html -- * More info: -- * https://www.securecoding.cert.org/confluence/display/seccode/FIO02-C.+Canonicalize+path+names+originating+from+untrusted+sources -- * Returns: -- * NULL file not found -- * !=NULL mem.malloc'd file name -- */ -- --const char *FileName::safeSearchPath(Strings *path, const char *name) --{ --#if _WIN32 -- /* Disallow % / \ : and .. in name characters -- */ -- for (const char *p = name; *p; p++) -- { -- char c = *p; -- if (c == '\\' || c == '/' || c == ':' || c == '%' || -- (c == '.' && p[1] == '.')) -- { -- return NULL; -- } -- } -- -- return FileName::searchPath(path, name, 0); --#elif POSIX -- /* Even with realpath(), we must check for // and disallow it -- */ -- for (const char *p = name; *p; p++) -- { -- char c = *p; -- if (c == '/' && p[1] == '/') -- { -- return NULL; -- } -- } -- -- if (path) -- { -- /* Each path is converted to a cannonical name and then a check is done to see -- * that the searched name is really a child one of the the paths searched. -- */ -- for (size_t i = 0; i < path->dim; i++) -- { -- const char *cname = NULL; -- const char *cpath = canonicalName(path->tdata()[i]); -- //printf("FileName::safeSearchPath(): name=%s; path=%s; cpath=%s\n", -- // name, (char *)path->data[i], cpath); -- if (cpath == NULL) -- goto cont; -- cname = canonicalName(combine(cpath, name)); -- //printf("FileName::safeSearchPath(): cname=%s\n", cname); -- if (cname == NULL) -- goto cont; -- //printf("FileName::safeSearchPath(): exists=%i " -- // "strncmp(cpath, cname, %i)=%i\n", exists(cname), -- // strlen(cpath), strncmp(cpath, cname, strlen(cpath))); -- // exists and name is *really* a "child" of path -- if (exists(cname) && strncmp(cpath, cname, strlen(cpath)) == 0) -- { -- ::free((void *)cpath); -- const char *p = mem.strdup(cname); -- ::free((void *)cname); -- return p; -- } --cont: -- if (cpath) -- ::free((void *)cpath); -- if (cname) -- ::free((void *)cname); -- } -- } -- return NULL; --#else -- assert(0); --#endif --} -- -- --int FileName::exists(const char *name) --{ --#if POSIX -- struct stat st; -- -- if (stat(name, &st) < 0) -- return 0; -- if (S_ISDIR(st.st_mode)) -- return 2; -- return 1; --#elif _WIN32 -- DWORD dw; -- int result; -- -- dw = GetFileAttributesA(name); -- if (dw == -1L) -- result = 0; -- else if (dw & FILE_ATTRIBUTE_DIRECTORY) -- result = 2; -- else -- result = 1; -- return result; --#else -- assert(0); --#endif --} -- --void FileName::ensurePathExists(const char *path) --{ -- //printf("FileName::ensurePathExists(%s)\n", path ? path : ""); -- if (path && *path) -- { -- if (!exists(path)) -- { -- const char *p = FileName::path(path); -- if (*p) -- { --#if _WIN32 -- size_t len = strlen(path); -- if (len > 2 && p[-1] == ':' && path + 2 == p) -- { mem.free((void *)p); -- return; -- } --#endif -- ensurePathExists(p); -- mem.free((void *)p); -- } --#if _WIN32 -- if (path[strlen(path) - 1] != '\\') --#endif --#if POSIX -- if (path[strlen(path) - 1] != '\\') --#endif -- { -- //printf("mkdir(%s)\n", path); --#if _WIN32 -- if (_mkdir(path)) --#endif --#if POSIX -- if (mkdir(path, 0777)) --#endif -- { -- /* Don't error out if another instance of dmd just created -- * this directory -- */ -- if (errno != EEXIST) -- error("cannot create directory %s", path); -- } -- } -- } -- } --} -- --void FileName::ensurePathToNameExists(const char *name) --{ -- const char *pt = path(name); -- if (*pt) -- ensurePathExists(pt); -- free(pt); --} -- -- --/****************************************** -- * Return canonical version of name in a malloc'd buffer. -- * This code is high risk. -- */ --const char *FileName::canonicalName(const char *name) --{ --#if linux -- // Lovely glibc extension to do it for us -- return canonicalize_file_name(name); --#elif POSIX -- #if _POSIX_VERSION >= 200809L || defined (linux) -- // NULL destination buffer is allowed and preferred -- return realpath(name, NULL); -- #else -- char *cname = NULL; -- #if PATH_MAX -- /* PATH_MAX must be defined as a constant in , -- * otherwise using it is unsafe due to TOCTOU -- */ -- size_t path_max = (size_t)PATH_MAX; -- if (path_max > 0) -- { -- /* Need to add one to PATH_MAX because of realpath() buffer overflow bug: -- * http://isec.pl/vulnerabilities/isec-0011-wu-ftpd.txt -- */ -- cname = (char *)malloc(path_max + 1); -- if (cname == NULL) -- return NULL; -- } -- #endif -- return realpath(name, cname); -- #endif --#elif _WIN32 -- /* Apparently, there is no good way to do this on Windows. -- * GetFullPathName isn't it, but use it anyway. -- */ -- DWORD result = GetFullPathName(name, 0, NULL, NULL); -- if (result) -- { -- char *buf = (char *)malloc(result); -- result = GetFullPathName(name, result, buf, NULL); -- if (result == 0) -- { -- ::free(buf); -- return NULL; -- } -- return buf; -- } -- return NULL; --#else -- assert(0); -- return NULL; --#endif --} -- --/******************************** -- * Free memory allocated by FileName routines -- */ --void FileName::free(const char *str) --{ -- if (str) -- { assert(str[0] != 0xAB); -- memset((void *)str, 0xAB, strlen(str) + 1); // stomp -- } -- mem.free((void *)str); --} -- -- --/****************************** File ********************************/ -- --File::File(const FileName *n) --{ -- ref = 0; -- buffer = NULL; -- len = 0; -- touchtime = NULL; -- name = (FileName *)n; --} -- --File::File(const char *n) --{ -- ref = 0; -- buffer = NULL; -- len = 0; -- touchtime = NULL; -- name = new FileName(n); --} -- --File::~File() --{ -- if (buffer) -- { -- if (ref == 0) -- mem.free(buffer); --#if _WIN32 -- else if (ref == 2) -- UnmapViewOfFile(buffer); --#endif -- } -- if (touchtime) -- mem.free(touchtime); --} -- --void File::mark() --{ -- mem.mark(buffer); -- mem.mark(touchtime); -- mem.mark(name); --} -- --/************************************* -- */ -- --int File::read() --{ --#if POSIX -- off_t size; -- ssize_t numread; -- int fd; -- struct stat buf; -- int result = 0; -- char *name; -- -- name = this->name->toChars(); -- //printf("File::read('%s')\n",name); -- fd = open(name, O_RDONLY); -- if (fd == -1) -- { -- //printf("\topen error, errno = %d\n",errno); -- goto err1; -- } -- -- if (!ref) -- ::free(buffer); -- ref = 0; // we own the buffer now -- -- //printf("\tfile opened\n"); -- if (fstat(fd, &buf)) -- { -- fprintf(stderr, "\tfstat error, errno = %d\n",errno); -- goto err2; -- } -- size = buf.st_size; -- buffer = (unsigned char *) ::malloc(size + 2); -- if (!buffer) -- { -- fprintf(stderr, "\tmalloc error, errno = %d\n",errno); -- goto err2; -- } -- -- numread = ::read(fd, buffer, size); -- if (numread != size) -- { -- fprintf(stderr, "\tread error, errno = %d\n",errno); -- goto err2; -- } -- -- if (touchtime) -- memcpy(touchtime, &buf, sizeof(buf)); -- -- if (close(fd) == -1) -- { -- fprintf(stderr, "\tclose error, errno = %d\n",errno); -- goto err; -- } -- -- len = size; -- -- // Always store a wchar ^Z past end of buffer so scanner has a sentinel -- buffer[size] = 0; // ^Z is obsolete, use 0 -- buffer[size + 1] = 0; -- return 0; -- --err2: -- close(fd); --err: -- ::free(buffer); -- buffer = NULL; -- len = 0; -- --err1: -- result = 1; -- return result; --#elif _WIN32 -- DWORD size; -- DWORD numread; -- HANDLE h; -- int result = 0; -- char *name; -- -- name = this->name->toChars(); -- h = CreateFileA(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, -- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,0); -- if (h == INVALID_HANDLE_VALUE) -- goto err1; -- -- if (!ref) -- ::free(buffer); -- ref = 0; -- -- size = GetFileSize(h,NULL); -- buffer = (unsigned char *) ::malloc(size + 2); -- if (!buffer) -- goto err2; -- -- if (ReadFile(h,buffer,size,&numread,NULL) != TRUE) -- goto err2; -- -- if (numread != size) -- goto err2; -- -- if (touchtime) -- { -- if (!GetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime)) -- goto err2; -- } -- -- if (!CloseHandle(h)) -- goto err; -- -- len = size; -- -- // Always store a wchar ^Z past end of buffer so scanner has a sentinel -- buffer[size] = 0; // ^Z is obsolete, use 0 -- buffer[size + 1] = 0; -- return 0; -- --err2: -- CloseHandle(h); --err: -- ::free(buffer); -- buffer = NULL; -- len = 0; -- --err1: -- result = 1; -- return result; --#else -- assert(0); --#endif --} -- --/***************************** -- * Read a file with memory mapped file I/O. -- */ -- --int File::mmread() --{ --#if POSIX -- return read(); --#elif _WIN32 -- HANDLE hFile; -- HANDLE hFileMap; -- DWORD size; -- char *name; -- -- name = this->name->toChars(); -- hFile = CreateFile(name, GENERIC_READ, -- FILE_SHARE_READ, NULL, -- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -- if (hFile == INVALID_HANDLE_VALUE) -- goto Lerr; -- size = GetFileSize(hFile, NULL); -- //printf(" file created, size %d\n", size); -- -- hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,size,NULL); -- if (CloseHandle(hFile) != TRUE) -- goto Lerr; -- -- if (hFileMap == NULL) -- goto Lerr; -- -- //printf(" mapping created\n"); -- -- if (!ref) -- mem.free(buffer); -- ref = 2; -- buffer = (unsigned char *)MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL); -- if (CloseHandle(hFileMap) != TRUE) -- goto Lerr; -- if (buffer == NULL) // mapping view failed -- goto Lerr; -- -- len = size; -- //printf(" buffer = %p\n", buffer); -- -- return 0; -- --Lerr: -- return GetLastError(); // failure --#else -- assert(0); --#endif --} -- --/********************************************* -- * Write a file. -- * Returns: -- * 0 success -- */ -- --int File::write() --{ --#if POSIX -- int fd; -- ssize_t numwritten; -- char *name; -- -- name = this->name->toChars(); -- fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644); -- if (fd == -1) -- goto err; -- -- numwritten = ::write(fd, buffer, len); -- if (len != numwritten) -- goto err2; -- -- if (close(fd) == -1) -- goto err; -- -- if (touchtime) -- { struct utimbuf ubuf; -- -- ubuf.actime = ((struct stat *)touchtime)->st_atime; -- ubuf.modtime = ((struct stat *)touchtime)->st_mtime; -- if (utime(name, &ubuf)) -- goto err; -- } -- return 0; -- --err2: -- close(fd); -- ::remove(name); --err: -- return 1; --#elif _WIN32 -- HANDLE h; -- DWORD numwritten; -- char *name; -- -- name = this->name->toChars(); -- h = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, -- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); -- if (h == INVALID_HANDLE_VALUE) -- goto err; -- -- if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE) -- goto err2; -- -- if (len != numwritten) -- goto err2; -- -- if (touchtime) { -- SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime); -- } -- if (!CloseHandle(h)) -- goto err; -- return 0; -- --err2: -- CloseHandle(h); -- DeleteFileA(name); --err: -- return 1; --#else -- assert(0); --#endif --} -- --/********************************************* -- * Append to a file. -- * Returns: -- * 0 success -- */ -- --int File::append() --{ --#if POSIX -- return 1; --#elif _WIN32 -- HANDLE h; -- DWORD numwritten; -- char *name; -- -- name = this->name->toChars(); -- h = CreateFileA(name,GENERIC_WRITE,0,NULL,OPEN_ALWAYS, -- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); -- if (h == INVALID_HANDLE_VALUE) -- goto err; -- --#if 1 -- SetFilePointer(h, 0, NULL, FILE_END); --#else // INVALID_SET_FILE_POINTER doesn't seem to have a definition -- if (SetFilePointer(h, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) -- goto err; --#endif -- -- if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE) -- goto err2; -- -- if (len != numwritten) -- goto err2; -- -- if (touchtime) { -- SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime); -- } -- if (!CloseHandle(h)) -- goto err; -- return 0; -- --err2: -- CloseHandle(h); --err: -- return 1; --#else -- assert(0); --#endif --} -- --/************************************** -- */ -- --void File::readv() --{ -- if (read()) -- error("Error reading file '%s'",name->toChars()); --} -- --/************************************** -- */ -- --void File::mmreadv() --{ -- if (mmread()) -- readv(); --} -- --void File::writev() --{ -- if (write()) -- error("Error writing file '%s'",name->toChars()); --} -- --void File::appendv() --{ -- if (write()) -- error("Error appending to file '%s'",name->toChars()); --} -- --/******************************************* -- * Return !=0 if file exists. -- * 0: file doesn't exist -- * 1: normal file -- * 2: directory -- */ -- --int File::exists() --{ --#if POSIX -- return 0; --#elif _WIN32 -- DWORD dw; -- int result; -- char *name; -- -- name = this->name->toChars(); -- if (touchtime) -- dw = ((WIN32_FIND_DATAA *)touchtime)->dwFileAttributes; -- else -- dw = GetFileAttributesA(name); -- if (dw == -1L) -- result = 0; -- else if (dw & FILE_ATTRIBUTE_DIRECTORY) -- result = 2; -- else -- result = 1; -- return result; --#else -- assert(0); --#endif --} -- --void File::remove() --{ --#if POSIX -- ::remove(this->name->toChars()); --#elif _WIN32 -- DeleteFileA(this->name->toChars()); --#else -- assert(0); --#endif --} -- --Files *File::match(char *n) --{ -- return match(new FileName(n)); --} -- --Files *File::match(FileName *n) --{ --#if POSIX -- return NULL; --#elif _WIN32 -- HANDLE h; -- WIN32_FIND_DATAA fileinfo; -- -- Files *a = new Files(); -- const char *c = n->toChars(); -- const char *name = n->name(); -- h = FindFirstFileA(c,&fileinfo); -- if (h != INVALID_HANDLE_VALUE) -- { -- do -- { -- // Glue path together with name -- char *fn; -- File *f; -- -- fn = (char *)mem.malloc(name - c + strlen(fileinfo.cFileName) + 1); -- memcpy(fn, c, name - c); -- strcpy(fn + (name - c), fileinfo.cFileName); -- f = new File(fn); -- f->touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); -- memcpy(f->touchtime, &fileinfo, sizeof(fileinfo)); -- a->push(f); -- } while (FindNextFileA(h,&fileinfo) != FALSE); -- FindClose(h); -- } -- return a; --#else -- assert(0); --#endif --} -- --int File::compareTime(File *f) --{ --#if POSIX -- return 0; --#elif _WIN32 -- if (!touchtime) -- stat(); -- if (!f->touchtime) -- f->stat(); -- return CompareFileTime(&((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime, &((WIN32_FIND_DATAA *)f->touchtime)->ftLastWriteTime); --#else -- assert(0); --#endif --} -- --void File::stat() --{ --#if POSIX -- if (!touchtime) -- { -- touchtime = mem.calloc(1, sizeof(struct stat)); -- } --#elif _WIN32 -- HANDLE h; -- -- if (!touchtime) -- { -- touchtime = mem.calloc(1, sizeof(WIN32_FIND_DATAA)); -- } -- h = FindFirstFileA(name->toChars(),(WIN32_FIND_DATAA *)touchtime); -- if (h != INVALID_HANDLE_VALUE) -- { -- FindClose(h); -- } --#else -- assert(0); --#endif --} -- --void File::checkoffset(size_t offset, size_t nbytes) --{ -- if (offset > len || offset + nbytes > len) -- error("Corrupt file '%s': offset x%llx off end of file",toChars(),(ulonglong)offset); --} -- --char *File::toChars() --{ -- return name->toChars(); --} -- -- --/************************* OutBuffer *************************/ -- --OutBuffer::OutBuffer() --{ -- data = NULL; -- offset = 0; -- size = 0; -- -- doindent = 0; -- level = 0; -- linehead = 1; --} -- --OutBuffer::~OutBuffer() --{ -- mem.free(data); --} -- --char *OutBuffer::extractData() --{ -- char *p; -- -- p = (char *)data; -- data = NULL; -- offset = 0; -- size = 0; -- return p; --} -- --void OutBuffer::mark() --{ -- mem.mark(data); --} -- --void OutBuffer::reserve(size_t nbytes) --{ -- //printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes); -- if (size - offset < nbytes) -- { -- size = (offset + nbytes) * 2; -- data = (unsigned char *)mem.realloc(data, size); -- } --} -- --void OutBuffer::reset() --{ -- offset = 0; --} -- --void OutBuffer::setsize(size_t size) --{ -- offset = size; --} -- --void OutBuffer::write(const void *data, size_t nbytes) --{ -- if (doindent && linehead) -- { -- if (level) -- { -- reserve(level); -- for (size_t i=0; idata[offset] = '\t'; -- offset++; -- } -- } -- linehead = 0; -- } -- reserve(nbytes); -- memcpy(this->data + offset, data, nbytes); -- offset += nbytes; --} -- --void OutBuffer::writebstring(unsigned char *string) --{ -- write(string,*string + 1); --} -- --void OutBuffer::writestring(const char *string) --{ -- write(string,strlen(string)); --} -- --void OutBuffer::prependstring(const char *string) --{ -- size_t len = strlen(string); -- reserve(len); -- memmove(data + len, data, offset); -- memcpy(data, string, len); -- offset += len; --} -- --void OutBuffer::writenl() --{ --#if _WIN32 -- writeword(0x0A0D); // newline is CR,LF on Microsoft OS's --#else -- writeByte('\n'); --#endif -- if (doindent) -- linehead = 1; --} -- --void OutBuffer::writeByte(unsigned b) --{ -- if (doindent && linehead -- && b != '\n') -- { -- if (level) -- { -- reserve(level); -- for (size_t i=0; idata[offset] = '\t'; -- offset++; -- } -- } -- linehead = 0; -- } -- reserve(1); -- this->data[offset] = (unsigned char)b; -- offset++; --} -- --void OutBuffer::writeUTF8(unsigned b) --{ -- reserve(6); -- if (b <= 0x7F) -- { -- this->data[offset] = (unsigned char)b; -- offset++; -- } -- else if (b <= 0x7FF) -- { -- this->data[offset + 0] = (unsigned char)((b >> 6) | 0xC0); -- this->data[offset + 1] = (unsigned char)((b & 0x3F) | 0x80); -- offset += 2; -- } -- else if (b <= 0xFFFF) -- { -- this->data[offset + 0] = (unsigned char)((b >> 12) | 0xE0); -- this->data[offset + 1] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -- this->data[offset + 2] = (unsigned char)((b & 0x3F) | 0x80); -- offset += 3; -- } -- else if (b <= 0x1FFFFF) -- { -- this->data[offset + 0] = (unsigned char)((b >> 18) | 0xF0); -- this->data[offset + 1] = (unsigned char)(((b >> 12) & 0x3F) | 0x80); -- this->data[offset + 2] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -- this->data[offset + 3] = (unsigned char)((b & 0x3F) | 0x80); -- offset += 4; -- } -- else if (b <= 0x3FFFFFF) -- { -- this->data[offset + 0] = (unsigned char)((b >> 24) | 0xF8); -- this->data[offset + 1] = (unsigned char)(((b >> 18) & 0x3F) | 0x80); -- this->data[offset + 2] = (unsigned char)(((b >> 12) & 0x3F) | 0x80); -- this->data[offset + 3] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -- this->data[offset + 4] = (unsigned char)((b & 0x3F) | 0x80); -- offset += 5; -- } -- else if (b <= 0x7FFFFFFF) -- { -- this->data[offset + 0] = (unsigned char)((b >> 30) | 0xFC); -- this->data[offset + 1] = (unsigned char)(((b >> 24) & 0x3F) | 0x80); -- this->data[offset + 2] = (unsigned char)(((b >> 18) & 0x3F) | 0x80); -- this->data[offset + 3] = (unsigned char)(((b >> 12) & 0x3F) | 0x80); -- this->data[offset + 4] = (unsigned char)(((b >> 6) & 0x3F) | 0x80); -- this->data[offset + 5] = (unsigned char)((b & 0x3F) | 0x80); -- offset += 6; -- } -- else -- assert(0); --} -- --void OutBuffer::prependbyte(unsigned b) --{ -- reserve(1); -- memmove(data + 1, data, offset); -- data[0] = (unsigned char)b; -- offset++; --} -- --void OutBuffer::writeword(unsigned w) --{ -- if (doindent && linehead --#if _WIN32 -- && w != 0x0A0D) --#else -- && w != '\n') --#endif -- { -- if (level) -- { -- reserve(level); -- for (size_t i=0; idata[offset] = '\t'; -- offset++; -- } -- } -- linehead = 0; -- } -- reserve(2); -- *(unsigned short *)(this->data + offset) = (unsigned short)w; -- offset += 2; --} -- --void OutBuffer::writeUTF16(unsigned w) --{ -- reserve(4); -- if (w <= 0xFFFF) -- { -- *(unsigned short *)(this->data + offset) = (unsigned short)w; -- offset += 2; -- } -- else if (w <= 0x10FFFF) -- { -- *(unsigned short *)(this->data + offset) = (unsigned short)((w >> 10) + 0xD7C0); -- *(unsigned short *)(this->data + offset + 2) = (unsigned short)((w & 0x3FF) | 0xDC00); -- offset += 4; -- } -- else -- assert(0); --} -- --void OutBuffer::write4(unsigned w) --{ -- if (doindent && linehead --#if _WIN32 -- && w != 0x000A000D) --#else -- ) --#endif -- { -- if (level) -- { -- reserve(level); -- for (size_t i=0; idata[offset] = '\t'; -- offset++; -- } -- } -- linehead = 0; -- } -- reserve(4); -- *(unsigned *)(this->data + offset) = w; -- offset += 4; --} -- --void OutBuffer::write(OutBuffer *buf) --{ -- if (buf) -- { reserve(buf->offset); -- memcpy(data + offset, buf->data, buf->offset); -- offset += buf->offset; -- } --} -- --void OutBuffer::write(Object *obj) --{ -- if (obj) -- { -- writestring(obj->toChars()); -- } --} -- --void OutBuffer::fill0(size_t nbytes) --{ -- reserve(nbytes); -- memset(data + offset,0,nbytes); -- offset += nbytes; --} -- --void OutBuffer::align(size_t size) --{ -- size_t nbytes = ((offset + size - 1) & ~(size - 1)) - offset; -- fill0(nbytes); --} -- -- --//////////////////////////////////////////////////////////////// --// The compiler shipped with Visual Studio 2005 (and possible --// other versions) does not support C99 printf format specfiers --// such as %z and %j --#if 0 && _MSC_VER --using std::string; --using std::wstring; -- --template --inline void --search_and_replace(S& str, const S& what, const S& replacement) --{ -- assert(!what.empty()); -- size_t pos = str.find(what); -- while (pos != S::npos) -- { -- str.replace(pos, what.size(), replacement); -- pos = str.find(what, pos + replacement.size()); -- } --} --#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) \ -- S tmp = f; \ -- search_and_replace(fmt, S("%z"), S("%l")); \ -- search_and_replace(fmt, S("%j"), S("%l")); \ -- f = tmp.c_str(); --#else --#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) --#endif -- --void OutBuffer::vprintf(const char *format, va_list args) --{ -- char buffer[128]; -- char *p; -- unsigned psize; -- int count; -- -- WORKAROUND_C99_SPECIFIERS_BUG(string, fmt, format); -- -- p = buffer; -- psize = sizeof(buffer); -- for (;;) -- { --#if _WIN32 -- count = _vsnprintf(p,psize,format,args); -- if (count != -1) -- break; -- psize *= 2; --#elif POSIX -- va_list va; -- va_copy(va, args); --/* -- The functions vprintf(), vfprintf(), vsprintf(), vsnprintf() -- are equivalent to the functions printf(), fprintf(), sprintf(), -- snprintf(), respectively, except that they are called with a -- va_list instead of a variable number of arguments. These -- functions do not call the va_end macro. Consequently, the value -- of ap is undefined after the call. The application should call -- va_end(ap) itself afterwards. -- */ -- count = vsnprintf(p,psize,format,va); -- va_end(va); -- if (count == -1) -- psize *= 2; -- else if (count >= psize) -- psize = count + 1; -- else -- break; --#else -- assert(0); --#endif -- p = (char *) alloca(psize); // buffer too small, try again with larger size -- } -- write(p,count); --} -- --void OutBuffer::printf(const char *format, ...) --{ -- va_list ap; -- va_start(ap, format); -- vprintf(format,ap); -- va_end(ap); --} -- --void OutBuffer::bracket(char left, char right) --{ -- reserve(2); -- memmove(data + 1, data, offset); -- data[0] = left; -- data[offset + 1] = right; -- offset += 2; --} -- --/****************** -- * Insert left at i, and right at j. -- * Return index just past right. -- */ -- --size_t OutBuffer::bracket(size_t i, const char *left, size_t j, const char *right) --{ -- size_t leftlen = strlen(left); -- size_t rightlen = strlen(right); -- reserve(leftlen + rightlen); -- insert(i, left, leftlen); -- insert(j + leftlen, right, rightlen); -- return j + leftlen + rightlen; --} -- --void OutBuffer::spread(size_t offset, size_t nbytes) --{ -- reserve(nbytes); -- memmove(data + offset + nbytes, data + offset, -- this->offset - offset); -- this->offset += nbytes; --} -- --/**************************************** -- * Returns: offset + nbytes -- */ -- --size_t OutBuffer::insert(size_t offset, const void *p, size_t nbytes) --{ -- spread(offset, nbytes); -- memmove(data + offset, p, nbytes); -- return offset + nbytes; --} -- --void OutBuffer::remove(size_t offset, size_t nbytes) --{ -- memmove(data + offset, data + offset + nbytes, this->offset - (offset + nbytes)); -- this->offset -= nbytes; --} -- --char *OutBuffer::toChars() --{ -- writeByte(0); -- return (char *)data; --} -- --// TODO: Remove (only used by disabled GC) --/********************************* Bits ****************************/ -- --Bits::Bits() --{ -- data = NULL; -- bitdim = 0; -- allocdim = 0; --} -- --Bits::~Bits() --{ -- mem.free(data); --} -- --void Bits::mark() --{ -- mem.mark(data); --} -- --void Bits::resize(unsigned bitdim) --{ -- unsigned allocdim; -- unsigned mask; -- -- allocdim = (bitdim + 31) / 32; -- data = (unsigned *)mem.realloc(data, allocdim * sizeof(data[0])); -- if (this->allocdim < allocdim) -- memset(data + this->allocdim, 0, (allocdim - this->allocdim) * sizeof(data[0])); -- -- // Clear other bits in last word -- mask = (1 << (bitdim & 31)) - 1; -- if (mask) -- data[allocdim - 1] &= ~mask; -- -- this->bitdim = bitdim; -- this->allocdim = allocdim; --} -- --void Bits::set(unsigned bitnum) --{ -- data[bitnum / 32] |= 1 << (bitnum & 31); --} -- --void Bits::clear(unsigned bitnum) --{ -- data[bitnum / 32] &= ~(1 << (bitnum & 31)); --} -- --int Bits::test(unsigned bitnum) --{ -- return data[bitnum / 32] & (1 << (bitnum & 31)); --} -- --void Bits::set() --{ unsigned mask; -- -- memset(data, ~0, allocdim * sizeof(data[0])); -- -- // Clear other bits in last word -- mask = (1 << (bitdim & 31)) - 1; -- if (mask) -- data[allocdim - 1] &= mask; --} -- --void Bits::clear() --{ -- memset(data, 0, allocdim * sizeof(data[0])); --} -- --void Bits::copy(Bits *from) --{ -- assert(bitdim == from->bitdim); -- memcpy(data, from->data, allocdim * sizeof(data[0])); --} -- --Bits *Bits::clone() --{ -- Bits *b; -- -- b = new Bits(); -- b->resize(bitdim); -- b->copy(this); -- return b; --} -- --void Bits::sub(Bits *b) --{ -- unsigned u; -- -- for (u = 0; u < allocdim; u++) -- data[u] &= ~b->data[u]; --} ---- a/src/gcc/d/dfrontend/root.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/root.h 2014-04-01 16:32:51.000000000 +0100 -@@ -10,386 +10,14 @@ - #ifndef ROOT_H - #define ROOT_H - --#include --#include --#ifdef DEBUG --#include --#endif -- --#include "port.h" -- - #if __DMC__ - #pragma once - #endif - --typedef size_t hash_t; -- --/* -- * Root of our class library. -- */ -- --struct OutBuffer; -- --// Can't include arraytypes.h here, need to declare these directly. --template struct ArrayBase; --typedef ArrayBase Files; --typedef ArrayBase Strings; -- -- --struct Object --{ -- Object() { } -- virtual ~Object() { } -- -- virtual int equals(Object *o); -- -- /** -- * Returns a hash code, useful for things like building hash tables of Objects. -- */ -- virtual hash_t hashCode(); -- -- /** -- * Return <0, ==0, or >0 if this is less than, equal to, or greater than obj. -- * Useful for sorting Objects. -- */ -- virtual int compare(Object *obj); -- -- /** -- * Pretty-print an Object. Useful for debugging the old-fashioned way. -- */ -- virtual void print(); -- -- virtual char *toChars(); -- virtual void toBuffer(OutBuffer *buf); -- -- /** -- * Used as a replacement for dynamic_cast. Returns a unique number -- * defined by the library user. For Object, the return value is 0. -- */ -- virtual int dyncast(); -- -- /** -- * Marks pointers for garbage collector by calling mem.mark() for all pointers into heap. -- */ -- /*virtual*/ // not used, disable for now -- void mark(); --}; -- --struct String : Object --{ -- const char *str; // the string itself -- -- String(const char *str); -- ~String(); -- -- static hash_t calcHash(const char *str, size_t len); -- static hash_t calcHash(const char *str); -- hash_t hashCode(); -- size_t len(); -- int equals(Object *obj); -- int compare(Object *obj); -- char *toChars(); -- void print(); -- void mark(); --}; -- --struct FileName : String --{ -- FileName(const char *str); -- hash_t hashCode(); -- int equals(Object *obj); -- static int equals(const char *name1, const char *name2); -- int compare(Object *obj); -- static int compare(const char *name1, const char *name2); -- static int absolute(const char *name); -- static const char *ext(const char *); -- const char *ext(); -- static const char *removeExt(const char *str); -- static const char *name(const char *); -- const char *name(); -- static const char *path(const char *); -- static const char *replaceName(const char *path, const char *name); -- -- static const char *combine(const char *path, const char *name); -- static Strings *splitPath(const char *path); -- static const char *defaultExt(const char *name, const char *ext); -- static const char *forceExt(const char *name, const char *ext); -- static int equalsExt(const char *name, const char *ext); -- -- int equalsExt(const char *ext); -- -- void CopyTo(FileName *to); -- static const char *searchPath(Strings *path, const char *name, int cwd); -- static const char *safeSearchPath(Strings *path, const char *name); -- static int exists(const char *name); -- static void ensurePathExists(const char *path); -- static void ensurePathToNameExists(const char *name); -- static const char *canonicalName(const char *name); -- -- static void free(const char *str); --}; -- --struct File : Object --{ -- int ref; // != 0 if this is a reference to someone else's buffer -- unsigned char *buffer; // data for our file -- size_t len; // amount of data in buffer[] -- void *touchtime; // system time to use for file -- -- FileName *name; // name of our file -- -- File(const char *); -- File(const FileName *); -- ~File(); -- -- void mark(); -- -- char *toChars(); -- -- /* Read file, return !=0 if error -- */ -- -- int read(); -- -- /* Write file, either succeed or fail -- * with error message & exit. -- */ -- -- void readv(); -- -- /* Read file, return !=0 if error -- */ -- -- int mmread(); -- -- /* Write file, either succeed or fail -- * with error message & exit. -- */ -- -- void mmreadv(); -- -- /* Write file, return !=0 if error -- */ -- -- int write(); -- -- /* Write file, either succeed or fail -- * with error message & exit. -- */ -- -- void writev(); -- -- /* Return !=0 if file exists. -- * 0: file doesn't exist -- * 1: normal file -- * 2: directory -- */ -- -- /* Append to file, return !=0 if error -- */ -- -- int append(); -- -- /* Append to file, either succeed or fail -- * with error message & exit. -- */ -- -- void appendv(); -- -- /* Return !=0 if file exists. -- * 0: file doesn't exist -- * 1: normal file -- * 2: directory -- */ -- -- int exists(); -- -- /* Given wildcard filespec, return an array of -- * matching File's. -- */ -- -- static Files *match(char *); -- static Files *match(FileName *); -- -- // Compare file times. -- // Return <0 this < f -- // =0 this == f -- // >0 this > f -- int compareTime(File *f); -- -- // Read system file statistics -- void stat(); -- -- /* Set buffer -- */ -- -- void setbuffer(void *buffer, size_t len) -- { -- this->buffer = (unsigned char *)buffer; -- this->len = len; -- } -- -- void checkoffset(size_t offset, size_t nbytes); -- -- void remove(); // delete file --}; -- --struct OutBuffer : Object --{ -- unsigned char *data; -- size_t offset; -- size_t size; -- -- int doindent, level, linehead; -- -- OutBuffer(); -- ~OutBuffer(); -- char *extractData(); -- void mark(); -- -- void reserve(size_t nbytes); -- void setsize(size_t size); -- void reset(); -- void write(const void *data, size_t nbytes); -- void writebstring(unsigned char *string); -- void writestring(const char *string); -- void prependstring(const char *string); -- void writenl(); // write newline -- void writeByte(unsigned b); -- void writebyte(unsigned b) { writeByte(b); } -- void writeUTF8(unsigned b); -- void prependbyte(unsigned b); -- void writeword(unsigned w); -- void writeUTF16(unsigned w); -- void write4(unsigned w); -- void write(OutBuffer *buf); -- void write(Object *obj); -- void fill0(size_t nbytes); -- void align(size_t size); -- void vprintf(const char *format, va_list args); -- void printf(const char *format, ...); -- void bracket(char left, char right); -- size_t bracket(size_t i, const char *left, size_t j, const char *right); -- void spread(size_t offset, size_t nbytes); -- size_t insert(size_t offset, const void *data, size_t nbytes); -- void remove(size_t offset, size_t nbytes); -- char *toChars(); -- char *extractString(); --}; -- --struct Array --{ -- size_t dim; -- void **data; -- -- private: -- size_t allocdim; -- #define SMALLARRAYCAP 1 -- void *smallarray[SMALLARRAYCAP]; // inline storage for small arrays -- -- public: -- Array(); -- ~Array(); -- //Array(const Array&); -- void mark(); -- char *toChars(); -- -- void reserve(size_t nentries); -- void setDim(size_t newdim); -- void fixDim(); -- void push(void *ptr); -- void *pop(); -- void shift(void *ptr); -- void insert(size_t index, void *ptr); -- void insert(size_t index, Array *a); -- void append(Array *a); -- void remove(size_t i); -- void zero(); -- void *tos(); -- void sort(); -- Array *copy(); --}; -- --template --struct ArrayBase : Array --{ -- TYPE **tdata() -- { -- return (TYPE **)data; -- } -- -- TYPE*& operator[] (size_t index) -- { --#ifdef DEBUG -- assert(index < dim); --#endif -- return ((TYPE **)data)[index]; -- } -- -- void insert(size_t index, TYPE *v) -- { -- Array::insert(index, (void *)v); -- } -- -- void insert(size_t index, ArrayBase *a) -- { -- Array::insert(index, (Array *)a); -- } -- -- void append(ArrayBase *a) -- { -- Array::append((Array *)a); -- } -- -- void push(TYPE *a) -- { -- Array::push((void *)a); -- } -- -- ArrayBase *copy() -- { -- return (ArrayBase *)Array::copy(); -- } -- -- typedef int (*ArrayBase_apply_ft_t)(TYPE *, void *); -- int apply(ArrayBase_apply_ft_t fp, void *param) -- { -- for (size_t i = 0; i < dim; i++) -- { TYPE *e = (*this)[i]; -- -- if (e) -- { -- if (e->apply(fp, param)) -- return 1; -- } -- } -- return 0; -- } --}; -- --// TODO: Remove (only used by disabled GC) --struct Bits : Object --{ -- unsigned bitdim; -- unsigned allocdim; -- unsigned *data; -- -- Bits(); -- ~Bits(); -- void mark(); -- -- void resize(unsigned bitdim); -- -- void set(unsigned bitnum); -- void clear(unsigned bitnum); -- int test(unsigned bitnum); -- -- void set(); -- void clear(); -- void copy(Bits *from); -- Bits *clone(); -- -- void sub(Bits *b); --}; -+#include "object.h" -+#include "filename.h" -+#include "file.h" -+#include "outbuffer.h" -+#include "array.h" - - #endif ---- a/src/gcc/d/dfrontend/sapply.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/dfrontend/sapply.c 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,210 @@ -+ -+// Compiler implementation of the D programming language -+// Copyright (c) 1999-2013 by Digital Mars -+// All Rights Reserved -+// written by Walter Bright -+// http://www.digitalmars.com -+// License for redistribution is by either the Artistic License -+// in artistic.txt, or the GNU General Public License in gnu.txt. -+// See the included readme.txt for details. -+ -+#include -+#include -+ -+#include "mars.h" -+#include "statement.h" -+ -+ -+/************************************** -+ * A Statement tree walker that will visit each Statement s in the tree, -+ * in depth-first evaluation order, and call fp(s,param) on it. -+ * fp() signals whether the walking continues with its return value: -+ * Returns: -+ * 0 continue -+ * 1 done -+ * It's a bit slower than using virtual functions, but more encapsulated and less brittle. -+ * Creating an iterator for this would be much more complex. -+ */ -+ -+typedef bool (*sapply_fp_t)(Statement *, void *); -+ -+bool Statement::apply(sapply_fp_t fp, void *param) -+{ -+ return (*fp)(this, param); -+} -+ -+/****************************** -+ * Perform apply() on an t if not null -+ */ -+#define scondApply(t, fp, param) (t ? t->apply(fp, param) : 0) -+ -+ -+ -+bool PeelStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return s->apply(fp, param) || -+ (*fp)(this, param); -+} -+ -+bool CompoundStatement::apply(sapply_fp_t fp, void *param) -+{ -+ for (size_t i = 0; i < statements->dim; i++) -+ { Statement *s = (*statements)[i]; -+ -+ bool r = scondApply(s, fp, param); -+ if (r) -+ return r; -+ } -+ return (*fp)(this, param); -+} -+ -+bool UnrolledLoopStatement::apply(sapply_fp_t fp, void *param) -+{ -+ for (size_t i = 0; i < statements->dim; i++) -+ { Statement *s = (*statements)[i]; -+ -+ bool r = scondApply(s, fp, param); -+ if (r) -+ return r; -+ } -+ return (*fp)(this, param); -+} -+ -+bool ScopeStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(statement, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool WhileStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool DoStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool ForStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(init, fp, param) || -+ scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool ForeachStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+#if DMDV2 -+bool ForeachRangeStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+#endif -+ -+bool IfStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(ifbody, fp, param) || -+ scondApply(elsebody, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool ConditionalStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(ifbody, fp, param) || -+ scondApply(elsebody, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool PragmaStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool SwitchStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool CaseStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(statement, fp, param) || -+ (*fp)(this, param); -+} -+ -+#if DMDV2 -+bool CaseRangeStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(statement, fp, param) || -+ (*fp)(this, param); -+} -+#endif -+ -+bool DefaultStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(statement, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool SynchronizedStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool WithStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool TryCatchStatement::apply(sapply_fp_t fp, void *param) -+{ -+ bool r = scondApply(body, fp, param); -+ if (r) -+ return r; -+ -+ for (size_t i = 0; i < catches->dim; i++) -+ { Catch *c = (*catches)[i]; -+ -+ bool r = scondApply(c->handler, fp, param); -+ if (r) -+ return r; -+ } -+ return (*fp)(this, param); -+} -+ -+bool TryFinallyStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(body, fp, param) || -+ scondApply(finalbody, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool OnScopeStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(statement, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool DebugStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(statement, fp, param) || -+ (*fp)(this, param); -+} -+ -+bool LabelStatement::apply(sapply_fp_t fp, void *param) -+{ -+ return scondApply(statement, fp, param) || -+ (*fp)(this, param); -+} -+ ---- a/src/gcc/d/dfrontend/scope.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/scope.c 2014-04-01 16:32:51.000000000 +0100 -@@ -12,6 +12,7 @@ - #include // strlen() - - #include "root.h" -+#include "rmem.h" - #include "speller.h" - - #include "mars.h" -@@ -21,6 +22,7 @@ - #include "attrib.h" - #include "dsymbol.h" - #include "declaration.h" -+#include "statement.h" - #include "aggregate.h" - #include "module.h" - #include "id.h" -@@ -50,6 +52,7 @@ Scope::Scope() - - //printf("Scope::Scope() %p\n", this); - this->module = NULL; -+ this->instantiatingModule = NULL; - this->scopesym = NULL; - this->sd = NULL; - this->enclosing = NULL; -@@ -60,7 +63,8 @@ Scope::Scope() - this->sbreak = NULL; - this->scontinue = NULL; - this->fes = NULL; -- this->structalign = global.structalign; -+ this->callsc = NULL; -+ this->structalign = STRUCTALIGN_DEFAULT; - this->func = NULL; - this->slabel = NULL; - this->linkage = LINKd; -@@ -72,12 +76,11 @@ Scope::Scope() - this->inunion = 0; - this->nofree = 0; - this->noctor = 0; -- this->noaccesscheck = 0; -- this->mustsemantic = 0; - this->intypeof = 0; - this->speculative = 0; -- this->parameterSpecialization = 0; - this->callSuper = 0; -+ this->fieldinit = NULL; -+ this->fieldinit_dim = 0; - this->flags = 0; - this->lastdc = NULL; - this->lastoffset = 0; -@@ -90,6 +93,7 @@ Scope::Scope(Scope *enclosing) - //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this); - assert(!(enclosing->flags & SCOPEfree)); - this->module = enclosing->module; -+ this->instantiatingModule = enclosing->instantiatingModule; - this->func = enclosing->func; - this->parent = enclosing->parent; - this->scopesym = NULL; -@@ -100,6 +104,7 @@ Scope::Scope(Scope *enclosing) - this->sbreak = enclosing->sbreak; - this->scontinue = enclosing->scontinue; - this->fes = enclosing->fes; -+ this->callsc = enclosing->callsc; - this->structalign = enclosing->structalign; - this->enclosing = enclosing; - #ifdef DEBUG -@@ -121,13 +126,12 @@ Scope::Scope(Scope *enclosing) - this->inunion = enclosing->inunion; - this->nofree = 0; - this->noctor = enclosing->noctor; -- this->noaccesscheck = enclosing->noaccesscheck; -- this->mustsemantic = enclosing->mustsemantic; - this->intypeof = enclosing->intypeof; - this->speculative = enclosing->speculative; -- this->parameterSpecialization = enclosing->parameterSpecialization; - this->callSuper = enclosing->callSuper; -- this->flags = (enclosing->flags & (SCOPEcontract | SCOPEdebug)); -+ this->fieldinit = enclosing->saveFieldInit(); -+ this->fieldinit_dim = enclosing->fieldinit_dim; -+ this->flags = (enclosing->flags & (SCOPEcontract | SCOPEdebug | SCOPEctfe)); - this->lastdc = NULL; - this->lastoffset = 0; - this->docbuf = enclosing->docbuf; -@@ -179,7 +183,17 @@ Scope *Scope::pop() - Scope *enc = enclosing; - - if (enclosing) -+ { - enclosing->callSuper |= callSuper; -+ if (enclosing->fieldinit && fieldinit) -+ { -+ size_t dim = fieldinit_dim; -+ for (size_t i = 0; i < dim; i++) -+ enclosing->fieldinit[i] |= fieldinit[i]; -+ delete[] fieldinit; -+ fieldinit = NULL; -+ } -+ } - - if (!nofree) - { enclosing = freelist; -@@ -190,6 +204,19 @@ Scope *Scope::pop() - return enc; - } - -+Scope *Scope::startCTFE() -+{ -+ Scope *sc = this->push(); -+ sc->flags = this->flags | SCOPEctfe; -+ return sc; -+} -+ -+Scope *Scope::endCTFE() -+{ -+ assert(flags & SCOPEctfe); -+ return pop(); -+} -+ - void Scope::mergeCallSuper(Loc loc, unsigned cs) - { - // This does a primitive flow analysis to support the restrictions -@@ -243,6 +270,131 @@ void Scope::mergeCallSuper(Loc loc, unsi - } - } - -+unsigned *Scope::saveFieldInit() -+{ -+ unsigned *fi = NULL; -+ if (fieldinit) // copy -+ { -+ size_t dim = fieldinit_dim; -+ fi = new unsigned[dim]; -+ fi[0] = dim; -+ for (size_t i = 0; i < dim; i++) -+ fi[i] = fieldinit[i]; -+ } -+ return fi; -+} -+ -+bool mergeFieldInit(Loc loc, unsigned &fieldInit, unsigned fi, bool mustInit) -+{ -+ if (fi != fieldInit) -+ { -+ -+ // Have any branches returned? -+ bool aRet = (fi & CSXreturn) != 0; -+ bool bRet = (fieldInit & CSXreturn) != 0; -+ -+ bool ok; -+ -+ if (aRet) -+ { -+ ok = !mustInit || (fi & CSXthis_ctor); -+ fieldInit = fieldInit; -+ } -+ else if (bRet) -+ { -+ ok = !mustInit || (fieldInit & CSXthis_ctor); -+ fieldInit = fi; -+ } -+ else -+ { -+ ok = !mustInit || !((fieldInit ^ fi) & CSXthis_ctor); -+ fieldInit |= fi; -+ } -+ -+ return ok; -+ } -+#if 0 -+ // This does a primitive flow analysis to support the restrictions -+ // regarding when and how constructors can appear. -+ // It merges the results of two paths. -+ // The two paths are fieldInit and fi; the result is merged into fieldInit. -+ -+ if (fi != fieldInit) -+ { // Have ALL branches called a constructor? -+ int aAll = (fi & CSXthis_ctor) != 0; -+ int bAll = (fieldInit & CSXthis_ctor) != 0; -+ -+ // Have ANY branches called a constructor? -+ bool aAny = (fi & CSXany_ctor) != 0; -+ bool bAny = (fieldInit & CSXany_ctor) != 0; -+ -+ // Have any branches returned? -+ bool aRet = (fi & CSXreturn) != 0; -+ bool bRet = (fieldInit & CSXreturn) != 0; -+ -+ bool ok = true; -+ -+printf("L%d fieldInit = x%x, fi = x%x\n", __LINE__, fieldInit, fi); -+ -+ // If one has returned without a constructor call, there must be never -+ // have been ctor calls in the other. -+ if ( (aRet && !aAny && bAny) || -+ (bRet && !bAny && aAny)) -+ { ok = false; -+printf("L%d\n", __LINE__); -+ } -+ // If one branch has called a ctor and then exited, anything the -+ // other branch has done is OK (except returning without a -+ // ctor call, but we already checked that). -+ else if (aRet && aAll) -+ { -+ //fieldInit |= fi & (CSXany_ctor | CSXlabel); -+printf("L%d -> fieldInit = x%x\n", __LINE__, fieldInit); -+ } -+ else if (bRet && bAll) -+ { -+ fieldInit = fi;// | (fieldInit & (CSXany_ctor | CSXlabel)); -+printf("L%d -> fieldInit = x%x\n", __LINE__, fieldInit); -+ } -+ else -+ { // Both branches must have called ctors, or both not. -+ ok = (aAll == bAll); -+ // If one returned without a ctor, we must remember that -+ // (Don't bother if we've already found an error) -+ if (ok && aRet && !aAny) -+ fieldInit |= CSXreturn; -+ fieldInit |= fi & (CSXany_ctor | CSXlabel); -+printf("L%d ok = %d, fieldInit = x%x, fi = x%x\n", __LINE__, ok, fieldInit, fi); -+ } -+ return ok; -+ } -+#endif -+ return true; -+} -+ -+void Scope::mergeFieldInit(Loc loc, unsigned *fies) -+{ -+ if (fieldinit && fies) -+ { -+ FuncDeclaration *f = func; -+ if (fes) f = fes->func; -+ AggregateDeclaration *ad = f->isAggregateMember2(); -+ assert(ad); -+ -+ for (size_t i = 0; i < ad->fields.dim; i++) -+ { -+ VarDeclaration *v = ad->fields[i]; -+ bool mustInit = (v->storage_class & STCnodefaultctor || -+ v->type->needsNested()); -+ -+ if (!::mergeFieldInit(loc, fieldinit[i], fies[i], mustInit)) -+ { -+ ::error(loc, "one path skips field %s", ad->fields[i]->toChars()); -+ } -+ } -+ } -+} -+ - Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym) - { Dsymbol *s; - Scope *sc; -@@ -278,8 +430,7 @@ Dsymbol *Scope::search(Loc loc, Identifi - s = sc->scopesym->search(loc, ident, 0); - if (s) - { -- if (global.params.Dversion > 1 && -- ident == Id::length && -+ if (ident == Id::length && - sc->scopesym->isArrayScopeSymbol() && - sc->enclosing && - sc->enclosing->search(loc, ident, NULL)) -@@ -410,9 +561,8 @@ void *scope_search_fp(void *arg, const c - assert(id); - - Scope *sc = (Scope *)arg; -- Module::clearCache(); -- Dsymbol *s = sc->search(0, id, NULL); -- return s; -+ Dsymbol *s = sc->search(Loc(), id, NULL); -+ return (void*)s; - } - - Dsymbol *Scope::search_correct(Identifier *ident) ---- a/src/gcc/d/dfrontend/scope.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/scope.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -14,20 +14,20 @@ - #pragma once - #endif - --struct Dsymbol; --struct ScopeDsymbol; --struct Identifier; --struct Module; --struct Statement; --struct SwitchStatement; --struct TryFinallyStatement; --struct LabelStatement; --struct ForeachStatement; --struct ClassDeclaration; --struct AggregateDeclaration; --struct FuncDeclaration; -+class Dsymbol; -+class ScopeDsymbol; -+class Identifier; -+class Module; -+class Statement; -+class SwitchStatement; -+class TryFinallyStatement; -+class LabelStatement; -+class ForeachStatement; -+class ClassDeclaration; -+class AggregateDeclaration; -+class FuncDeclaration; - struct DocComment; --struct TemplateInstance; -+class TemplateInstance; - - #if __GNUC__ - // Requires a full definition for PROT and LINK -@@ -38,11 +38,34 @@ enum LINK; - enum PROT; - #endif - -+#define CSXthis_ctor 1 // called this() -+#define CSXsuper_ctor 2 // called super() -+#define CSXthis 4 // referenced this -+#define CSXsuper 8 // referenced super -+#define CSXlabel 0x10 // seen a label -+#define CSXreturn 0x20 // seen a return statement -+#define CSXany_ctor 0x40 // either this() or super() was called -+ -+#define SCOPEctor 0x0001 // constructor type -+#define SCOPEstaticif 0x0002 // inside static if -+#define SCOPEfree 0x0004 // is on free list -+#define SCOPEstaticassert 0x0008 // inside static assert -+#define SCOPEdebug 0x0010 // inside debug conditional -+ -+#define SCOPEinvariant 0x0020 // inside invariant code -+#define SCOPErequire 0x0040 // inside in contract code -+#define SCOPEensure 0x0060 // inside out contract code -+#define SCOPEcontract 0x0060 // [mask] we're inside contract code -+ -+#define SCOPEctfe 0x0080 // inside a ctfe-only expression -+#define SCOPEnoaccesscheck 0x0100 // don't do access checks -+ - struct Scope - { - Scope *enclosing; // enclosing Scope - - Module *module; // Root module -+ Module *instantiatingModule; // top level module that started a chain of template instantiations - ScopeDsymbol *scopesym; // current symbol - ScopeDsymbol *sd; // if in static if, and declaring new symbols, - // sd gets the addMember() -@@ -55,6 +78,7 @@ struct Scope - Statement *sbreak; // enclosing statement that supports "break" - Statement *scontinue; // enclosing statement that supports "continue" - ForeachStatement *fes; // if nested function for ForeachStatement, this is it -+ Scope *callsc; // used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__ - unsigned offset; // next offset to use in aggregate - // This really shouldn't be a part of Scope, because it requires - // semantic() to be done in the lexical field order. It should be -@@ -65,39 +89,21 @@ struct Scope - int noctor; // set if constructor calls aren't allowed - int intypeof; // in typeof(exp) - bool speculative; // in __traits(compiles) or typeof(exp) -- int parameterSpecialization; // if in template parameter specialization -- int noaccesscheck; // don't do access checks -- int mustsemantic; // cannot defer semantic() - - unsigned callSuper; // primitive flow analysis for constructors --#define CSXthis_ctor 1 // called this() --#define CSXsuper_ctor 2 // called super() --#define CSXthis 4 // referenced this --#define CSXsuper 8 // referenced super --#define CSXlabel 0x10 // seen a label --#define CSXreturn 0x20 // seen a return statement --#define CSXany_ctor 0x40 // either this() or super() was called -+ unsigned *fieldinit; -+ unsigned fieldinit_dim; - - structalign_t structalign; // alignment for struct members -- enum LINK linkage; // linkage for external functions -+ LINK linkage; // linkage for external functions - -- enum PROT protection; // protection for class members -+ PROT protection; // protection for class members - int explicitProtection; // set if in an explicit protection attribute - - StorageClass stc; // storage class - char *depmsg; // customized deprecation message - - unsigned flags; --#define SCOPEctor 1 // constructor type --#define SCOPEstaticif 2 // inside static if --#define SCOPEfree 4 // is on free list --#define SCOPEstaticassert 8 // inside static assert --#define SCOPEdebug 0x10 // inside debug conditional -- --#define SCOPEinvariant 0x20 // inside invariant code --#define SCOPErequire 0x40 // inside in contract code --#define SCOPEensure 0x60 // inside out contract code --#define SCOPEcontract 0x60 // [mask] we're inside contract code - - Expressions *userAttributes; // user defined attributes - -@@ -110,15 +116,20 @@ struct Scope - static Scope *createGlobal(Module *module); - - Scope(); -- Scope(Module *module); - Scope(Scope *enclosing); - - Scope *push(); - Scope *push(ScopeDsymbol *ss); - Scope *pop(); - -+ Scope *startCTFE(); -+ Scope *endCTFE(); -+ - void mergeCallSuper(Loc loc, unsigned cs); - -+ unsigned *saveFieldInit(); -+ void mergeFieldInit(Loc loc, unsigned *cses); -+ - Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym); - Dsymbol *search_correct(Identifier *ident); - Dsymbol *insert(Dsymbol *s); ---- a/src/gcc/d/dfrontend/statement.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/statement.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2011 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -52,6 +52,15 @@ Identifier *fixupLabelName(Scope *sc, Id - return ident; - } - -+LabelStatement *checkLabeledLoop(Scope *sc, Statement *statement) -+{ -+ if (sc->slabel && sc->slabel->statement == statement) -+ { -+ return sc->slabel; -+ } -+ return NULL; -+} -+ - /******************************** Statement ***************************/ - - Statement::Statement(Loc loc) -@@ -69,17 +78,18 @@ Statement *Statement::syntaxCopy() - - void Statement::print() - { -- fprintf(stdmsg, "%s\n", toChars()); -- fflush(stdmsg); -+ fprintf(stderr, "%s\n", toChars()); -+ fflush(stderr); - } - - char *Statement::toChars() --{ OutBuffer *buf; -+{ - HdrGenState hgs; - -- buf = new OutBuffer(); -- toCBuffer(buf, &hgs); -- return buf->toChars(); -+ OutBuffer buf; -+ toCBuffer(&buf, &hgs); -+ buf.writebyte(0); -+ return buf.extractData(); - } - - void Statement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -154,13 +164,78 @@ bool Statement::hasContinue() - return FALSE; - } - -+/* ============================================== */ - // TRUE if statement uses exception handling - - bool Statement::usesEH() - { -- return FALSE; -+ struct UsesEH -+ { -+ static bool lambdaUsesEH(Statement *s, void *param) -+ { -+ return s->usesEHimpl(); -+ } -+ }; -+ -+ UsesEH ueh; -+ return apply(&UsesEH::lambdaUsesEH, &ueh); -+} -+ -+bool Statement::usesEHimpl() { return false; } -+bool TryCatchStatement::usesEHimpl() { return true; } -+bool TryFinallyStatement::usesEHimpl() { return true; } -+bool OnScopeStatement::usesEHimpl() { return true; } -+bool SynchronizedStatement::usesEHimpl() { return true; } -+ -+/* ============================================== */ -+// TRUE if statement 'comes from' somewhere else, like a goto -+ -+bool Statement::comeFrom() -+{ -+ struct ComeFrom -+ { -+ static bool lambdaComeFrom(Statement *s, void *param) -+ { -+ return s->comeFromImpl(); -+ } -+ }; -+ -+ ComeFrom cf; -+ return apply(&ComeFrom::lambdaComeFrom, &cf); -+} -+ -+bool Statement::comeFromImpl() { return false; } -+bool CaseStatement::comeFromImpl() { return true; } -+bool DefaultStatement::comeFromImpl() { return true; } -+bool LabelStatement::comeFromImpl() { return true; } -+bool AsmStatement::comeFromImpl() { return true; } -+ -+/* ============================================== */ -+// Return true if statement has executable code. -+ -+bool Statement::hasCode() -+{ -+ struct HasCode -+ { -+ static bool lambdaHasCode(Statement *s, void *param) -+ { -+ return s->hasCodeImpl(); -+ } -+ }; -+ -+ HasCode hc; -+ return apply(&HasCode::lambdaHasCode, &hc); - } - -+bool Statement::hasCodeImpl() { return true; } -+bool ExpStatement::hasCodeImpl() { return exp != NULL; } -+bool CompoundStatement::hasCodeImpl() { return false; } -+bool ScopeStatement::hasCodeImpl() { return false; } -+bool ImportStatement::hasCodeImpl() { return false; } -+ -+ -+/* ============================================== */ -+ - /* Only valid after semantic analysis - * If 'mustNotThrow' is true, generate an error if it throws - */ -@@ -172,21 +247,6 @@ int Statement::blockExit(bool mustNotThr - return BEany; - } - --// TRUE if statement 'comes from' somewhere else, like a goto -- --int Statement::comeFrom() --{ -- //printf("Statement::comeFrom()\n"); -- return FALSE; --} -- --// Return TRUE if statement has no code in it --int Statement::isEmpty() --{ -- //printf("Statement::isEmpty()\n"); -- return FALSE; --} -- - Statement *Statement::last() - { - return this; -@@ -224,6 +284,28 @@ Statements *Statement::flatten(Scope *sc - } - - -+/******************************** ErrorStatement ***************************/ -+ -+ErrorStatement::ErrorStatement() -+ : Statement(Loc()) -+{ -+} -+ -+Statement *ErrorStatement::syntaxCopy() -+{ -+ return this; -+} -+ -+Statement *ErrorStatement::semantic(Scope *sc) -+{ -+ return this; -+} -+ -+int ErrorStatement::blockExit(bool mustNotThrow) -+{ -+ return BEany; -+} -+ - /******************************** PeelStatement ***************************/ - - PeelStatement::PeelStatement(Statement *s) -@@ -305,6 +387,8 @@ Statement *ExpStatement::semantic(Scope - exp = resolveProperties(sc, exp); - exp->discardValue(); - exp = exp->optimize(0); -+ if (exp->op == TOKerror) -+ return new ErrorStatement(); - } - return this; - } -@@ -328,11 +412,6 @@ int ExpStatement::blockExit(bool mustNot - return result; - } - --int ExpStatement::isEmpty() --{ -- return exp == NULL; --} -- - Statement *ExpStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) - { - //printf("ExpStatement::scopeCode()\n"); -@@ -425,28 +504,38 @@ void CompileStatement::toCBuffer(OutBuff - Statements *CompileStatement::flatten(Scope *sc) - { - //printf("CompileStatement::flatten() %s\n", exp->toChars()); -+ sc = sc->startCTFE(); - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); -+ sc = sc->endCTFE(); - exp = exp->ctfeInterpret(); -- if (exp->op == TOKerror) -- return NULL; -- StringExp *se = exp->toString(); -- if (!se) -- { error("argument to mixin must be a string, not (%s)", exp->toChars()); -- return NULL; -- } -- se = se->toUTF8(sc); -- Parser p(sc->module, (unsigned char *)se->string, se->len, 0); -- p.loc = loc; -- p.nextToken(); - - Statements *a = new Statements(); -- while (p.token.value != TOKeof) -+ if (exp->op != TOKerror) - { -- Statement *s = p.parseStatement(PSsemi | PScurlyscope); -- if (s) // if no parsing errors -- a->push(s); -+ StringExp *se = exp->toString(); -+ if (!se) -+ error("argument to mixin must be a string, not (%s)", exp->toChars()); -+ else -+ { -+ se = se->toUTF8(sc); -+ Parser p(sc->module, (utf8_t *)se->string, se->len, 0); -+ p.scanloc = loc; -+ p.nextToken(); -+ -+ while (p.token.value != TOKeof) -+ { -+ unsigned errors = global.errors; -+ Statement *s = p.parseStatement(PSsemi | PScurlyscope); -+ if (!s || global.errors != errors) -+ goto Lerror; -+ a->push(s); -+ } -+ return a; -+ } - } -+Lerror: -+ a->push(new ErrorStatement()); - return a; - } - -@@ -569,26 +658,26 @@ Statement *CompoundStatement::semantic(S - { - a->push((*statements)[j]); - } -- Statement *body = new CompoundStatement(0, a); -- body = new ScopeStatement(0, body); -+ Statement *body = new CompoundStatement(Loc(), a); -+ body = new ScopeStatement(Loc(), body); - - Identifier *id = Lexer::uniqueId("__o"); - - Statement *handler = sexception; - if (sexception->blockExit(FALSE) & BEfallthru) -- { handler = new ThrowStatement(0, new IdentifierExp(0, id)); -+ { handler = new ThrowStatement(Loc(), new IdentifierExp(Loc(), id)); - ((ThrowStatement *)handler)->internalThrow = true; -- handler = new CompoundStatement(0, sexception, handler); -+ handler = new CompoundStatement(Loc(), sexception, handler); - } - - Catches *catches = new Catches(); -- Catch *ctch = new Catch(0, NULL, id, handler); -+ Catch *ctch = new Catch(Loc(), NULL, id, handler); - ctch->internalCatch = true; - catches->push(ctch); -- s = new TryCatchStatement(0, body, catches); -+ s = new TryCatchStatement(Loc(), body, catches); - - if (sfinally) -- s = new TryFinallyStatement(0, s, sfinally); -+ s = new TryFinallyStatement(Loc(), s, sfinally); - s = s->semantic(sc); - statements->setDim(i + 1); - statements->push(s); -@@ -613,8 +702,8 @@ Statement *CompoundStatement::semantic(S - { - a->push((*statements)[j]); - } -- Statement *body = new CompoundStatement(0, a); -- s = new TryFinallyStatement(0, body, sfinally); -+ Statement *body = new CompoundStatement(Loc(), a); -+ s = new TryFinallyStatement(Loc(), body, sfinally); - s = s->semantic(sc); - statements->setDim(i + 1); - statements->push(s); -@@ -622,9 +711,27 @@ Statement *CompoundStatement::semantic(S - } - } - } -+#ifdef IN_GCC -+ else -+ { -+ // Remove NULL statement from list. -+ statements->remove(i); -+ continue; -+ } -+#endif - } - i++; - } -+ for (size_t i = 0; i < statements->dim; ++i) -+ { -+ s = (*statements)[i]; -+ if (s) -+ { -+ Statement *se = s->isErrorStatement(); -+ if (se) -+ return se; -+ } -+ } - if (statements->dim == 1) - { - return (*statements)[0]; -@@ -678,16 +785,6 @@ void CompoundStatement::toCBuffer(OutBuf - } - } - --bool CompoundStatement::usesEH() --{ -- for (size_t i = 0; i < statements->dim; i++) -- { Statement *s = (*statements)[i]; -- if (s && s->usesEH()) -- return TRUE; -- } -- return FALSE; --} -- - int CompoundStatement::blockExit(bool mustNotThrow) - { - //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim); -@@ -698,7 +795,7 @@ int CompoundStatement::blockExit(bool mu - if (s) - { - //printf("result = x%x\n", result); -- //printf("%s\n", s->toChars()); -+ //printf("s: %s\n", s->toChars()); - if (global.params.warnings && result & BEfallthru && slast) - { - slast = slast->last(); -@@ -708,9 +805,9 @@ int CompoundStatement::blockExit(bool mu - // Allow if last case/default was empty - CaseStatement *sc = slast->isCaseStatement(); - DefaultStatement *sd = slast->isDefaultStatement(); -- if (sc && sc->statement->isEmpty()) -+ if (sc && (!sc->statement->hasCode() || sc->statement->isCaseStatement())) - ; -- else if (sd && sd->statement->isEmpty()) -+ else if (sd && (!sd->statement->hasCode() || sd->statement->isCaseStatement())) - ; - else - s->error("switch case fallthrough - use 'goto %s;' if intended", -@@ -720,7 +817,7 @@ int CompoundStatement::blockExit(bool mu - - if (!(result & BEfallthru) && !s->comeFrom()) - { -- if (s->blockExit(mustNotThrow) != BEhalt && !s->isEmpty()) -+ if (s->blockExit(mustNotThrow) != BEhalt && s->hasCode()) - s->warning("statement is not reachable"); - } - else -@@ -734,31 +831,6 @@ int CompoundStatement::blockExit(bool mu - return result; - } - --int CompoundStatement::comeFrom() --{ int comefrom = FALSE; -- -- //printf("CompoundStatement::comeFrom()\n"); -- for (size_t i = 0; i < statements->dim; i++) -- { Statement *s = (*statements)[i]; -- -- if (!s) -- continue; -- -- comefrom |= s->comeFrom(); -- } -- return comefrom; --} -- --int CompoundStatement::isEmpty() --{ -- for (size_t i = 0; i < statements->dim; i++) -- { Statement *s = (*statements)[i]; -- if (s && !s->isEmpty()) -- return FALSE; -- } -- return TRUE; --} -- - - /******************************** CompoundDeclarationStatement ***************************/ - -@@ -804,7 +876,7 @@ void CompoundDeclarationStatement::toCBu - */ - if (anywritten) - { -- buf->writeByte(','); -+ buf->writestring(", "); - buf->writestring(v->ident->toChars()); - } - else -@@ -864,11 +936,10 @@ Statement *UnrolledLoopStatement::semant - { - //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc); - -- sc->noctor++; - Scope *scd = sc->push(); - scd->sbreak = this; - scd->scontinue = this; -- -+ Statement *serror = NULL; - for (size_t i = 0; i < statements->dim; i++) - { - Statement *s = (*statements)[i]; -@@ -877,12 +948,14 @@ Statement *UnrolledLoopStatement::semant - //printf("[%d]: %s\n", i, s->toChars()); - s = s->semantic(scd); - (*statements)[i] = s; -+ -+ if (s && !serror) -+ serror = s->isErrorStatement(); - } - } - - scd->pop(); -- sc->noctor--; -- return this; -+ return serror ? serror : this; - } - - void UnrolledLoopStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -@@ -915,16 +988,6 @@ bool UnrolledLoopStatement::hasContinue( - return TRUE; - } - --bool UnrolledLoopStatement::usesEH() --{ -- for (size_t i = 0; i < statements->dim; i++) -- { Statement *s = (*statements)[i]; -- if (s && s->usesEH()) -- return TRUE; -- } -- return FALSE; --} -- - int UnrolledLoopStatement::blockExit(bool mustNotThrow) - { - int result = BEfallthru; -@@ -940,22 +1003,6 @@ int UnrolledLoopStatement::blockExit(boo - } - - --int UnrolledLoopStatement::comeFrom() --{ int comefrom = FALSE; -- -- //printf("UnrolledLoopStatement::comeFrom()\n"); -- for (size_t i = 0; i < statements->dim; i++) -- { Statement *s = (*statements)[i]; -- -- if (!s) -- continue; -- -- comefrom |= s->comeFrom(); -- } -- return comefrom; --} -- -- - /******************************** ScopeStatement ***************************/ - - ScopeStatement::ScopeStatement(Loc loc, Statement *s) -@@ -979,13 +1026,12 @@ Statement *ScopeStatement::semantic(Scop - - //printf("ScopeStatement::semantic(sc = %p)\n", sc); - if (statement) -- { Statements *a; -- -+ { - sym = new ScopeDsymbol(); - sym->parent = sc->scopesym; - sc = sc->push(sym); - -- a = statement->flatten(sc); -+ Statements *a = statement->flatten(sc); - if (a) - { - statement = new CompoundStatement(loc, a); -@@ -994,6 +1040,12 @@ Statement *ScopeStatement::semantic(Scop - statement = statement->semantic(sc); - if (statement) - { -+ if (statement->isErrorStatement()) -+ { -+ sc->pop(); -+ return statement; -+ } -+ - Statement *sentry; - Statement *sexception; - Statement *sfinally; -@@ -1025,11 +1077,6 @@ bool ScopeStatement::hasContinue() - return statement ? statement->hasContinue() : FALSE; - } - --bool ScopeStatement::usesEH() --{ -- return statement ? statement->usesEH() : FALSE; --} -- - int ScopeStatement::blockExit(bool mustNotThrow) - { - //printf("ScopeStatement::blockExit(%p)\n", statement); -@@ -1037,18 +1084,6 @@ int ScopeStatement::blockExit(bool mustN - } - - --int ScopeStatement::comeFrom() --{ -- //printf("ScopeStatement::comeFrom()\n"); -- return statement ? statement->comeFrom() : FALSE; --} -- --int ScopeStatement::isEmpty() --{ -- //printf("ScopeStatement::isEmpty() %d\n", statement ? statement->isEmpty() : TRUE); -- return statement ? statement->isEmpty() : TRUE; --} -- - void ScopeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writeByte('{'); -@@ -1099,12 +1134,6 @@ bool WhileStatement::hasContinue() - return TRUE; - } - --bool WhileStatement::usesEH() --{ -- assert(global.errors); -- return 0; --} -- - int WhileStatement::blockExit(bool mustNotThrow) - { - assert(global.errors); -@@ -1112,12 +1141,6 @@ int WhileStatement::blockExit(bool mustN - } - - --int WhileStatement::comeFrom() --{ -- assert(global.errors); -- return FALSE; --} -- - void WhileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring("while ("); -@@ -1156,6 +1179,12 @@ Statement *DoStatement::semantic(Scope * - - condition = condition->checkToBoolean(sc); - -+ if (condition->op == TOKerror) -+ return new ErrorStatement(); -+ -+ if (body && body->isErrorStatement()) -+ return body; -+ - return this; - } - -@@ -1169,11 +1198,6 @@ bool DoStatement::hasContinue() - return TRUE; - } - --bool DoStatement::usesEH() --{ -- return body ? body->usesEH() : 0; --} -- - int DoStatement::blockExit(bool mustNotThrow) - { int result; - -@@ -1198,13 +1222,6 @@ int DoStatement::blockExit(bool mustNotT - } - - --int DoStatement::comeFrom() --{ -- if (body) -- return body->comeFrom(); -- return FALSE; --} -- - void DoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring("do"); -@@ -1226,7 +1243,6 @@ ForStatement::ForStatement(Loc loc, Stat - this->condition = condition; - this->increment = increment; - this->body = body; -- this->nest = 0; - this->relatedLabeled = NULL; - } - -@@ -1245,144 +1261,44 @@ Statement *ForStatement::syntaxCopy() - return s; - } - --/* -- * Run semantic on init recursively. -- * Rewrite: -- * for (auto x=X(), y = Y(); ...; ...) {} -- * as: -- * try { -- * try { -- * for (auto x=X(), auto y=Y(); ...; ...) {} -- * } -- * finally { y.~this(); } -- * } -- * finally { x.~this(); } -- */ --Statement *ForStatement::semanticInit(Scope *sc) -+Statement *ForStatement::semantic(Scope *sc) - { -- assert(init); -- ++nest; -+ //printf("ForStatement::semantic %s\n", toChars()); - -- Loc locinit = init->loc; -- Statements *ainit = init->flatten(sc); -- if (!ainit) -- (ainit = new Statements())->push(init); -- init = NULL; -- -- Statement *statement = this; -- -- for (size_t i = 0; i < ainit->dim; i++) -- { Statement *s = (*ainit)[i]; -+ if (init) -+ { -+ /* Rewrite: -+ * for (auto v1 = i1, v2 = i2; condition; increment) { ... } -+ * to: -+ * { auto v1 = i1, v2 = i2; for (; condition; increment) { ... } } -+ * then lowered to: -+ * auto v1 = i1; -+ * try { -+ * auto v2 = i2; -+ * try { -+ * for (; condition; increment) { ... } -+ * } finally { v2.~this(); } -+ * } finally { v1.~this(); } -+ */ -+ Statements *ainit = new Statements(); -+ ainit->push(init), init = NULL; -+ ainit->push(this); -+ Statement *s = new CompoundStatement(loc, ainit); -+ s = new ScopeStatement(loc, s); - s = s->semantic(sc); -- (*ainit)[i] = s; -- if (s) -+ if (!s->isErrorStatement()) - { -- Statement *sentry; -- Statement *sexception; -- Statement *sfinally; -- -- (*ainit)[i] = s->scopeCode(sc, &sentry, &sexception, &sfinally); -- -- if (sentry) -- { sentry = sentry->semantic(sc); -- if (sentry) -- ainit->insert(i++, sentry); -- } -- if (sexception) -- sexception = sexception->semantic(sc); -- if (sexception) -- { // Re-initialize this->init -- if (i + 1 < ainit->dim) -- { -- Statements *a = new Statements(); -- for (size_t j = i + 1; j < ainit->dim; j++) -- a->push((*ainit)[j]); -- init = new CompoundStatement(0, a); -- } -- -- Identifier *id = Lexer::uniqueId("__o"); -- Statement *handler = sexception; -- if (sexception->blockExit(FALSE) & BEfallthru) -- { handler = new ThrowStatement(0, new IdentifierExp(0, id)); -- ((ThrowStatement *)handler)->internalThrow = true; -- handler = new CompoundStatement(0, sexception, handler); -- } -- Catches *catches = new Catches(); -- Catch *ctch = new Catch(0, NULL, id, handler); -- catches->push(ctch); -- s = new TryCatchStatement(0, this, catches); -- -- if (sfinally) -- s = new TryFinallyStatement(0, s, sfinally); -- //printf("ex {{{\n"); -- s = s->semantic(sc); -- //printf("}}}\n"); -- this->relatedLabeled = s; -- statement = s; -- -- if (init) -- { Statements *a = init->flatten(sc); -- if (!a) -- (a = new Statements())->push(init); -- for (size_t j = 0; j < i + 1; j++) -- a->insert(j, (*ainit)[j]); -- init = new CompoundStatement(locinit, a); -- } -- break; -- } -- else if (sfinally) -- { // Re-initialize this->init -- if (i + 1 < ainit->dim) -- { -- Statements *a = new Statements(); -- for (size_t j = i + 1; j < ainit->dim; j++) -- a->push((*ainit)[j]); -- init = new CompoundStatement(0, a); -- } -- -- s = new TryFinallyStatement(0, this, sfinally); -- //printf("fi {{{\n"); -- s = s->semantic(sc); -- //printf("}}} fi\n"); -- this->relatedLabeled = s; -- statement = s; -- -- if (init) -- { Statements *a = init->flatten(sc); -- if (!a) -- (a = new Statements())->push(init); -- for (size_t j = 0; j < i + 1; j++) -- a->insert(j, (*ainit)[j]); -- init = new CompoundStatement(locinit, a); -- } -- break; -- } -+ if (LabelStatement *ls = checkLabeledLoop(sc, this)) -+ ls->gotoTarget = this; -+ relatedLabeled = s; - } -+ return s; - } -- if (!init) -- { // whole init semantic is completely done. -- init = new CompoundStatement(locinit, ainit); -- } -- -- --nest; -- return statement; --} -- --Statement *ForStatement::semantic(Scope *sc) --{ -- if (!nest) -- { ScopeDsymbol *sym = new ScopeDsymbol(); -- sym->parent = sc->scopesym; -- sc = sc->push(sym); -- } -- else if (init) -- { // Process this->init recursively -- return semanticInit(sc); -- } -+ assert(init == NULL); - -- Statement *statement = this; -- if (init) -- statement = semanticInit(sc); -+ ScopeDsymbol *sym = new ScopeDsymbol(); -+ sym->parent = sc->scopesym; -+ sc = sc->push(sym); - - sc->noctor++; - if (condition) -@@ -1403,10 +1319,14 @@ Statement *ForStatement::semantic(Scope - body = body->semanticNoScope(sc); - sc->noctor--; - -- if (!nest) -- sc->pop(); -- //if (!nest) statement->print(); -- return statement; -+ sc->pop(); -+ -+ if (condition && condition->op == TOKerror || -+ increment && increment->op == TOKerror || -+ body && body->isErrorStatement()) -+ return new ErrorStatement(); -+ -+ return this; - } - - Statement *ForStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) -@@ -1427,11 +1347,6 @@ bool ForStatement::hasContinue() - return TRUE; - } - --bool ForStatement::usesEH() --{ -- return (init && init->usesEH()) || body->usesEH(); --} -- - int ForStatement::blockExit(bool mustNotThrow) - { int result = BEfallthru; - -@@ -1462,17 +1377,6 @@ int ForStatement::blockExit(bool mustNot - } - - --int ForStatement::comeFrom() --{ -- //printf("ForStatement::comeFrom()\n"); -- if (body) -- { int result = body->comeFrom(); -- //printf("result = %d\n", result); -- return result; -- } -- return FALSE; --} -- - void ForStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring("for ("); -@@ -1506,7 +1410,7 @@ void ForStatement::toCBuffer(OutBuffer * - - /******************************** ForeachStatement ***************************/ - --ForeachStatement::ForeachStatement(Loc loc, enum TOK op, Parameters *arguments, -+ForeachStatement::ForeachStatement(Loc loc, TOK op, Parameters *arguments, - Expression *aggr, Statement *body) - : Statement(loc) - { -@@ -1552,7 +1456,8 @@ Statement *ForeachStatement::semantic(Sc - if (!inferAggregate(sc, sapply)) - { - error("invalid foreach aggregate %s", aggr->toChars()); -- return this; -+ Lerror: -+ return new ErrorStatement(); - } - - /* Check for inference errors -@@ -1561,7 +1466,7 @@ Statement *ForeachStatement::semantic(Sc - { - //printf("dim = %d, arguments->dim = %d\n", dim, arguments->dim); - error("cannot uniquely infer foreach argument types"); -- return this; -+ goto Lerror; - } - - Type *tab = aggr->type->toBasetype(); -@@ -1571,30 +1476,24 @@ Statement *ForeachStatement::semantic(Sc - if (dim < 1 || dim > 2) - { - error("only one (value) or two (key,value) arguments for tuple foreach"); -- return s; -+ goto Lerror; - } - - Type *argtype = (*arguments)[dim-1]->type; - if (argtype) -- argtype = argtype->semantic(loc, sc); -+ { argtype = argtype->semantic(loc, sc); -+ if (argtype->ty == Terror) -+ goto Lerror; -+ } - - TypeTuple *tuple = (TypeTuple *)tab; - Statements *statements = new Statements(); - //printf("aggr: op = %d, %s\n", aggr->op, aggr->toChars()); - size_t n; - TupleExp *te = NULL; -- Expression *prelude = NULL; - if (aggr->op == TOKtuple) // expression tuple - { te = (TupleExp *)aggr; - n = te->exps->dim; -- -- if (te->exps->dim > 0 && (*te->exps)[0]->op == TOKdotvar && -- ((DotVarExp *)(*te->exps)[0])->e1->isTemp()) -- { -- CommaExp *ce = (CommaExp *)((DotVarExp *)(*te->exps)[0])->e1; -- prelude = ce->e1; -- ((DotVarExp *)(*te->exps)[0])->e1 = ce->e2; -- } - } - else if (aggr->op == TOKtype) // type tuple - { -@@ -1616,7 +1515,9 @@ Statement *ForeachStatement::semantic(Sc - if (dim == 2) - { // Declare key - if (arg->storageClass & (STCout | STCref | STClazy)) -- error("no storage class for key %s", arg->ident->toChars()); -+ { error("no storage class for key %s", arg->ident->toChars()); -+ goto Lerror; -+ } - arg->type = arg->type->semantic(loc, sc); - TY keyty = arg->type->ty; - if (keyty != Tint32 && keyty != Tuns32) -@@ -1624,12 +1525,16 @@ Statement *ForeachStatement::semantic(Sc - if (global.params.is64bit) - { - if (keyty != Tint64 && keyty != Tuns64) -- error("foreach: key type must be int or uint, long or ulong, not %s", arg->type->toChars()); -+ { error("foreach: key type must be int or uint, long or ulong, not %s", arg->type->toChars()); -+ goto Lerror; -+ } - } - else -- error("foreach: key type must be int or uint, not %s", arg->type->toChars()); -+ { error("foreach: key type must be int or uint, not %s", arg->type->toChars()); -+ goto Lerror; -+ } - } -- Initializer *ie = new ExpInitializer(0, new IntegerExp(k)); -+ Initializer *ie = new ExpInitializer(Loc(), new IntegerExp(k)); - VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, ie); - var->storage_class |= STCmanifest; - DeclarationExp *de = new DeclarationExp(loc, var); -@@ -1639,7 +1544,10 @@ Statement *ForeachStatement::semantic(Sc - // Declare value - if (arg->storageClass & (STCout | STClazy) || - arg->storageClass & STCref && !te) -+ { - error("no storage class for value %s", arg->ident->toChars()); -+ goto Lerror; -+ } - Dsymbol *var; - if (te) - { Type *tb = e->type->toBasetype(); -@@ -1655,29 +1563,37 @@ Statement *ForeachStatement::semantic(Sc - { - var = new AliasDeclaration(loc, arg->ident, s); - if (arg->storageClass & STCref) -- error("symbol %s cannot be ref", s->toChars()); -- if (argtype && argtype->ty != Terror) -- error("cannot specify element type for symbol %s", s->toChars()); -+ { error("symbol %s cannot be ref", s->toChars()); -+ goto Lerror; -+ } -+ if (argtype) -+ { error("cannot specify element type for symbol %s", s->toChars()); -+ goto Lerror; -+ } - } - else if (e->op == TOKtype) - { - var = new AliasDeclaration(loc, arg->ident, e->type); -- if (argtype && argtype->ty != Terror) -- error("cannot specify element type for type %s", e->type->toChars()); -+ if (argtype) -+ { error("cannot specify element type for type %s", e->type->toChars()); -+ goto Lerror; -+ } - } - else - { - arg->type = e->type; -- if (argtype && argtype->ty != Terror) -+ if (argtype) - arg->type = argtype; -- Initializer *ie = new ExpInitializer(0, e); -+ Initializer *ie = new ExpInitializer(Loc(), e); - VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie); - if (arg->storageClass & STCref) - v->storage_class |= STCref | STCforeach; - if (e->isConst() || e->op == TOKstring || - e->op == TOKstructliteral || e->op == TOKarrayliteral) - { if (v->storage_class & STCref) -- error("constant value %s cannot be ref", ie->toChars()); -+ { error("constant value %s cannot be ref", ie->toChars()); -+ goto Lerror; -+ } - else - v->storage_class |= STCmanifest; - } -@@ -1687,8 +1603,10 @@ Statement *ForeachStatement::semantic(Sc - else - { - var = new AliasDeclaration(loc, arg->ident, t); -- if (argtype && argtype->ty != Terror) -- error("cannot specify element type for symbol %s", s->toChars()); -+ if (argtype) -+ { error("cannot specify element type for symbol %s", s->toChars()); -+ goto Lerror; -+ } - } - DeclarationExp *de = new DeclarationExp(loc, var); - st->push(new ExpStatement(loc, de)); -@@ -1700,9 +1618,11 @@ Statement *ForeachStatement::semantic(Sc - } - - s = new UnrolledLoopStatement(loc, statements); -- if (prelude) -+ if (LabelStatement *ls = checkLabeledLoop(sc, this)) -+ ls->gotoTarget = s; -+ if (te && te->e0) - s = new CompoundStatement(loc, -- new ExpStatement(prelude->loc, prelude), s); -+ new ExpStatement(te->e0->loc, te->e0), s); - s = s->semantic(sc); - return s; - } -@@ -1724,7 +1644,7 @@ Lagain: - if (dim < 1 || dim > 2) - { - error("only one or two arguments for array foreach"); -- break; -+ goto Lerror2; - } - - /* Look for special case of parsing char types out of char type -@@ -1732,10 +1652,9 @@ Lagain: - */ - tn = tab->nextOf()->toBasetype(); - if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) -- { Parameter *arg; -- -+ { - int i = (dim == 1) ? 0 : 1; // index of value -- arg = (*arguments)[i]; -+ Parameter *arg = (*arguments)[i]; - arg->type = arg->type->semantic(loc, sc); - arg->type = arg->type->addStorageClass(arg->storageClass); - tnv = arg->type->toBasetype(); -@@ -1743,11 +1662,15 @@ Lagain: - (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar)) - { - if (arg->storageClass & STCref) -- error("foreach: value of UTF conversion cannot be ref"); -+ { error("foreach: value of UTF conversion cannot be ref"); -+ goto Lerror2; -+ } - if (dim == 2) - { arg = (*arguments)[0]; - if (arg->storageClass & STCref) -- error("foreach: key cannot be ref"); -+ { error("foreach: key cannot be ref"); -+ goto Lerror2; -+ } - } - goto Lapply; - } -@@ -1770,11 +1693,12 @@ Lagain: - key = var; - if (arg->storageClass & STCref) - { -- if (!var->type->invariantOf()->equals(arg->type->invariantOf()) || -+ if (!var->type->immutableOf()->equals(arg->type->immutableOf()) || - !MODimplicitConv(var->type->mod, arg->type->mod)) - { - error("key type mismatch, %s to ref %s", - var->type->toChars(), arg->type->toChars()); -+ goto Lerror2; - } - } - } -@@ -1797,11 +1721,12 @@ Lagain: - var->storage_class |= STCconst; - - Type *t = tab->nextOf(); -- if (!t->invariantOf()->equals(arg->type->invariantOf()) || -+ if (!t->immutableOf()->equals(arg->type->immutableOf()) || - !MODimplicitConv(t->mod, arg->type->mod)) - { - error("argument type mismatch, %s to ref %s", - t->toChars(), arg->type->toChars()); -+ goto Lerror2; - } - } - } -@@ -1836,7 +1761,7 @@ Lagain: - if (op == TOKforeach_reverse) - key->init = new ExpInitializer(loc, tmp_length); - else -- key->init = new ExpInitializer(loc, new IntegerExp(0)); -+ key->init = new ExpInitializer(loc, new IntegerExp(loc, 0, NULL)); - - Statements *cs = new Statements(); - cs->push(new ExpStatement(loc, tmp)); -@@ -1854,7 +1779,7 @@ Lagain: - Expression *increment = NULL; - if (op == TOKforeach) - // key += 1 -- increment = new AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(1)); -+ increment = new AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(loc, 1, NULL)); - - // T value = tmp[key]; - value->init = new ExpInitializer(loc, new IndexExp(loc, new VarExp(loc, tmp), new VarExp(loc, key))); -@@ -1871,17 +1796,15 @@ Lagain: - { - ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident)); - VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie); --#if (BUG6652 == 1 || BUG6652 == 2) -- v->storage_class |= STCforeach | STCref | (arg->storageClass & STCref ? 0 : STCbug6652); --#else - v->storage_class |= STCforeach | (arg->storageClass & STCref); --#endif - body = new CompoundStatement(loc, new ExpStatement(loc, v), body); - } - } - body = new CompoundStatement(loc, ds, body); - - s = new ForStatement(loc, forinit, cond, increment, body); -+ if (LabelStatement *ls = checkLabeledLoop(sc, this)) -+ ls->gotoTarget = s; - s = s->semantic(sc); - break; - } -@@ -1926,7 +1849,7 @@ Lagain: - if (dim < 1 || dim > 2) - { - error("only one or two arguments for associative array foreach"); -- break; -+ goto Lerror2; - } - - /* This only works if Key or Value is a static array. -@@ -1964,7 +1887,7 @@ Lagain: - { idfront = Id::Fback; - idpopFront = Id::FpopBack; - } -- Dsymbol *sfront = ad->search(0, idfront, 0); -+ Dsymbol *sfront = ad->search(Loc(), idfront, 0); - if (!sfront) - goto Lapply; - -@@ -2057,6 +1980,8 @@ Lagain: - makeargs, this->body); - - s = new ForStatement(loc, init, condition, increment, forbody); -+ if (LabelStatement *ls = checkLabeledLoop(sc, this)) -+ ls->gotoTarget = s; - #if 0 - printf("init: %s\n", init->toChars()); - printf("condition: %s\n", condition->toChars()); -@@ -2068,7 +1993,7 @@ Lagain: - - Lrangeerr: - error("cannot infer argument types"); -- break; -+ goto Lerror2; - } - #endif - case Tdelegate: -@@ -2082,8 +2007,6 @@ Lagain: - return this; - } - -- Type *tret = func->type->nextOf(); -- - TypeFunction *tfld = NULL; - if (sapply) - { FuncDeclaration *fdapply = sapply->isFuncDeclaration(); -@@ -2127,7 +2050,9 @@ Lagain: - id = arg->ident; // argument copy is not need. - if ((arg->storageClass & STCref) != stc) - { if (!stc) -- error("foreach: cannot make %s ref", arg->ident->toChars()); -+ { error("foreach: cannot make %s ref", arg->ident->toChars()); -+ goto Lerror2; -+ } - goto LcopyArg; - } - } -@@ -2142,9 +2067,9 @@ Lagain: - LcopyArg: - id = Lexer::uniqueId("__applyArg", (int)i); - -- Initializer *ie = new ExpInitializer(0, new IdentifierExp(0, id)); -- VarDeclaration *v = new VarDeclaration(0, arg->type, arg->ident, ie); -- s = new ExpStatement(0, v); -+ Initializer *ie = new ExpInitializer(Loc(), new IdentifierExp(Loc(), id)); -+ VarDeclaration *v = new VarDeclaration(Loc(), arg->type, arg->ident, ie); -+ s = new ExpStatement(Loc(), v); - body = new CompoundStatement(loc, s, body); - } - args->push(new Parameter(stc, arg->type, id, NULL)); -@@ -2152,7 +2077,7 @@ Lagain: - tfld = new TypeFunction(args, Type::tint32, 0, LINKd); - cases = new Statements(); - gotos = new CompoundStatements(); -- FuncLiteralDeclaration *fld = new FuncLiteralDeclaration(loc, 0, tfld, TOKdelegate, this); -+ FuncLiteralDeclaration *fld = new FuncLiteralDeclaration(loc, Loc(), tfld, TOKdelegate, this); - fld->fbody = body; - Expression *flde = new FuncExp(loc, fld); - flde = flde->semantic(sc); -@@ -2166,7 +2091,7 @@ Lagain: - if (!gs->label->statement) - { // 'Promote' it to this scope, and replace with a return - cases->push(gs); -- s = new ReturnStatement(0, new IntegerExp(cases->dim + 1)); -+ s = new ReturnStatement(Loc(), new IntegerExp(cases->dim + 1)); - (*cs->statements)[0] = s; - } - } -@@ -2178,38 +2103,61 @@ Lagain: - if (dim == 2) - { - if (arg->storageClass & STCref) -- error("foreach: index cannot be ref"); -+ { error("foreach: index cannot be ref"); -+ goto Lerror2; -+ } - if (!arg->type->equals(taa->index)) -- error("foreach: index must be type %s, not %s", taa->index->toChars(), arg->type->toChars()); -+ { error("foreach: index must be type %s, not %s", taa->index->toChars(), arg->type->toChars()); -+ goto Lerror2; -+ } - arg = (*arguments)[1]; - } - if (!arg->type->equals(taa->nextOf())) -- error("foreach: value must be type %s, not %s", taa->nextOf()->toChars(), arg->type->toChars()); -- -+ { error("foreach: value must be type %s, not %s", taa->nextOf()->toChars(), arg->type->toChars()); -+ goto Lerror2; -+ } - /* Call: - * _aaApply(aggr, keysize, flde) - */ -- FuncDeclaration *fdapply; -- if (dim == 2) -- fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2"); -- else -- fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply"); -- ec = new VarExp(0, fdapply); -+ static const char *name[2] = { "_aaApply", "_aaApply2" }; -+ static FuncDeclaration *fdapply[2] = { NULL, NULL }; -+ static TypeDelegate *fldeTy[2] = { NULL, NULL }; -+ -+ unsigned char i = dim == 2; -+ if (!fdapply[i]) { -+ Parameters* args = new Parameters; -+ args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL)); -+ args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); -+ Parameters* dgargs = new Parameters; -+ dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); -+ if (dim == 2) -+ dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); -+ fldeTy[i] = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); -+ args->push(new Parameter(STCin, fldeTy[i], NULL, NULL)); -+ fdapply[i] = FuncDeclaration::genCfunc(args, Type::tint32, name[i]); -+ } -+ -+ ec = new VarExp(Loc(), fdapply[i]); - Expressions *exps = new Expressions(); - exps->push(aggr); - size_t keysize = taa->index->size(); - keysize = (keysize + ((size_t)Target::ptrsize-1)) & ~((size_t)Target::ptrsize-1); -- exps->push(new IntegerExp(0, keysize, Type::tsize_t)); -+ // paint delegate argument to the type runtime expects -+ if (!fldeTy[i]->equals(flde->type)) { -+ flde = new CastExp(loc, flde, flde->type); -+ flde->type = fldeTy[i]; -+ } -+ exps->push(new IntegerExp(Loc(), keysize, Type::tsize_t)); - exps->push(flde); - e = new CallExp(loc, ec, exps); -- e->type = Type::tindex; // don't run semantic() on e -+ e->type = Type::tint32; // don't run semantic() on e - } - else if (tab->ty == Tarray || tab->ty == Tsarray) - { - /* Call: - * _aApply(aggr, flde) - */ -- static char fntab[9][3] = -+ static const char fntab[9][3] = - { "cc","cw","cd", - "wc","cc","wd", - "dc","dw","dd" -@@ -2233,17 +2181,33 @@ Lagain: - } - const char *r = (op == TOKforeach_reverse) ? "R" : ""; - int j = sprintf(fdname, "_aApply%s%.*s%llu", r, 2, fntab[flag], (ulonglong)dim); -- assert(j < sizeof(fdname)); -- FuncDeclaration *fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname); -+ assert(j < sizeof(fdname) / sizeof(fdname[0])); - -- ec = new VarExp(0, fdapply); -+ FuncDeclaration *fdapply; -+ TypeDelegate *dgty; -+ Parameters* args = new Parameters; -+ args->push(new Parameter(STCin, tn->arrayOf(), NULL, NULL)); -+ Parameters* dgargs = new Parameters; -+ dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); -+ if (dim == 2) -+ dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); -+ dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); -+ args->push(new Parameter(STCin, dgty, NULL, NULL)); -+ fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname); -+ -+ ec = new VarExp(Loc(), fdapply); - Expressions *exps = new Expressions(); - if (tab->ty == Tsarray) - aggr = aggr->castTo(sc, tn->arrayOf()); - exps->push(aggr); -+ // paint delegate argument to the type runtime expects -+ if (!dgty->equals(flde->type)) { -+ flde = new CastExp(loc, flde, flde->type); -+ flde->type = dgty; -+ } - exps->push(flde); - e = new CallExp(loc, ec, exps); -- e->type = Type::tindex; // don't run semantic() on e -+ e->type = Type::tint32; // don't run semantic() on e - } - else if (tab->ty == Tdelegate) - { -@@ -2260,7 +2224,9 @@ Lagain: - e = new CallExp(loc, aggr, exps); - e = e->semantic(sc); - if (e->type != Type::tint32) -- error("opApply() function for %s must return an int", tab->toChars()); -+ { error("opApply() function for %s must return an int", tab->toChars()); -+ goto Lerror2; -+ } - } - else - { -@@ -2290,7 +2256,9 @@ Lagain: - e = new CallExp(loc, ec, exps); - e = e->semantic(sc); - if (e->type != Type::tint32) -- error("opApply() function for %s must return an int", tab->toChars()); -+ { error("opApply() function for %s must return an int", tab->toChars()); -+ goto Lerror2; -+ } - } - - if (!cases->dim) -@@ -2302,15 +2270,15 @@ Lagain: - Statements *a = new Statements(); - - // default: break; takes care of cases 0 and 1 -- s = new BreakStatement(0, NULL); -- s = new DefaultStatement(0, s); -+ s = new BreakStatement(Loc(), NULL); -+ s = new DefaultStatement(Loc(), s); - a->push(s); - - // cases 2... - for (size_t i = 0; i < cases->dim; i++) - { - s = (*cases)[i]; -- s = new CaseStatement(0, new IntegerExp(i + 2), s); -+ s = new CaseStatement(Loc(), new IntegerExp(i + 2), s); - a->push(s); - } - -@@ -2321,13 +2289,13 @@ Lagain: - break; - } - case Terror: -- s = NULL; -+ Lerror2: -+ s = new ErrorStatement(); - break; - - default: - error("foreach: %s is not an aggregate type", aggr->type->toChars()); -- s = NULL; // error recovery -- break; -+ goto Lerror2; - } - sc->noctor--; - sc->pop(); -@@ -2359,11 +2327,6 @@ bool ForeachStatement::hasContinue() - return TRUE; - } - --bool ForeachStatement::usesEH() --{ -- return body->usesEH(); --} -- - int ForeachStatement::blockExit(bool mustNotThrow) - { int result = BEfallthru; - -@@ -2378,13 +2341,6 @@ int ForeachStatement::blockExit(bool mus - } - - --int ForeachStatement::comeFrom() --{ -- if (body) -- return body->comeFrom(); -- return FALSE; --} -- - void ForeachStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring(Token::toChars(op)); -@@ -2395,8 +2351,7 @@ void ForeachStatement::toCBuffer(OutBuff - if (i) - buf->writestring(", "); - if (a->storageClass & STCref) -- buf->writestring((global.params.Dversion == 1) -- ? (char*)"inout " : (char*)"ref "); -+ buf->writestring((char*)"ref "); - if (a->type) - a->type->toCBuffer(buf, a->ident, hgs); - else -@@ -2420,7 +2375,7 @@ void ForeachStatement::toCBuffer(OutBuff - - #if DMDV2 - --ForeachRangeStatement::ForeachRangeStatement(Loc loc, enum TOK op, Parameter *arg, -+ForeachRangeStatement::ForeachRangeStatement(Loc loc, TOK op, Parameter *arg, - Expression *lwr, Expression *upr, Statement *body) - : Statement(loc) - { -@@ -2446,15 +2401,14 @@ Statement *ForeachRangeStatement::syntax - Statement *ForeachRangeStatement::semantic(Scope *sc) - { - //printf("ForeachRangeStatement::semantic() %p\n", this); -- Statement *s = this; -- - lwr = lwr->semantic(sc); - lwr = resolveProperties(sc, lwr); - lwr = lwr->optimize(WANTvalue); - if (!lwr->type) - { - error("invalid range lower bound %s", lwr->toChars()); -- return this; -+ Lerror: -+ return new ErrorStatement(); - } - - upr = upr->semantic(sc); -@@ -2463,7 +2417,7 @@ Statement *ForeachRangeStatement::semant - if (!upr->type) - { - error("invalid range upper bound %s", upr->toChars()); -- return this; -+ goto Lerror; - } - - if (arg->type) -@@ -2483,19 +2437,24 @@ Statement *ForeachRangeStatement::semant - /* Just picking the first really isn't good enough. - */ - arg->type = lwr->type; -- arg->type = arg->type->addStorageClass(arg->storageClass); -+ } -+ else if (lwr->type == upr->type) -+ { -+ /* Same logic as CondExp ?lwr:upr -+ */ -+ arg->type = lwr->type; - } - else - { - AddExp ea(loc, lwr, upr); - Expression *e = ea.typeCombine(sc); - arg->type = ea.type; -- arg->type = arg->type->addStorageClass(arg->storageClass); - lwr = ea.e1; - upr = ea.e2; - } -+ arg->type = arg->type->addStorageClass(arg->storageClass); - } --#if 1 -+ - /* Convert to a for loop: - * foreach (key; lwr .. upr) => - * for (auto key = lwr, auto tmp = upr; key < tmp; ++key) -@@ -2561,16 +2520,12 @@ Statement *ForeachRangeStatement::semant - { - ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident)); - VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie); --#if (BUG6652 == 1 || BUG6652 == 2) -- v->storage_class |= STCforeach | STCref | (arg->storageClass & STCref ? 0 : STCbug6652); --#else - v->storage_class |= STCforeach | (arg->storageClass & STCref); --#endif - body = new CompoundStatement(loc, new ExpStatement(loc, v), body); - } - if (arg->storageClass & STCref) - { -- if (!key->type->invariantOf()->equals(arg->type->invariantOf()) || -+ if (!key->type->immutableOf()->equals(arg->type->immutableOf()) || - !MODimplicitConv(key->type->mod, arg->type->mod)) - { - error("argument type mismatch, %s to ref %s", -@@ -2578,34 +2533,10 @@ Statement *ForeachRangeStatement::semant - } - } - -- ForStatement *fs = new ForStatement(loc, forinit, cond, increment, body); -- s = fs->semantic(sc); -- return s; --#else -- if (!arg->type->isscalar()) -- error("%s is not a scalar type", arg->type->toChars()); -- -- sym = new ScopeDsymbol(); -- sym->parent = sc->scopesym; -- sc = sc->push(sym); -- -- sc->noctor++; -- -- key = new VarDeclaration(loc, arg->type, arg->ident, NULL); -- DeclarationExp *de = new DeclarationExp(loc, key); -- de->semantic(sc); -- -- if (key->storage_class) -- error("foreach range: key cannot have storage class"); -- -- sc->sbreak = this; -- sc->scontinue = this; -- body = body->semantic(sc); -- -- sc->noctor--; -- sc->pop(); -- return s; --#endif -+ ForStatement *s = new ForStatement(loc, forinit, cond, increment, body); -+ if (LabelStatement *ls = checkLabeledLoop(sc, this)) -+ ls->gotoTarget = s; -+ return s->semantic(sc); - } - - bool ForeachRangeStatement::hasBreak() -@@ -2618,12 +2549,6 @@ bool ForeachRangeStatement::hasContinue( - return TRUE; - } - --bool ForeachRangeStatement::usesEH() --{ -- assert(global.errors); -- return body->usesEH(); --} -- - int ForeachRangeStatement::blockExit(bool mustNotThrow) - { - assert(global.errors); -@@ -2631,12 +2556,6 @@ int ForeachRangeStatement::blockExit(boo - } - - --int ForeachRangeStatement::comeFrom() --{ -- assert(global.errors); -- return FALSE; --} -- - void ForeachRangeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring(Token::toChars(op)); -@@ -2697,21 +2616,23 @@ Statement *IfStatement::semantic(Scope * - // Evaluate at runtime - unsigned cs0 = sc->callSuper; - unsigned cs1; -+ unsigned *fi0 = fi0 = sc->saveFieldInit(); -+ unsigned *fi1 = NULL; - -- Scope *scd; -+ ScopeDsymbol *sym = new ScopeDsymbol(); -+ sym->parent = sc->scopesym; -+ Scope *scd = sc->push(sym); - if (arg) - { /* Declare arg, which we will set to be the - * result of condition. - */ -- ScopeDsymbol *sym = new ScopeDsymbol(); -- sym->parent = sc->scopesym; -- scd = sc->push(sym); - - match = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, condition)); - match->parent = sc->func; -+ match->storage_class |= arg->storageClass; - - DeclarationExp *de = new DeclarationExp(loc, match); -- VarExp *ve = new VarExp(0, match); -+ VarExp *ve = new VarExp(Loc(), match); - condition = new CommaExp(loc, de, ve); - condition = condition->semantic(scd); - -@@ -2728,7 +2649,6 @@ Statement *IfStatement::semantic(Scope * - condition = condition->semantic(sc); - condition = condition->addDtorHook(sc); - condition = resolveProperties(sc, condition); -- scd = sc->push(); - } - - // Convert to boolean after declaring arg so this works: -@@ -2744,19 +2664,23 @@ Statement *IfStatement::semantic(Scope * - scd->pop(); - - cs1 = sc->callSuper; -+ fi1 = sc->fieldinit; - sc->callSuper = cs0; -+ sc->fieldinit = fi0; - if (elsebody) - elsebody = elsebody->semanticScope(sc, NULL, NULL); - sc->mergeCallSuper(loc, cs1); -+ sc->mergeFieldInit(loc, fi1); - -+ if (condition->op == TOKerror || -+ (ifbody && ifbody->isErrorStatement()) || -+ (elsebody && elsebody->isErrorStatement())) -+ { -+ return new ErrorStatement(); -+ } - return this; - } - --bool IfStatement::usesEH() --{ -- return (ifbody && ifbody->usesEH()) || (elsebody && elsebody->usesEH()); --} -- - int IfStatement::blockExit(bool mustNotThrow) - { - //printf("IfStatement::blockExit(%p)\n", this); -@@ -2898,11 +2822,6 @@ Statements *ConditionalStatement::flatte - return a; - } - --bool ConditionalStatement::usesEH() --{ -- return (ifbody && ifbody->usesEH()) || (elsebody && elsebody->usesEH()); --} -- - int ConditionalStatement::blockExit(bool mustNotThrow) - { - int result = ifbody->blockExit(mustNotThrow); -@@ -2971,10 +2890,12 @@ Statement *PragmaStatement::semantic(Sco - { - Expression *e = (*args)[i]; - -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -- if (e->op != TOKerror && e->op != TOKtype) -- e = e->ctfeInterpret(); -+ sc = sc->endCTFE(); -+ // pragma(msg) is allowed to contain types as well as expressions -+ e = ctfeInterpretForPragmaMsg(e); - if (e->op == TOKerror) - { errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars()); - goto Lerror; -@@ -2982,12 +2903,12 @@ Statement *PragmaStatement::semantic(Sco - StringExp *se = e->toString(); - if (se) - { -- fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); -+ fprintf(stderr, "%.*s", (int)se->len, (char *)se->string); - } - else -- fprintf(stdmsg, "%s", e->toChars()); -+ fprintf(stderr, "%s", e->toChars()); - } -- fprintf(stdmsg, "\n"); -+ fprintf(stderr, "\n"); - } - } - else if (ident == Id::lib) -@@ -3003,8 +2924,11 @@ Statement *PragmaStatement::semantic(Sco - { - Expression *e = (*args)[0]; - -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); -+ - e = e->ctfeInterpret(); - (*args)[0] = e; - StringExp *se = e->toString(); -@@ -3015,7 +2939,7 @@ Statement *PragmaStatement::semantic(Sco - char *name = (char *)mem.malloc(se->len + 1); - memcpy(name, se->string, se->len); - name[se->len] = 0; -- printf("library %s\n", name); -+ fprintf(global.stdmsg, "library %s\n", name); - mem.free(name); - } - } -@@ -3029,8 +2953,12 @@ Statement *PragmaStatement::semantic(Sco - else - { - Expression *e = (*args)[0]; -+ -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); -+ - e = e->ctfeInterpret(); - (*args)[0] = e; - Dsymbol *sa = getDsymbol(e); -@@ -3054,11 +2982,6 @@ Lerror: - return body; - } - --bool PragmaStatement::usesEH() --{ -- return body && body->usesEH(); --} -- - int PragmaStatement::blockExit(bool mustNotThrow) - { - int result = BEfallthru; -@@ -3179,8 +3102,9 @@ Statement *SwitchStatement::semantic(Sco - condition->type = condition->type->constOf(); - } - else -- { condition = condition->integralPromotions(sc); -- if (!condition->type->isintegral()) -+ { -+ condition = condition->integralPromotions(sc); -+ if (condition->op != TOKerror && !condition->type->isintegral()) - error("'%s' must be of integral or string type, it is a %s", condition->toChars(), condition->type->toChars()); - } - condition = condition->optimize(WANTvalue); -@@ -3249,8 +3173,11 @@ Statement *SwitchStatement::semantic(Sco - if (em) - { - for (size_t j = 0; j < cases->dim; j++) -- { CaseStatement *cs = (*cases)[j]; -- if (cs->exp->equals(em->value) || cs->exp->toInteger() == em->value->toInteger()) -+ { -+ CaseStatement *cs = (*cases)[j]; -+ if (cs->exp->equals(em->value) || -+ (!cs->exp->type->isString() && !em->value->type->isString() && -+ cs->exp->toInteger() == em->value->toInteger())) - goto L1; - } - error("enum member %s not represented in final switch", em->toChars()); -@@ -3267,7 +3194,7 @@ Statement *SwitchStatement::semantic(Sco - if (!sc->sw->sdefault && (!isFinal || needswitcherror || global.params.useAssert)) - { hasNoDefault = 1; - -- if (!isFinal) -+ if (!isFinal && !body->isErrorStatement()) - deprecation("non-final switch statement without a default is deprecated"); - - // Generate runtime error if the default is hit -@@ -3286,7 +3213,7 @@ Statement *SwitchStatement::semantic(Sco - sc->sw->sdefault = new DefaultStatement(loc, s); - a->push(body); - if (body->blockExit(FALSE) & BEfallthru) -- a->push(new BreakStatement(0, NULL)); -+ a->push(new BreakStatement(Loc(), NULL)); - a->push(sc->sw->sdefault); - cs = new CompoundStatement(loc, a); - body = cs; -@@ -3301,11 +3228,6 @@ bool SwitchStatement::hasBreak() - return TRUE; - } - --bool SwitchStatement::usesEH() --{ -- return body ? body->usesEH() : 0; --} -- - int SwitchStatement::blockExit(bool mustNotThrow) - { int result = BEnone; - if (condition->canThrow(mustNotThrow)) -@@ -3368,11 +3290,14 @@ Statement *CaseStatement::syntaxCopy() - } - - Statement *CaseStatement::semantic(Scope *sc) --{ SwitchStatement *sw = sc->sw; -+{ -+ SwitchStatement *sw = sc->sw; - - //printf("CaseStatement::semantic() %s\n", toChars()); -+ sc = sc->startCTFE(); - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); -+ sc = sc->endCTFE(); - if (sw) - { - exp = exp->implicitCastTo(sc, sw->condition->type); -@@ -3438,7 +3363,7 @@ Statement *CaseStatement::semantic(Scope - return this; - } - --int CaseStatement::compare(Object *obj) -+int CaseStatement::compare(RootObject *obj) - { - // Sort cases so we can do an efficient lookup - CaseStatement *cs2 = (CaseStatement *)(obj); -@@ -3446,22 +3371,12 @@ int CaseStatement::compare(Object *obj) - return exp->compare(cs2->exp); - } - --bool CaseStatement::usesEH() --{ -- return statement->usesEH(); --} -- - int CaseStatement::blockExit(bool mustNotThrow) - { - return statement->blockExit(mustNotThrow); - } - - --int CaseStatement::comeFrom() --{ -- return TRUE; --} -- - void CaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring("case "); -@@ -3494,17 +3409,27 @@ Statement *CaseRangeStatement::syntaxCop - Statement *CaseRangeStatement::semantic(Scope *sc) - { SwitchStatement *sw = sc->sw; - -+ if (sw == NULL) -+ { -+ error("case range not in switch statement"); -+ return NULL; -+ } -+ - //printf("CaseRangeStatement::semantic() %s\n", toChars()); - if (sw->isFinal) - error("case ranges not allowed in final switch"); - -+ sc = sc->startCTFE(); - first = first->semantic(sc); - first = resolveProperties(sc, first); -+ sc = sc->endCTFE(); - first = first->implicitCastTo(sc, sw->condition->type); - first = first->ctfeInterpret(); - -+ sc = sc->startCTFE(); - last = last->semantic(sc); - last = resolveProperties(sc, last); -+ sc = sc->endCTFE(); - last = last->implicitCastTo(sc, sw->condition->type); - last = last->ctfeInterpret(); - -@@ -3606,22 +3531,12 @@ Statement *DefaultStatement::semantic(Sc - return this; - } - --bool DefaultStatement::usesEH() --{ -- return statement->usesEH(); --} -- - int DefaultStatement::blockExit(bool mustNotThrow) - { - return statement->blockExit(mustNotThrow); - } - - --int DefaultStatement::comeFrom() --{ -- return TRUE; --} -- - void DefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring("default:"); -@@ -3764,7 +3679,12 @@ Statement *ReturnStatement::semantic(Sco - if (fd->fes) - fd = fd->fes->func; // fd is now function enclosing foreach - -- Type *tret = fd->type->nextOf(); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ assert(tf->ty == Tfunction); -+ bool isRefReturn = tf->isref && !(fd->storage_class & STCauto); -+ // Until 'ref' deduction finished, 'auto ref' is treated as a 'value return'. -+ -+ Type *tret = tf->next; - if (fd->tintro) - /* We'll be implicitly casting the return expression to tintro - */ -@@ -3791,7 +3711,7 @@ Statement *ReturnStatement::semantic(Sco - // return this; - if (exp && exp->op != TOKthis) - error("cannot return expression from constructor"); -- exp = new ThisExp(0); -+ exp = new ThisExp(Loc()); - exp->type = tret; - } - -@@ -3809,30 +3729,30 @@ Statement *ReturnStatement::semantic(Sco - exp = exp->inferType(fld->treq->nextOf()->nextOf()); - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); -- if (!((TypeFunction *)fd->type)->isref) -+ // Until 'ref' deduction finished, don't invoke constant folding -+ if (!tf->isref) - exp = exp->optimize(WANTvalue); - -+ if (Expression *e = exp->isTemp()) -+ exp = e; // don't need temporary - if (exp->op == TOKcall) -- valueNoDtor(exp); -- else -- { -- Expression *e = exp->isTemp(); -- if (e) -- exp = e; // don't need temporary -- } -+ exp = valueNoDtor(exp); - - if (fd->nrvo_can && exp->op == TOKvar) -- { VarExp *ve = (VarExp *)exp; -+ { -+ VarExp *ve = (VarExp *)exp; - VarDeclaration *v = ve->var->isVarDeclaration(); - -- if (((TypeFunction *)fd->type)->isref) -+ if (isRefReturn) - // Function returns a reference - fd->nrvo_can = 0; - else if (!v || v->isOut() || v->isRef()) - fd->nrvo_can = 0; - else if (fd->nrvo_var == NULL) -- { if (!v->isDataseg() && !v->isParameter() && v->toParent2() == fd) -- { //printf("Setting nrvo to %s\n", v->toChars()); -+ { -+ if (!v->isDataseg() && !v->isParameter() && v->toParent2() == fd) -+ { -+ //printf("Setting nrvo to %s\n", v->toChars()); - fd->nrvo_var = v; - } - else -@@ -3844,15 +3764,8 @@ Statement *ReturnStatement::semantic(Sco - else - fd->nrvo_can = 0; - -- if (!fd->nrvo_can && -- exp->isLvalue() && !((TypeFunction *)fd->type)->isref) -- { -- exp = callCpCtor(exp->loc, sc, exp, 1); -- } -- - if (fd->inferRetType) -- { TypeFunction *tf = (TypeFunction *)fd->type; -- assert(tf->ty == Tfunction); -+ { - Type *tfret = tf->nextOf(); - if (tfret) - { -@@ -3871,7 +3784,7 @@ Statement *ReturnStatement::semantic(Sco - tf->next = exp->type; - else if (m1 && !m2) - ; -- else -+ else if (exp->op != TOKerror) - error("mismatched function return type inference of %s and %s", - exp->type->toChars(), tfret->toChars()); - } -@@ -3898,21 +3811,26 @@ Statement *ReturnStatement::semantic(Sco - unsigned errors = global.startGagging(); - exp->checkEscapeRef(); - if (global.endGagging(errors)) -- tf->isref = FALSE; // return by value -+ tf->isref = false; // return by value - } - else -- tf->isref = FALSE; // return by value -+ tf->isref = false; // return by value - fd->storage_class &= ~STCauto; -+ -+ isRefReturn = tf->isref; // 'ref' deduction finished -+ if (!isRefReturn) -+ exp = exp->optimize(WANTvalue); - } - tf->next = exp->type; - //fd->type = tf->semantic(loc, sc); // Removed with 6902 - if (!fd->tintro) -- { tret = fd->type->nextOf(); -+ { -+ tret = tf->next; - tbret = tret->toBasetype(); - } - } - if (fd->returnLabel) -- eorg = exp; -+ eorg = exp->copy(); - - if (!fd->returns) - fd->returns = new ReturnStatements(); -@@ -3920,38 +3838,41 @@ Statement *ReturnStatement::semantic(Sco - } - else if (tbret->ty != Tvoid) - { -- assert(fd->type->ty == Tfunction); -- TypeFunction *tf = (TypeFunction *)fd->type; -- if (fd->isPureBypassingInference() != PUREimpure && -- !tf->hasMutableIndirectionParams() && -- !exp->type->implicitConvTo(tret) && -- exp->type->invariantOf()->implicitConvTo(tret)) -+ if (!exp->type->implicitConvTo(tret) && -+ fd->parametersIntersect(exp->type)) - { -- exp = exp->castTo(sc, exp->type->invariantOf()); -+ if (exp->type->immutableOf()->implicitConvTo(tret)) -+ exp = exp->castTo(sc, exp->type->immutableOf()); -+ else if (exp->type->wildOf()->implicitConvTo(tret)) -+ exp = exp->castTo(sc, exp->type->wildOf()); - } - if (fd->tintro) -- exp = exp->implicitCastTo(sc, fd->type->nextOf()); -+ exp = exp->implicitCastTo(sc, tf->next); - - // eorg isn't casted to tret (== fd->tintro->nextOf()) - if (fd->returnLabel) - eorg = exp->copy(); - exp = exp->implicitCastTo(sc, tret); - -- if (!((TypeFunction *)fd->type)->isref) -+ if (!isRefReturn) - exp = exp->optimize(WANTvalue); -+ -+ if (!fd->returns) -+ fd->returns = new ReturnStatements(); -+ fd->returns->push(this); - } - } - else if (fd->inferRetType) - { -- if (fd->type->nextOf()) -+ if (tf->next) - { -- if (fd->type->nextOf()->ty != Tvoid) -+ if (tf->next->ty != Tvoid) - error("mismatched function return type inference of void and %s", -- fd->type->nextOf()->toChars()); -+ tf->next->toChars()); - } - else - { -- ((TypeFunction *)fd->type)->next = Type::tvoid; -+ tf->next = Type::tvoid; - //fd->type = fd->type->semantic(loc, sc); // Remove with7321, same as 6902 - if (!fd->tintro) - { tret = Type::tvoid; -@@ -3977,16 +3898,16 @@ Statement *ReturnStatement::semantic(Sco - { - sc->fes->cases->push(this); - // Construct: return cases->dim+1; -- s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); -+ s = new ReturnStatement(Loc(), new IntegerExp(sc->fes->cases->dim + 1)); - } -- else if (fd->type->nextOf()->toBasetype() == Type::tvoid) -+ else if (tf->next->toBasetype() == Type::tvoid) - { -- s = new ReturnStatement(0, NULL); -+ s = new ReturnStatement(Loc(), NULL); - sc->fes->cases->push(s); - - // Construct: { exp; return cases->dim + 1; } - Statement *s1 = new ExpStatement(loc, exp); -- Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); -+ Statement *s2 = new ReturnStatement(Loc(), new IntegerExp(sc->fes->cases->dim + 1)); - s = new CompoundStatement(loc, s1, s2); - } - else -@@ -4000,7 +3921,7 @@ Statement *ReturnStatement::semantic(Sco - VarDeclaration *v = new VarDeclaration(loc, tret, fd->outId, NULL); - v->noscope = 1; - v->storage_class |= STCresult; -- if (((TypeFunction *)fd->type)->isref) -+ if (isRefReturn) - v->storage_class |= STCref | STCforeach; - v->semantic(sco); - if (!sco->insert(v)) -@@ -4009,14 +3930,14 @@ Statement *ReturnStatement::semantic(Sco - fd->vresult = v; - } - -- s = new ReturnStatement(0, new VarExp(0, fd->vresult)); -+ s = new ReturnStatement(Loc(), new VarExp(Loc(), fd->vresult)); - sc->fes->cases->push(s); - - // Construct: { vresult = exp; return cases->dim + 1; } -- exp = new ConstructExp(loc, new VarExp(0, fd->vresult), exp); -+ exp = new ConstructExp(loc, new VarExp(Loc(), fd->vresult), exp); - exp = exp->semantic(sc); - Statement *s1 = new ExpStatement(loc, exp); -- Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); -+ Statement *s2 = new ReturnStatement(Loc(), new IntegerExp(sc->fes->cases->dim + 1)); - s = new CompoundStatement(loc, s1, s2); - } - return s; -@@ -4024,7 +3945,7 @@ Statement *ReturnStatement::semantic(Sco - - if (exp) - { -- if (((TypeFunction *)fd->type)->isref && !fd->isCtorDeclaration()) -+ if (isRefReturn && !fd->isCtorDeclaration()) - { // Function returns a reference - exp = exp->toLvalue(sc, exp); - exp->checkEscapeRef(); -@@ -4039,7 +3960,7 @@ Statement *ReturnStatement::semantic(Sco - if (fd->returnLabel && tbret->ty != Tvoid) - { - fd->buildResultVar(); -- VarExp *v = new VarExp(0, fd->vresult); -+ VarExp *v = new VarExp(Loc(), fd->vresult); - - assert(eorg); - exp = new ConstructExp(loc, v, eorg); -@@ -4051,8 +3972,23 @@ Statement *ReturnStatement::semantic(Sco - if (sc->callSuper & CSXany_ctor && - !(sc->callSuper & (CSXthis_ctor | CSXsuper_ctor))) - error("return without calling constructor"); -- - sc->callSuper |= CSXreturn; -+ if (sc->fieldinit) -+ { -+ AggregateDeclaration *ad = fd->isAggregateMember2(); -+ assert(ad); -+ size_t dim = sc->fieldinit_dim; -+ for (size_t i = 0; i < dim; i++) -+ { -+ VarDeclaration *v = ad->fields[i]; -+ bool mustInit = (v->storage_class & STCnodefaultctor || -+ v->type->needsNested()); -+ if (mustInit && !(sc->fieldinit[i] & CSXthis_ctor)) -+ error("an earlier return statement skips field %s initialization", v->toChars()); -+ -+ sc->fieldinit[i] |= CSXreturn; -+ } -+ } - - // See if all returns are instead to be replaced with a goto returnLabel; - if (fd->returnLabel) -@@ -4064,7 +4000,7 @@ Statement *ReturnStatement::semantic(Sco - { /* Replace: return exp; - * with: exp; goto returnLabel; - */ -- Statement *s = new ExpStatement(0, exp); -+ Statement *s = new ExpStatement(Loc(), exp); - return new CompoundStatement(loc, s, gs); - } - return gs; -@@ -4072,19 +4008,20 @@ Statement *ReturnStatement::semantic(Sco - - if (exp && tbret->ty == Tvoid && !implicit0) - { -+ if (exp->type->ty != Tvoid) -+ { -+ error("cannot return non-void from void function"); -+ } -+ - /* Replace: - * return exp; - * with: -- * exp; return; -+ * cast(void)exp; return; - */ -- Statement *s = new ExpStatement(loc, exp); -+ Expression *ce = new CastExp(loc, exp, Type::tvoid); -+ Statement *s = new ExpStatement(loc, ce); - s = s->semantic(sc); - -- if (exp->type->ty != Tvoid) -- { -- error("cannot return non-void from void function"); -- } -- - exp = NULL; - return new CompoundStatement(loc, s, this); - } -@@ -4133,13 +4070,10 @@ Statement *BreakStatement::semantic(Scop - { - ident = fixupLabelName(sc, ident); - -- Scope *scx; - FuncDeclaration *thisfunc = sc->func; - -- for (scx = sc; scx; scx = scx->enclosing) -+ for (Scope *scx = sc; scx; scx = scx->enclosing) - { -- LabelStatement *ls; -- - if (scx->func != thisfunc) // if in enclosing function - { - if (sc->fes) // if this is the body of a foreach -@@ -4151,38 +4085,40 @@ Statement *BreakStatement::semantic(Scop - * Case numbers start with 2, not 0, as 0 is continue - * and 1 is break. - */ -- Statement *s; - sc->fes->cases->push(this); -- s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); -+ Statement *s = new ReturnStatement(Loc(), new IntegerExp(sc->fes->cases->dim + 1)); - return s; - } - break; // can't break to it - } - -- ls = scx->slabel; -+ LabelStatement *ls = scx->slabel; - if (ls && ls->ident == ident) - { - Statement *s = ls->statement; - - if (!s->hasBreak()) - error("label '%s' has no break", ident->toChars()); -- if (ls->tf != sc->tf) -+ else if (ls->tf != sc->tf) - error("cannot break out of finally block"); -- return this; -+ else -+ return this; -+ return new ErrorStatement(); - } - } - error("enclosing label '%s' for break not found", ident->toChars()); -+ return new ErrorStatement(); - } - else if (!sc->sbreak) - { - if (sc->fes) -- { Statement *s; -- -+ { - // Replace break; with return 1; -- s = new ReturnStatement(0, new IntegerExp(1)); -+ Statement *s = new ReturnStatement(Loc(), new IntegerExp(1)); - return s; - } - error("break is not inside a loop or switch"); -+ return new ErrorStatement(); - } - return this; - } -@@ -4243,7 +4179,7 @@ Statement *ContinueStatement::semantic(S - if (ls && ls->ident == ident && ls->statement == sc->fes) - { - // Replace continue ident; with return 0; -- return new ReturnStatement(0, new IntegerExp(0)); -+ return new ReturnStatement(Loc(), new IntegerExp(0)); - } - } - -@@ -4254,9 +4190,8 @@ Statement *ContinueStatement::semantic(S - * Case numbers start with 2, not 0, as 0 is continue - * and 1 is break. - */ -- Statement *s; - sc->fes->cases->push(this); -- s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); -+ Statement *s = new ReturnStatement(Loc(), new IntegerExp(sc->fes->cases->dim + 1)); - return s; - } - break; // can't continue to it -@@ -4269,20 +4204,22 @@ Statement *ContinueStatement::semantic(S - - if (!s->hasContinue()) - error("label '%s' has no continue", ident->toChars()); -- if (ls->tf != sc->tf) -+ else if (ls->tf != sc->tf) - error("cannot continue out of finally block"); -- return this; -+ else -+ return this; -+ return new ErrorStatement(); - } - } - error("enclosing label '%s' for continue not found", ident->toChars()); -+ return new ErrorStatement(); - } - else if (!sc->scontinue) - { - if (sc->fes) -- { Statement *s; -- -+ { - // Replace continue; with return 0; -- s = new ReturnStatement(0, new IntegerExp(0)); -+ Statement *s = new ReturnStatement(Loc(), new IntegerExp(0)); - return s; - } - error("continue is not inside a loop"); -@@ -4342,7 +4279,10 @@ Statement *SynchronizedStatement::semant - goto Lbody; - ClassDeclaration *cd = exp->type->isClassHandle(); - if (!cd) -+ { - error("can only synchronize on class objects, not '%s'", exp->type->toChars()); -+ return new ErrorStatement(); -+ } - else if (cd->isInterfaceDeclaration()) - { /* Cast the interface to an object, as the object has the monitor, - * not the interface. -@@ -4354,7 +4294,7 @@ Statement *SynchronizedStatement::semant - } - - Type *t = ClassDeclaration::object->type; -- t = t->semantic(0, sc)->toBasetype(); -+ t = t->semantic(Loc(), sc)->toBasetype(); - assert(t->ty == Tclass); - - exp = new CastExp(loc, exp, t); -@@ -4374,12 +4314,15 @@ Statement *SynchronizedStatement::semant - Statements *cs = new Statements(); - cs->push(new ExpStatement(loc, tmp)); - -- FuncDeclaration *fdenter = FuncDeclaration::genCfunc(Type::tvoid, Id::monitorenter); -+ Parameters* args = new Parameters; -+ args->push(new Parameter(STCin, ClassDeclaration::object->type, NULL, NULL)); -+ -+ FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorenter); - Expression *e = new CallExp(loc, new VarExp(loc, fdenter), new VarExp(loc, tmp)); - e->type = Type::tvoid; // do not run semantic on e - cs->push(new ExpStatement(loc, e)); - -- FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::monitorexit); -+ FuncDeclaration *fdexit = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorexit); - e = new CallExp(loc, new VarExp(loc, fdexit), new VarExp(loc, tmp)); - e->type = Type::tvoid; // do not run semantic on e - Statement *s = new ExpStatement(loc, e); -@@ -4405,14 +4348,17 @@ Statement *SynchronizedStatement::semant - Statements *cs = new Statements(); - cs->push(new ExpStatement(loc, tmp)); - -- FuncDeclaration *fdenter = FuncDeclaration::genCfunc(Type::tvoid, Id::criticalenter); -+ Parameters* args = new Parameters; -+ args->push(new Parameter(STCin, t->pointerTo(), NULL, NULL)); -+ -+ FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::criticalenter); - Expression *e = new DotIdExp(loc, new VarExp(loc, tmp), Id::ptr); - e = e->semantic(sc); - e = new CallExp(loc, new VarExp(loc, fdenter), e); - e->type = Type::tvoid; // do not run semantic on e - cs->push(new ExpStatement(loc, e)); - -- FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::criticalexit); -+ FuncDeclaration *fdexit = FuncDeclaration::genCfunc(args, Type::tvoid, Id::criticalexit); - e = new DotIdExp(loc, new VarExp(loc, tmp), Id::ptr); - e = e->semantic(sc); - e = new CallExp(loc, new VarExp(loc, fdexit), e); -@@ -4428,6 +4374,8 @@ Statement *SynchronizedStatement::semant - Lbody: - if (body) - body = body->semantic(sc); -+ if (body && body->isErrorStatement()) -+ return body; - return this; - } - -@@ -4441,11 +4389,6 @@ bool SynchronizedStatement::hasContinue( - return FALSE; //TRUE; - } - --bool SynchronizedStatement::usesEH() --{ -- return TRUE; --} -- - int SynchronizedStatement::blockExit(bool mustNotThrow) - { - return body ? body->blockExit(mustNotThrow) : BEfallthru; -@@ -4491,7 +4434,7 @@ Statement *WithStatement::semantic(Scope - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); - if (exp->op == TOKerror) -- return NULL; -+ return new ErrorStatement(); - if (exp->op == TOKimport) - { ScopeExp *es = (ScopeExp *)exp; - -@@ -4504,13 +4447,21 @@ Statement *WithStatement::semantic(Scope - sym = s ? s->isScopeDsymbol() : NULL; - if (!sym) - { error("with type %s has no members", es->toChars()); -- if (body) -- body = body->semantic(sc); -- return this; -+ return new ErrorStatement(); - } - } - else -- { Type *t = exp->type; -+ { -+ Type *t = exp->type; -+ t = t->toBasetype(); -+ -+ Expression *olde = exp; -+ if (t->ty == Tpointer) -+ { -+ exp = new PtrExp(loc, exp); -+ exp = exp->semantic(sc); -+ t = exp->type->toBasetype(); -+ } - - assert(t); - t = t->toBasetype(); -@@ -4537,19 +4488,25 @@ Statement *WithStatement::semantic(Scope - wthis = new VarDeclaration(loc, e->type, Id::withSym, init); - wthis->semantic(sc); - sym = new WithScopeSymbol(this); -+ // Need to set the scope to make use of resolveAliasThis -+ sym->setScope(sc); - sym->parent = sc->scopesym; - } - else -- { error("with expressions must be aggregate types, not '%s'", exp->type->toChars()); -- return NULL; -+ { -+ error("with expressions must be aggregate types or pointers to them, not '%s'", olde->type->toChars()); -+ return new ErrorStatement(); - } - } -- sc = sc->push(sym); - - if (body) -+ { -+ sc = sc->push(sym); - body = body->semantic(sc); -- -- sc->pop(); -+ sc->pop(); -+ if (body && body->isErrorStatement()) -+ return body; -+ } - - return this; - } -@@ -4564,11 +4521,6 @@ void WithStatement::toCBuffer(OutBuffer - body->toCBuffer(buf, hgs); - } - --bool WithStatement::usesEH() --{ -- return body ? body->usesEH() : 0; --} -- - int WithStatement::blockExit(bool mustNotThrow) - { - int result = BEnone; -@@ -4608,12 +4560,20 @@ Statement *TryCatchStatement::syntaxCopy - Statement *TryCatchStatement::semantic(Scope *sc) - { - body = body->semanticScope(sc, NULL /*this*/, NULL); -+#ifdef IN_GCC -+ assert(body); -+#endif - - /* Even if body is NULL, still do semantic analysis on catches - */ -+ bool catchErrors = false; - for (size_t i = 0; i < catches->dim; i++) - { Catch *c = (*catches)[i]; - c->semantic(sc); -+ if (c->type->ty == Terror) -+ { catchErrors = true; -+ continue; -+ } - - // Determine if current catch 'hides' any previous catches - for (size_t j = 0; j < i; j++) -@@ -4622,27 +4582,25 @@ Statement *TryCatchStatement::semantic(S - char *sj = cj->loc.toChars(); - - if (c->type->toBasetype()->implicitConvTo(cj->type->toBasetype())) -- error("catch at %s hides catch at %s", sj, si); -- } -- } -- --#ifdef IN_GCC -- if (!body || body->isEmpty()) -- { -- for (size_t i = 0; i < catches->dim; i++) -- { -- Catch *c = (*catches)[i]; -- if (!c->handler || !c->handler->comeFrom()) - { -- catches->remove(i); -- --i; -+ error("catch at %s hides catch at %s", sj, si); -+ catchErrors = true; - } - } -- if (catches->dim == 0) -- return NULL; - } --#else -- if (!body || body->isEmpty()) -+ if (catchErrors) -+ return new ErrorStatement(); -+ -+#ifndef IN_GCC -+ if (!body) -+ return NULL; -+#endif -+ -+ if (body->isErrorStatement()) -+ return body; -+ -+#ifndef IN_GCC -+ if (!body->hasCode()) - { - return NULL; - } -@@ -4668,8 +4626,13 @@ Statement *TryCatchStatement::semantic(S - } - } - -+#ifdef IN_GCC -+ if (catches->dim == 0) -+ return (body->hasCode()) ? body : NULL; -+#else - if (catches->dim == 0) - return body; -+#endif - - return this; - } -@@ -4679,11 +4642,6 @@ bool TryCatchStatement::hasBreak() - return FALSE; - } - --bool TryCatchStatement::usesEH() --{ -- return TRUE; --} -- - int TryCatchStatement::blockExit(bool mustNotThrow) - { - assert(body); -@@ -4701,7 +4659,11 @@ int TryCatchStatement::blockExit(bool mu - /* If we're catching Object, then there is no throwing - */ - Identifier *id = c->type->toBasetype()->isClassHandle()->ident; -- if (id == Id::Object || id == Id::Throwable || id == Id::Exception) -+ if (id == Id::Object || id == Id::Throwable) -+ { -+ result &= ~(BEthrow | BEerrthrow); -+ } -+ if (id == Id::Exception) - { - result &= ~BEthrow; - } -@@ -4752,9 +4714,6 @@ Catch *Catch::syntaxCopy() - - void Catch::semantic(Scope *sc) - { -- if (type && type->deco) -- return; -- - //printf("Catch::semantic(%s)\n", ident->toChars()); - - #ifndef IN_GCC -@@ -4775,7 +4734,7 @@ void Catch::semantic(Scope *sc) - sc = sc->push(sym); - - if (!type) -- type = new TypeIdentifier(0, Id::Throwable); -+ type = new TypeIdentifier(Loc(), Id::Throwable); - type = type->semantic(loc, sc); - ClassDeclaration *cd = type->toBasetype()->isClassHandle(); - if (!cd || ((cd != ClassDeclaration::throwable) && !ClassDeclaration::throwable->isBaseOf(cd, NULL))) -@@ -4798,7 +4757,7 @@ void Catch::semantic(Scope *sc) - else if (ident) - { - var = new VarDeclaration(loc, type, ident, NULL); -- var->parent = sc->parent; -+ var->semantic(sc); - sc->insert(var); - } - handler = handler->semantic(sc); -@@ -4899,11 +4858,6 @@ bool TryFinallyStatement::hasContinue() - return FALSE; //TRUE; - } - --bool TryFinallyStatement::usesEH() --{ -- return TRUE; --} -- - int TryFinallyStatement::blockExit(bool mustNotThrow) - { - int result = BEfallthru; -@@ -4955,11 +4909,6 @@ void OnScopeStatement::toCBuffer(OutBuff - statement->toCBuffer(buf, hgs); - } - --bool OnScopeStatement::usesEH() --{ -- return 1; --} -- - Statement *OnScopeStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) - { - //printf("OnScopeStatement::scopeCode()\n"); -@@ -4986,17 +4935,17 @@ Statement *OnScopeStatement::scopeCode(S - */ - Identifier *id = Lexer::uniqueId("__os"); - -- ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(0, 0, Type::tbool)); -+ ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(Loc(), 0, Type::tbool)); - VarDeclaration *v = new VarDeclaration(loc, Type::tbool, id, ie); - *sentry = new ExpStatement(loc, v); - -- Expression *e = new IntegerExp(0, 1, Type::tbool); -- e = new AssignExp(0, new VarExp(0, v), e); -- *sexception = new ExpStatement(0, e); -- -- e = new VarExp(0, v); -- e = new NotExp(0, e); -- *sfinally = new IfStatement(0, NULL, e, statement, NULL); -+ Expression *e = new IntegerExp(Loc(), 1, Type::tbool); -+ e = new AssignExp(Loc(), new VarExp(Loc(), v), e); -+ *sexception = new ExpStatement(Loc(), e); -+ -+ e = new VarExp(Loc(), v); -+ e = new NotExp(Loc(), e); -+ *sfinally = new IfStatement(Loc(), NULL, e, statement, NULL); - - break; - } -@@ -5038,10 +4987,13 @@ Statement *ThrowStatement::semantic(Scop - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); - if (exp->op == TOKerror) -- return this; -+ return new ErrorStatement(); - ClassDeclaration *cd = exp->type->toBasetype()->isClassHandle(); - if (!cd || ((cd != ClassDeclaration::throwable) && !ClassDeclaration::throwable->isBaseOf(cd, NULL))) -+ { - error("can only throw class objects derived from Throwable, not type %s", exp->type->toChars()); -+ return new ErrorStatement(); -+ } - - return this; - } -@@ -5049,18 +5001,19 @@ Statement *ThrowStatement::semantic(Scop - int ThrowStatement::blockExit(bool mustNotThrow) - { - Type *t = exp->type->toBasetype(); -- if (mustNotThrow && t->ty != Terror) -- { -- ClassDeclaration *cd = t->isClassHandle(); -- assert(cd); -+ ClassDeclaration *cd = t->isClassHandle(); -+ assert(cd); - -- // Bugzilla 8675 -- // Throwing Errors is allowed even if mustNotThrow -- if (!internalThrow && -- cd != ClassDeclaration::errorException && -- !ClassDeclaration::errorException->isBaseOf(cd, NULL)) -- error("%s is thrown but not caught", exp->type->toChars()); -+ if (cd == ClassDeclaration::errorException || -+ ClassDeclaration::errorException->isBaseOf(cd, NULL)) -+ { -+ return BEerrthrow; - } -+ // Bugzilla 8675 -+ // Throwing Errors is allowed even if mustNotThrow -+ if (!internalThrow && mustNotThrow) -+ error("%s is thrown but not caught", exp->type->toChars()); -+ - return BEthrow; - } - -@@ -5165,7 +5118,10 @@ Statement *GotoStatement::semantic(Scope - return s; - } - if (label->statement && label->statement->tf != sc->tf) -+ { - error("cannot goto in or out of finally block"); -+ return new ErrorStatement(); -+ } - return this; - } - -@@ -5192,6 +5148,7 @@ LabelStatement::LabelStatement(Loc loc, - this->ident = ident; - this->statement = statement; - this->tf = NULL; -+ this->gotoTarget = NULL; - this->lblock = NULL; - this->fwdrefs = NULL; - } -@@ -5211,13 +5168,22 @@ Statement *LabelStatement::semantic(Scop - - ls = fd->searchLabel(ident); - if (ls->statement) -+ { - error("Label '%s' already defined", ls->toChars()); -+ return new ErrorStatement(); -+ } - else - ls->statement = this; - tf = sc->tf; - sc = sc->push(); - sc->scopesym = sc->enclosing->scopesym; - sc->callSuper |= CSXlabel; -+ if (sc->fieldinit) -+ { -+ size_t dim = sc->fieldinit_dim; -+ for (size_t i = 0; i < dim; i++) -+ sc->fieldinit[i] |= CSXlabel; -+ } - sc->slabel = this; - if (statement) - statement = statement->semanticNoScope(sc); -@@ -5249,11 +5215,6 @@ Statements *LabelStatement::flatten(Scop - } - - --bool LabelStatement::usesEH() --{ -- return statement ? statement->usesEH() : FALSE; --} -- - int LabelStatement::blockExit(bool mustNotThrow) - { - //printf("LabelStatement::blockExit(%p)\n", this); -@@ -5261,12 +5222,6 @@ int LabelStatement::blockExit(bool mustN - } - - --int LabelStatement::comeFrom() --{ -- //printf("LabelStatement::comeFrom()\n"); -- return TRUE; --} -- - void LabelStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - buf->writestring(ident->toChars()); -@@ -5310,12 +5265,6 @@ Statement *AsmStatement::syntaxCopy() - } - - -- --int AsmStatement::comeFrom() --{ -- return TRUE; --} -- - int AsmStatement::blockExit(bool mustNotThrow) - { - if (mustNotThrow) -@@ -5388,6 +5337,7 @@ Statement *ImportStatement::semantic(Sco - - TypeIdentifier *tname = new TypeIdentifier(s->loc, name); - AliasDeclaration *ad = new AliasDeclaration(s->loc, alias, tname); -+ ad->import = s; - - s->aliasdecls.push(ad); - } -@@ -5409,11 +5359,6 @@ int ImportStatement::blockExit(bool must - return BEfallthru; - } - --int ImportStatement::isEmpty() --{ -- return TRUE; --} -- - void ImportStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) - { - for (size_t i = 0; i < imports->dim; i++) ---- a/src/gcc/d/dfrontend/statement.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/statement.h 2014-04-01 16:32:51.000000000 +0100 -@@ -23,36 +23,40 @@ - - struct OutBuffer; - struct Scope; --struct Expression; --struct LabelDsymbol; --struct Identifier; --struct IfStatement; --struct ExpStatement; --struct DefaultStatement; --struct VarDeclaration; --struct Condition; --struct Module; -+class Expression; -+class LabelDsymbol; -+class Identifier; -+class IfStatement; -+class ExpStatement; -+class DefaultStatement; -+class VarDeclaration; -+class Condition; -+class Module; - struct Token; - struct InlineCostState; - struct InlineDoState; - struct InlineScanState; --struct ReturnStatement; --struct CompoundStatement; --struct Parameter; --struct StaticAssert; --struct AsmStatement; --struct GotoStatement; --struct ScopeStatement; --struct TryCatchStatement; --struct TryFinallyStatement; --struct CaseStatement; --struct DefaultStatement; --struct LabelStatement; -+class ErrorStatement; -+class ReturnStatement; -+class CompoundStatement; -+class Parameter; -+class StaticAssert; -+class AsmStatement; -+class GotoStatement; -+class ScopeStatement; -+class TryCatchStatement; -+class TryFinallyStatement; -+class CaseStatement; -+class DefaultStatement; -+class LabelStatement; - struct HdrGenState; - struct InterState; -+struct CompiledCtfeFunction; - - enum TOK; - -+typedef bool (*sapply_fp_t)(Statement *, void *); -+ - // Back end - struct IRState; - struct Blockx; -@@ -77,11 +81,13 @@ enum BE - BEhalt = 0x10, - BEbreak = 0x20, - BEcontinue = 0x40, -+ BEerrthrow = 0x80, - BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt), - }; - --struct Statement : Object -+class Statement : public RootObject - { -+public: - Loc loc; - - Statement(Loc loc); -@@ -94,20 +100,24 @@ struct Statement : Object - void warning(const char *format, ...); - void deprecation(const char *format, ...); - virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- virtual ScopeStatement *isScopeStatement() { return NULL; } - virtual Statement *semantic(Scope *sc); - Statement *semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue); - Statement *semanticNoScope(Scope *sc); - virtual Statement *getRelatedLabeled() { return this; } - virtual bool hasBreak(); - virtual bool hasContinue(); -- virtual bool usesEH(); -+ bool usesEH(); -+ virtual bool usesEHimpl(); - virtual int blockExit(bool mustNotThrow); -- virtual int comeFrom(); -- virtual int isEmpty(); -+ bool comeFrom(); -+ virtual bool comeFromImpl(); -+ bool hasCode(); -+ virtual bool hasCodeImpl(); - virtual Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - virtual Statements *flatten(Scope *sc); - virtual Expression *interpret(InterState *istate); -+ virtual bool apply(sapply_fp_t fp, void *param); -+ virtual void ctfeCompile(CompiledCtfeFunction *ccf); - virtual Statement *last(); - - virtual int inlineCost(InlineCostState *ics); -@@ -119,6 +129,8 @@ struct Statement : Object - virtual void toIR(IRState *irs); - - // Avoid dynamic_cast -+ virtual ErrorStatement *isErrorStatement() { return NULL; } -+ virtual ScopeStatement *isScopeStatement() { return NULL; } - virtual ExpStatement *isExpStatement() { return NULL; } - virtual CompoundStatement *isCompoundStatement() { return NULL; } - virtual ReturnStatement *isReturnStatement() { return NULL; } -@@ -128,16 +140,33 @@ struct Statement : Object - virtual LabelStatement *isLabelStatement() { return NULL; } - }; - --struct PeelStatement : Statement -+/** Any Statement that fails semantic() or has a component that is an ErrorExp or -+ * a TypeError should return an ErrorStatement from semantic(). -+ */ -+class ErrorStatement : public Statement - { -+public: -+ ErrorStatement(); -+ Statement *syntaxCopy(); -+ Statement *semantic(Scope *sc); -+ int blockExit(bool mustNotThrow); -+ -+ ErrorStatement *isErrorStatement() { return this; } -+}; -+ -+class PeelStatement : public Statement -+{ -+public: - Statement *s; - - PeelStatement(Statement *s); - Statement *semantic(Scope *sc); -+ bool apply(sapply_fp_t fp, void *param); - }; - --struct ExpStatement : Statement -+class ExpStatement : public Statement - { -+public: - Expression *exp; - - ExpStatement(Loc loc, Expression *exp); -@@ -146,8 +175,9 @@ struct ExpStatement : Statement - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - Statement *semantic(Scope *sc); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - int blockExit(bool mustNotThrow); -- int isEmpty(); -+ bool hasCodeImpl(); - Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - - int inlineCost(InlineCostState *ics); -@@ -160,8 +190,9 @@ struct ExpStatement : Statement - ExpStatement *isExpStatement() { return this; } - }; - --struct DtorExpStatement : ExpStatement -+class DtorExpStatement : public ExpStatement - { -+public: - /* Wraps an expression that is the destruction of 'var' - */ - -@@ -172,8 +203,9 @@ struct DtorExpStatement : ExpStatement - void toIR(IRState *irs); - }; - --struct CompileStatement : Statement -+class CompileStatement : public Statement - { -+public: - Expression *exp; - - CompileStatement(Loc loc, Expression *exp); -@@ -184,8 +216,9 @@ struct CompileStatement : Statement - int blockExit(bool mustNotThrow); - }; - --struct CompoundStatement : Statement -+class CompoundStatement : public Statement - { -+public: - Statements *statements; - - CompoundStatement(Loc loc, Statements *s); -@@ -194,13 +227,13 @@ struct CompoundStatement : Statement - Statement *syntaxCopy(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - Statement *semantic(Scope *sc); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); -- int isEmpty(); -+ bool hasCodeImpl(); - Statements *flatten(Scope *sc); - ReturnStatement *isReturnStatement(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - Statement *last(); - - int inlineCost(InlineCostState *ics); -@@ -213,8 +246,9 @@ struct CompoundStatement : Statement - CompoundStatement *isCompoundStatement() { return this; } - }; - --struct CompoundDeclarationStatement : CompoundStatement -+class CompoundDeclarationStatement : public CompoundStatement - { -+public: - CompoundDeclarationStatement(Loc loc, Statements *s); - Statement *syntaxCopy(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -223,8 +257,9 @@ struct CompoundDeclarationStatement : Co - /* The purpose of this is so that continue will go to the next - * of the statements, and break will go to the end of the statements. - */ --struct UnrolledLoopStatement : Statement -+class UnrolledLoopStatement : public Statement - { -+public: - Statements *statements; - - UnrolledLoopStatement(Loc loc, Statements *statements); -@@ -232,10 +267,10 @@ struct UnrolledLoopStatement : Statement - Statement *semantic(Scope *sc); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - int inlineCost(InlineCostState *ics); -@@ -246,8 +281,9 @@ struct UnrolledLoopStatement : Statement - void toIR(IRState *irs); - }; - --struct ScopeStatement : Statement -+class ScopeStatement : public Statement - { -+public: - Statement *statement; - - ScopeStatement(Loc loc, Statement *s); -@@ -257,11 +293,11 @@ struct ScopeStatement : Statement - Statement *semantic(Scope *sc); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); -- int isEmpty(); -+ bool hasCodeImpl(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - int inlineCost(InlineCostState *ics); - Expression *doInline(InlineDoState *ids); -@@ -271,8 +307,9 @@ struct ScopeStatement : Statement - void toIR(IRState *irs); - }; - --struct WhileStatement : Statement -+class WhileStatement : public Statement - { -+public: - Expression *condition; - Statement *body; - -@@ -281,10 +318,10 @@ struct WhileStatement : Statement - Statement *semantic(Scope *sc); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - Statement *inlineScan(InlineScanState *iss); -@@ -292,8 +329,9 @@ struct WhileStatement : Statement - void toIR(IRState *irs); - }; - --struct DoStatement : Statement -+class DoStatement : public Statement - { -+public: - Statement *body; - Expression *condition; - -@@ -302,10 +340,10 @@ struct DoStatement : Statement - Statement *semantic(Scope *sc); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - Statement *inlineScan(InlineScanState *iss); -@@ -313,13 +351,13 @@ struct DoStatement : Statement - void toIR(IRState *irs); - }; - --struct ForStatement : Statement -+class ForStatement : public Statement - { -+public: - Statement *init; - Expression *condition; - Expression *increment; - Statement *body; -- int nest; - - // When wrapped in try/finally clauses, this points to the outermost one, - // which may have an associated label. Internal break/continue statements -@@ -328,16 +366,15 @@ struct ForStatement : Statement - - ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body); - Statement *syntaxCopy(); -- Statement *semanticInit(Scope *sc); - Statement *semantic(Scope *sc); - Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; } - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - int inlineCost(InlineCostState *ics); -@@ -347,9 +384,10 @@ struct ForStatement : Statement - void toIR(IRState *irs); - }; - --struct ForeachStatement : Statement -+class ForeachStatement : public Statement - { -- enum TOK op; // TOKforeach or TOKforeach_reverse -+public: -+ TOK op; // TOKforeach or TOKforeach_reverse - Parameters *arguments; // array of Parameter*'s - Expression *aggr; - Statement *body; -@@ -362,7 +400,7 @@ struct ForeachStatement : Statement - Statements *cases; // put breaks, continues, gotos and returns here - CompoundStatements *gotos; // forward referenced goto's go here - -- ForeachStatement(Loc loc, enum TOK op, Parameters *arguments, Expression *aggr, Statement *body); -+ ForeachStatement(Loc loc, TOK op, Parameters *arguments, Expression *aggr, Statement *body); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - bool checkForArgTypes(); -@@ -370,10 +408,10 @@ struct ForeachStatement : Statement - int inferApplyArgTypes(Scope *sc, Dsymbol *&sapply); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - Statement *inlineScan(InlineScanState *iss); -@@ -382,9 +420,10 @@ struct ForeachStatement : Statement - }; - - #if DMDV2 --struct ForeachRangeStatement : Statement -+class ForeachRangeStatement : public Statement - { -- enum TOK op; // TOKforeach or TOKforeach_reverse -+public: -+ TOK op; // TOKforeach or TOKforeach_reverse - Parameter *arg; // loop index variable - Expression *lwr; - Expression *upr; -@@ -392,16 +431,16 @@ struct ForeachRangeStatement : Statement - - VarDeclaration *key; - -- ForeachRangeStatement(Loc loc, enum TOK op, Parameter *arg, -+ ForeachRangeStatement(Loc loc, TOK op, Parameter *arg, - Expression *lwr, Expression *upr, Statement *body); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - Statement *inlineScan(InlineScanState *iss); -@@ -410,8 +449,9 @@ struct ForeachRangeStatement : Statement - }; - #endif - --struct IfStatement : Statement -+class IfStatement : public Statement - { -+public: - Parameter *arg; - Expression *condition; - Statement *ifbody; -@@ -423,8 +463,9 @@ struct IfStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- bool usesEH(); - int blockExit(bool mustNotThrow); - IfStatement *isIfStatement() { return this; } - -@@ -436,8 +477,9 @@ struct IfStatement : Statement - void toIR(IRState *irs); - }; - --struct ConditionalStatement : Statement -+class ConditionalStatement : public Statement - { -+public: - Condition *condition; - Statement *ifbody; - Statement *elsebody; -@@ -446,14 +488,15 @@ struct ConditionalStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Statements *flatten(Scope *sc); -- bool usesEH(); - int blockExit(bool mustNotThrow); -+ bool apply(sapply_fp_t fp, void *param); - - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct PragmaStatement : Statement -+class PragmaStatement : public Statement - { -+public: - Identifier *ident; - Expressions *args; // array of Expression's - Statement *body; -@@ -461,16 +504,17 @@ struct PragmaStatement : Statement - PragmaStatement(Loc loc, Identifier *ident, Expressions *args, Statement *body); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); -- bool usesEH(); - int blockExit(bool mustNotThrow); -+ bool apply(sapply_fp_t fp, void *param); - - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - void toIR(IRState *irs); - }; - --struct StaticAssertStatement : Statement -+class StaticAssertStatement : public Statement - { -+public: - StaticAssert *sa; - - StaticAssertStatement(StaticAssert *sa); -@@ -481,8 +525,9 @@ struct StaticAssertStatement : Statement - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct SwitchStatement : Statement -+class SwitchStatement : public Statement - { -+public: - Expression *condition; - Statement *body; - bool isFinal; -@@ -498,9 +543,10 @@ struct SwitchStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - bool hasBreak(); -- bool usesEH(); - int blockExit(bool mustNotThrow); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - Statement *inlineScan(InlineScanState *iss); -@@ -508,8 +554,9 @@ struct SwitchStatement : Statement - void toIR(IRState *irs); - }; - --struct CaseStatement : Statement -+class CaseStatement : public Statement - { -+public: - Expression *exp; - Statement *statement; - -@@ -519,11 +566,12 @@ struct CaseStatement : Statement - CaseStatement(Loc loc, Expression *exp, Statement *s); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); -- int compare(Object *obj); -- bool usesEH(); -+ int compare(RootObject *obj); - int blockExit(bool mustNotThrow); -- int comeFrom(); -+ bool comeFromImpl(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - CaseStatement *isCaseStatement() { return this; } - -@@ -534,8 +582,9 @@ struct CaseStatement : Statement - - #if DMDV2 - --struct CaseRangeStatement : Statement -+class CaseRangeStatement : public Statement - { -+public: - Expression *first; - Expression *last; - Statement *statement; -@@ -543,13 +592,15 @@ struct CaseRangeStatement : Statement - CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); -+ bool apply(sapply_fp_t fp, void *param); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - - #endif - --struct DefaultStatement : Statement -+class DefaultStatement : public Statement - { -+public: - Statement *statement; - #ifdef IN_GCC - block *cblock; // back end: label for the block -@@ -558,10 +609,11 @@ struct DefaultStatement : Statement - DefaultStatement(Loc loc, Statement *s); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); -+ bool comeFromImpl(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - DefaultStatement *isDefaultStatement() { return this; } - -@@ -570,22 +622,25 @@ struct DefaultStatement : Statement - void toIR(IRState *irs); - }; - --struct GotoDefaultStatement : Statement -+class GotoDefaultStatement : public Statement - { -+public: - SwitchStatement *sw; - - GotoDefaultStatement(Loc loc); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - int blockExit(bool mustNotThrow); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - void toIR(IRState *irs); - }; - --struct GotoCaseStatement : Statement -+class GotoCaseStatement : public Statement - { -+public: - Expression *exp; // NULL, or which case to goto - CaseStatement *cs; // case statement it resolves to - -@@ -593,23 +648,27 @@ struct GotoCaseStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - int blockExit(bool mustNotThrow); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - void toIR(IRState *irs); - }; - --struct SwitchErrorStatement : Statement -+class SwitchErrorStatement : public Statement - { -+public: - SwitchErrorStatement(Loc loc); - int blockExit(bool mustNotThrow); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - void toIR(IRState *irs); - }; - --struct ReturnStatement : Statement -+class ReturnStatement : public Statement - { -+public: - Expression *exp; - bool implicit0; // this is an implicit "return 0;" - -@@ -619,6 +678,7 @@ struct ReturnStatement : Statement - Statement *semantic(Scope *sc); - int blockExit(bool mustNotThrow); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - int inlineCost(InlineCostState *ics); - Expression *doInline(InlineDoState *ids); -@@ -630,36 +690,41 @@ struct ReturnStatement : Statement - ReturnStatement *isReturnStatement() { return this; } - }; - --struct BreakStatement : Statement -+class BreakStatement : public Statement - { -+public: - Identifier *ident; - - BreakStatement(Loc loc, Identifier *ident); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - int blockExit(bool mustNotThrow); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - void toIR(IRState *irs); - }; - --struct ContinueStatement : Statement -+class ContinueStatement : public Statement - { -+public: - Identifier *ident; - - ContinueStatement(Loc loc, Identifier *ident); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - int blockExit(bool mustNotThrow); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - void toIR(IRState *irs); - }; - --struct SynchronizedStatement : Statement -+class SynchronizedStatement : public Statement - { -+public: - Expression *exp; - Statement *body; - -@@ -668,8 +733,9 @@ struct SynchronizedStatement : Statement - Statement *semantic(Scope *sc); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); -+ bool usesEHimpl(); - int blockExit(bool mustNotThrow); -+ bool apply(sapply_fp_t fp, void *param); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - Statement *inlineScan(InlineScanState *iss); -@@ -680,8 +746,9 @@ struct SynchronizedStatement : Statement - void toIR(IRState *irs); - }; - --struct WithStatement : Statement -+class WithStatement : public Statement - { -+public: - Expression *exp; - Statement *body; - VarDeclaration *wthis; -@@ -690,17 +757,19 @@ struct WithStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- bool usesEH(); - int blockExit(bool mustNotThrow); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - Statement *inlineScan(InlineScanState *iss); - - void toIR(IRState *irs); - }; - --struct TryCatchStatement : Statement -+class TryCatchStatement : public Statement - { -+public: - Statement *body; - Catches *catches; - -@@ -708,9 +777,11 @@ struct TryCatchStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - bool hasBreak(); -- bool usesEH(); -+ bool usesEHimpl(); - int blockExit(bool mustNotThrow); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - Statement *inlineScan(InlineScanState *iss); - -@@ -718,8 +789,9 @@ struct TryCatchStatement : Statement - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct Catch : Object -+class Catch : public RootObject - { -+public: - Loc loc; - Type *type; - Identifier *ident; -@@ -735,8 +807,9 @@ struct Catch : Object - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct TryFinallyStatement : Statement -+class TryFinallyStatement : public Statement - { -+public: - Statement *body; - Statement *finalbody; - -@@ -746,17 +819,20 @@ struct TryFinallyStatement : Statement - Statement *semantic(Scope *sc); - bool hasBreak(); - bool hasContinue(); -- bool usesEH(); -+ bool usesEHimpl(); - int blockExit(bool mustNotThrow); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - Statement *inlineScan(InlineScanState *iss); - - void toIR(IRState *irs); - }; - --struct OnScopeStatement : Statement -+class OnScopeStatement : public Statement - { -+public: - TOK tok; - Statement *statement; - -@@ -765,15 +841,18 @@ struct OnScopeStatement : Statement - int blockExit(bool mustNotThrow); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - Statement *semantic(Scope *sc); -- bool usesEH(); -+ bool usesEHimpl(); - Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - void toIR(IRState *irs); - }; - --struct ThrowStatement : Statement -+class ThrowStatement : public Statement - { -+public: - Expression *exp; - bool internalThrow; // was generated by the compiler, - // wasn't present in source code -@@ -784,25 +863,29 @@ struct ThrowStatement : Statement - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - int blockExit(bool mustNotThrow); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - Statement *inlineScan(InlineScanState *iss); - - void toIR(IRState *irs); - }; - --struct DebugStatement : Statement -+class DebugStatement : public Statement - { -+public: - Statement *statement; - - DebugStatement(Loc loc, Statement *statement); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Statements *flatten(Scope *sc); -+ bool apply(sapply_fp_t fp, void *param); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct GotoStatement : Statement -+class GotoStatement : public Statement - { -+public: - Identifier *ident; - LabelDsymbol *label; - TryFinallyStatement *tf; -@@ -812,16 +895,19 @@ struct GotoStatement : Statement - Statement *semantic(Scope *sc); - int blockExit(bool mustNotThrow); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - void toIR(IRState *irs); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - }; - --struct LabelStatement : Statement -+class LabelStatement : public Statement - { -+public: - Identifier *ident; - Statement *statement; - TryFinallyStatement *tf; -+ Statement *gotoTarget; // interpret - block *lblock; // back end - - Blocks *fwdrefs; // forward references to this LabelStatement -@@ -830,10 +916,11 @@ struct LabelStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - Statements *flatten(Scope *sc); -- bool usesEH(); - int blockExit(bool mustNotThrow); -- int comeFrom(); -+ bool comeFromImpl(); - Expression *interpret(InterState *istate); -+ bool apply(sapply_fp_t fp, void *param); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - - Statement *inlineScan(InlineScanState *iss); -@@ -842,16 +929,18 @@ struct LabelStatement : Statement - void toIR(IRState *irs); - }; - --struct LabelDsymbol : Dsymbol -+class LabelDsymbol : public Dsymbol - { -+public: - LabelStatement *statement; - - LabelDsymbol(Identifier *ident); - LabelDsymbol *isLabel(); - }; - --struct AsmStatement : Statement -+class AsmStatement : public Statement - { -+public: - Token *tokens; - code *asmcode; - unsigned asmalign; // alignment of this statement -@@ -863,8 +952,9 @@ struct AsmStatement : Statement - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - int blockExit(bool mustNotThrow); -- int comeFrom(); -+ bool comeFromImpl(); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - -@@ -875,16 +965,18 @@ struct AsmStatement : Statement - void toIR(IRState *irs); - }; - --struct ImportStatement : Statement -+class ImportStatement : public Statement - { -+public: - Dsymbols *imports; // Array of Import's - - ImportStatement(Loc loc, Dsymbols *imports); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - int blockExit(bool mustNotThrow); -- int isEmpty(); -+ bool hasCodeImpl(); - Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - -@@ -898,22 +990,25 @@ struct ImportStatement : Statement - #ifdef IN_GCC - - // Assembler instructions with D expression operands --struct ExtAsmStatement : Statement -+class ExtAsmStatement : public Statement - { -+public: - Expression *insn; - Expressions *args; - Identifiers *names; // of NULL or Identifier* - Expressions *constraints; // of StringExp* - unsigned outputargs; - Expressions *clobbers; // of StringExp* -- Dsymbols *labels; // of LabelDsymbol* - -- ExtAsmStatement(Loc loc, Expression *insn, Expressions *args, Identifiers *names, -- Expressions *constraints, int outputargs, Expressions *clobbers, Dsymbols *labels); -+ ExtAsmStatement(Loc loc, Expression *insn, Expressions *args, -+ Identifiers *names, Expressions *constraints, -+ int outputargs, Expressions *clobbers); - Statement *syntaxCopy(); - Statement *semantic(Scope *sc); - int blockExit(bool mustNotThrow); -- int comeFrom(); -+ bool comeFromImpl(); -+ Expression *interpret(InterState *istate); -+ void ctfeCompile(CompiledCtfeFunction *ccf); - - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - ---- a/src/gcc/d/dfrontend/staticassert.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/staticassert.c 2014-04-01 16:32:51.000000000 +0100 -@@ -55,9 +55,16 @@ void StaticAssert::semantic2(Scope *sc) - ScopeDsymbol *sd = new ScopeDsymbol(); - sc = sc->push(sd); - sc->flags |= SCOPEstaticassert; -+ -+ sc = sc->startCTFE(); - Expression *e = exp->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); - sc = sc->pop(); -+ -+ // Simplify expression, to make error messages nicer if CTFE fails -+ e = e->optimize(0); -+ - if (!e->type->checkBoolean()) - { - if (e->type->toBasetype() != Type::terror) -@@ -73,11 +80,14 @@ void StaticAssert::semantic2(Scope *sc) - else if (e->isBool(FALSE)) - { - if (msg) -- { HdrGenState hgs; -+ { -+ HdrGenState hgs; - OutBuffer buf; - -+ sc = sc->startCTFE(); - msg = msg->semantic(sc); - msg = resolveProperties(sc, msg); -+ sc = sc->endCTFE(); - msg = msg->ctfeInterpret(); - hgs.console = 1; - StringExp * s = msg->toString(); -@@ -101,11 +111,11 @@ void StaticAssert::semantic2(Scope *sc) - } - } - --int StaticAssert::oneMember(Dsymbol **ps, Identifier *ident) -+bool StaticAssert::oneMember(Dsymbol **ps, Identifier *ident) - { - //printf("StaticAssert::oneMember())\n"); - *ps = NULL; -- return TRUE; -+ return true; - } - - void StaticAssert::inlineScan() -@@ -128,7 +138,7 @@ void StaticAssert::toCBuffer(OutBuffer * - exp->toCBuffer(buf, hgs); - if (msg) - { -- buf->writeByte(','); -+ buf->writestring(", "); - msg->toCBuffer(buf, hgs); - } - buf->writestring(");"); ---- a/src/gcc/d/dfrontend/staticassert.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/staticassert.h 2014-04-01 16:32:51.000000000 +0100 -@@ -17,11 +17,12 @@ - - #include "dsymbol.h" - --struct Expression; -+class Expression; - struct HdrGenState; - --struct StaticAssert : Dsymbol -+class StaticAssert : public Dsymbol - { -+public: - Expression *exp; - Expression *msg; - -@@ -32,7 +33,7 @@ struct StaticAssert : Dsymbol - void semantic(Scope *sc); - void semantic2(Scope *sc); - void inlineScan(); -- int oneMember(Dsymbol **ps, Identifier *ident); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - void toObjFile(int multiobj); - const char *kind(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); ---- a/src/gcc/d/dfrontend/stringtable.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/stringtable.c 2014-04-01 16:32:51.000000000 +0100 -@@ -22,6 +22,13 @@ hash_t calcHash(const char *str, size_t - { - hash_t hash = 0; - -+ union -+ { -+ uint8_t scratchB[4]; -+ uint16_t scratchS[2]; -+ uint32_t scratchI; -+ }; -+ - while (1) - { - switch (len) -@@ -36,18 +43,26 @@ hash_t calcHash(const char *str, size_t - - case 2: - hash *= 37; -- hash += *(const uint16_t *)str; -+ scratchB[0] = str[0]; -+ scratchB[1] = str[1]; -+ hash += scratchS[0]; - return hash; - - case 3: - hash *= 37; -- hash += (*(const uint16_t *)str << 8) + -+ scratchB[0] = str[0]; -+ scratchB[1] = str[1]; -+ hash += (scratchS[0] << 8) + - ((const uint8_t *)str)[2]; - return hash; - - default: - hash *= 37; -- hash += *(const uint32_t *)str; -+ scratchB[0] = str[0]; -+ scratchB[1] = str[1]; -+ scratchB[2] = str[2]; -+ scratchB[3] = str[3]; -+ hash += scratchI; - str += 4; - len -= 4; - break; -@@ -62,7 +77,7 @@ void StringValue::ctor(const char *p, si - memcpy(this->lstring, p, length * sizeof(char)); - } - --void StringTable::init(size_t size) -+void StringTable::_init(size_t size) - { - table = (void **)mem.calloc(size, sizeof(void *)); - tabledim = size; ---- a/src/gcc/d/dfrontend/stringtable.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/stringtable.h 2014-04-01 16:32:51.000000000 +0100 -@@ -24,11 +24,7 @@ struct StringEntry; - // method because the only thing which should be creating these is StringTable. - struct StringValue - { -- union -- { -- void *ptrvalue; -- char *string; -- }; -+ void *ptrvalue; - private: - size_t length; - -@@ -57,7 +53,7 @@ private: - size_t tabledim; - - public: -- void init(size_t size = 37); -+ void _init(size_t size = 37); - ~StringTable(); - - StringValue *lookup(const char *s, size_t len); ---- a/src/gcc/d/dfrontend/struct.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/struct.c 2014-04-01 16:32:51.000000000 +0100 -@@ -22,6 +22,75 @@ - #include "template.h" - - FuncDeclaration *StructDeclaration::xerreq; // object.xopEquals -+FuncDeclaration *StructDeclaration::xerrcmp; // object.xopCmp -+ -+bool inNonRoot(Dsymbol *s) -+{ -+ if (!s || !s->parent) -+ return false; -+ s = s->parent; -+ for (; s; s = s->parent) -+ { -+ if (TemplateInstance *ti = s->isTemplateInstance()) -+ { -+ if (!ti->instantiatingModule || !ti->instantiatingModule->isRoot()) -+ return true; -+ return false; -+ } -+ else if (Module *m = s->isModule()) -+ { -+ if (!m->isRoot()) -+ return true; -+ break; -+ } -+ } -+ return false; -+} -+ -+/*************************************** -+ * Search toHash member function for TypeInfo_Struct. -+ * const hash_t toHash(); -+ */ -+FuncDeclaration *search_toHash(StructDeclaration *sd) -+{ -+ Dsymbol *s = search_function(sd, Id::tohash); -+ FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL; -+ if (fd) -+ { -+ static TypeFunction *tftohash; -+ if (!tftohash) -+ { -+ tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd); -+ tftohash->mod = MODconst; -+ tftohash = (TypeFunction *)tftohash->merge(); -+ } -+ -+ fd = fd->overloadExactMatch(tftohash); -+ } -+ return fd; -+} -+ -+/*************************************** -+ * Search toString member function for TypeInfo_Struct. -+ * string toString(); -+ */ -+FuncDeclaration *search_toString(StructDeclaration *sd) -+{ -+ Dsymbol *s = search_function(sd, Id::tostring); -+ FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL; -+ if (fd) -+ { -+ static TypeFunction *tftostring; -+ if (!tftostring) -+ { -+ tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd); -+ tftostring = (TypeFunction *)tftostring->merge(); -+ } -+ -+ fd = fd->overloadExactMatch(tftostring); -+ } -+ return fd; -+} - - /********************************* AggregateDeclaration ****************************/ - -@@ -46,7 +115,7 @@ AggregateDeclaration::AggregateDeclarati - - stag = NULL; - sinit = NULL; -- isnested = false; -+ enclosing = NULL; - vthis = NULL; - - #if DMDV2 -@@ -59,7 +128,7 @@ AggregateDeclaration::AggregateDeclarati - getRTInfo = NULL; - } - --enum PROT AggregateDeclaration::prot() -+PROT AggregateDeclaration::prot() - { - return protection; - } -@@ -81,6 +150,7 @@ void AggregateDeclaration::semantic2(Sco - if (members) - { - sc = sc->push(this); -+ sc->parent = this; - for (size_t i = 0; i < members->dim; i++) - { - Dsymbol *s = (*members)[i]; -@@ -96,16 +166,24 @@ void AggregateDeclaration::semantic3(Sco - //printf("AggregateDeclaration::semantic3(%s)\n", toChars()); - if (members) - { -+ StructDeclaration *sd = isStructDeclaration(); -+ if (!sc) // from runDeferredSemantic3 for TypeInfo generation -+ goto Lxop; -+ - sc = sc->push(this); -+ sc->parent = this; - for (size_t i = 0; i < members->dim; i++) - { - Dsymbol *s = (*members)[i]; - s->semantic3(sc); - } -- sc->pop(); -+ sc = sc->pop(); - -- if (!getRTInfo) -- { // Evaluate: gcinfo!type -+ if (!getRTInfo && Type::rtinfo && -+ (!isDeprecated() || global.params.useDeprecated) && // don't do it for unused deprecated types -+ (type && type->ty != Terror)) // or error types -+ { -+ // Evaluate: RTinfo!type - Objects *tiargs = new Objects(); - tiargs->push(type); - TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs); -@@ -113,11 +191,56 @@ void AggregateDeclaration::semantic3(Sco - ti->semantic2(sc); - ti->semantic3(sc); - Dsymbol *s = ti->toAlias(); -- Expression *e = new DsymbolExp(0, s, 0); -- e = e->semantic(ti->tempdecl->scope); -+ Expression *e = new DsymbolExp(Loc(), s, 0); -+ -+ Scope *sc2 = ti->tempdecl->scope->startCTFE(); -+ sc2->instantiatingModule = sc->instantiatingModule ? sc->instantiatingModule : sc->module; -+ e = e->semantic(sc2); -+ sc2->endCTFE(); -+ - e = e->ctfeInterpret(); - getRTInfo = e; - } -+ -+ if (sd) -+ { -+ Lxop: -+ if (sd->xeq && -+ sd->xeq->scope && -+ sd->xeq->semanticRun < PASSsemantic3done) -+ { -+ unsigned errors = global.startGagging(); -+ sd->xeq->semantic3(sd->xeq->scope); -+ if (global.endGagging(errors)) -+ sd->xeq = sd->xerreq; -+ } -+ -+ if (sd->xcmp && -+ sd->xcmp->scope && -+ sd->xcmp->semanticRun < PASSsemantic3done) -+ { -+ unsigned errors = global.startGagging(); -+ sd->xcmp->semantic3(sd->xcmp->scope); -+ if (global.endGagging(errors)) -+ sd->xcmp = sd->xerrcmp; -+ } -+ -+ FuncDeclaration *ftostr = search_toString(sd); -+ if (ftostr && -+ ftostr->scope && -+ ftostr->semanticRun < PASSsemantic3done) -+ { -+ ftostr->semantic3(ftostr->scope); -+ } -+ -+ FuncDeclaration *ftohash = search_toHash(sd); -+ if (ftohash && -+ ftohash->scope && -+ ftohash->semanticRun < PASSsemantic3done) -+ { -+ ftohash->semantic3(ftohash->scope); -+ } -+ } - } - } - -@@ -140,8 +263,6 @@ unsigned AggregateDeclaration::size(Loc - //printf("AggregateDeclaration::size() %s, scope = %p\n", toChars(), scope); - if (loc.linnum == 0) - loc = this->loc; -- if (!members) -- error(loc, "unknown size"); - if (sizeok != SIZEOKdone && scope) - semantic(NULL); - -@@ -166,7 +287,7 @@ unsigned AggregateDeclaration::size(Loc - v->semantic(NULL); - if (v->storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCctfe | STCtemplateparameter)) - return 0; -- if (v->storage_class & STCfield && v->sem >= SemanticDone) -+ if (v->isField() && v->sem >= SemanticDone) - return 0; - return 1; - } -@@ -185,8 +306,13 @@ unsigned AggregateDeclaration::size(Loc - L1: ; - } - -- if (sizeok != SIZEOKdone) -- { error(loc, "no size yet for forward reference"); -+ if (!members) -+ { -+ error(loc, "unknown size"); -+ } -+ else if (sizeok != SIZEOKdone) -+ { -+ error(loc, "no size yet for forward reference"); - //*(char*)0=0; - } - return structsize; -@@ -197,12 +323,12 @@ Type *AggregateDeclaration::getType() - return type; - } - --int AggregateDeclaration::isDeprecated() -+bool AggregateDeclaration::isDeprecated() - { - return isdeprecated; - } - --int AggregateDeclaration::isExport() -+bool AggregateDeclaration::isExport() - { - return protection == PROTexport; - } -@@ -220,11 +346,11 @@ void AggregateDeclaration::alignmember( - //printf("alignment = %d, size = %d, offset = %d\n",alignment,size,offset); - switch (alignment) - { -- case 1: -+ case (structalign_t) 1: - // No alignment - break; - -- case STRUCTALIGN_DEFAULT: -+ case (structalign_t) STRUCTALIGN_DEFAULT: - { /* Must match what the corresponding C compiler's default - * alignment behavior is. - */ -@@ -287,14 +413,68 @@ unsigned AggregateDeclaration::placeFiel - - - /**************************************** -- * Returns !=0 if there's an extra member which is the 'this' -+ * Returns true if there's an extra member which is the 'this' - * pointer to the enclosing context (enclosing aggregate or function) - */ - --int AggregateDeclaration::isNested() -+bool AggregateDeclaration::isNested() - { -- assert((isnested & ~1) == 0); -- return isnested; -+ return enclosing != NULL; -+} -+ -+void AggregateDeclaration::makeNested() -+{ -+ if (!enclosing && sizeok != SIZEOKdone && !isUnionDeclaration() && !isInterfaceDeclaration()) -+ { -+ // If nested struct, add in hidden 'this' pointer to outer scope -+ if (!(storage_class & STCstatic)) -+ { -+ Dsymbol *s = toParent2(); -+ if (s) -+ { -+ AggregateDeclaration *ad = s->isAggregateDeclaration(); -+ FuncDeclaration *fd = s->isFuncDeclaration(); -+ -+ if (fd) -+ { -+ enclosing = fd; -+ } -+ else if (isClassDeclaration() && ad && ad->isClassDeclaration()) -+ { -+ enclosing = ad; -+ } -+ else if (isStructDeclaration() && ad) -+ { -+ if (TemplateInstance *ti = ad->parent->isTemplateInstance()) -+ { -+ enclosing = ti->enclosing; -+ } -+ } -+ if (enclosing) -+ { -+ //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars()); -+ Type *t; -+ if (ad) -+ t = ad->handle; -+ else if (fd) -+ { AggregateDeclaration *ad2 = fd->isMember2(); -+ if (ad2) -+ t = ad2->handle; -+ else -+ t = Type::tvoidptr; -+ } -+ else -+ assert(0); -+ if (t->ty == Tstruct) -+ t = Type::tvoidptr; // t should not be a ref type -+ assert(!vthis); -+ vthis = new ThisDeclaration(loc, t); -+ //vthis->storage_class |= STCref; -+ members->push(vthis); -+ } -+ } -+ } -+ } - } - - /**************************************** -@@ -349,6 +529,25 @@ int AggregateDeclaration::numFieldsInUni - return count; - } - -+/******************************************* -+ * Look for constructor declaration. -+ */ -+void AggregateDeclaration::searchCtor() -+{ -+ ctor = search(Loc(), Id::ctor, 0); -+ if (ctor) -+ { -+ if (!(ctor->isCtorDeclaration() || -+ ctor->isTemplateDeclaration() || -+ ctor->isOverloadSet())) -+ { -+ error("%s %s is not a constructor; identifiers starting with __ are reserved for the implementation", ctor->kind(), ctor->toChars()); -+ errors = true; -+ ctor = NULL; -+ } -+ } -+} -+ - /********************************* StructDeclaration ****************************/ - - StructDeclaration::StructDeclaration(Loc loc, Identifier *id) -@@ -362,6 +561,7 @@ StructDeclaration::StructDeclaration(Loc - postblit = NULL; - - xeq = NULL; -+ xcmp = NULL; - alignment = 0; - #endif - arg1type = NULL; -@@ -369,6 +569,19 @@ StructDeclaration::StructDeclaration(Loc - - // For forward references - type = new TypeStruct(this); -+ -+#if MODULEINFO_IS_STRUCT -+ #ifdef DMDV2 -+ if (id == Id::ModuleInfo && !Module::moduleinfo) -+ Module::moduleinfo = this; -+ #else -+ if (id == Id::ModuleInfo) -+ { if (Module::moduleinfo) -+ Module::moduleinfo->error("only object.d can define this reserved struct name"); -+ Module::moduleinfo = this; -+ } -+ #endif -+#endif - } - - Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s) -@@ -392,7 +605,7 @@ void StructDeclaration::semantic(Scope * - //static int count; if (++count == 20) halt(); - - assert(type); -- if (!members) // if forward reference -+ if (!members) // if opaque declaration - { - return; - } -@@ -409,14 +622,13 @@ void StructDeclaration::semantic(Scope * - - Scope *scx = NULL; - if (scope) -- { sc = scope; -+ { -+ sc = scope; - scx = scope; // save so we don't make redundant copies - scope = NULL; - } -- -- int errors = global.gaggedErrors; -- - unsigned dprogress_save = Module::dprogress; -+ int errors = global.errors; - - parent = sc->parent; - type = type->semantic(loc, sc); -@@ -456,15 +668,10 @@ void StructDeclaration::semantic(Scope * - * resolve individual members like enums. - */ - for (size_t i = 0; i < members->dim; i++) -- { Dsymbol *s = (*members)[i]; -- /* There are problems doing this in the general case because -- * Scope keeps track of things like 'offset' -- */ -- //if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident)) -- { -- //printf("struct: setScope %s %s\n", s->kind(), s->toChars()); -- s->setScope(sc2); -- } -+ { -+ Dsymbol *s = (*members)[i]; -+ //printf("struct: setScope %s %s\n", s->kind(), s->toChars()); -+ s->setScope(sc2); - } - - for (size_t i = 0; i < members->dim; i++) -@@ -481,14 +688,10 @@ void StructDeclaration::semantic(Scope * - if (sizeok == SIZEOKnone && s->isAliasDeclaration()) - finalizeSize(sc2); - } -+ - // Ungag errors when not speculative -- unsigned oldgag = global.gag; -- if (global.isSpeculativeGagging() && !isSpeculative()) -- { -- global.gag = 0; -- } -+ Ungag ungag = ungagSpeculative(); - s->semantic(sc2); -- global.gag = oldgag; - } - finalizeSize(sc2); - -@@ -562,7 +765,7 @@ void StructDeclaration::semantic(Scope * - - arguments->push(arg); - tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); -- tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc); -+ tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), sc); - } - - TypeFunction *tfeq; -@@ -572,7 +775,7 @@ void StructDeclaration::semantic(Scope * - - arguments->push(arg); - tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd); -- tfeq = (TypeFunction *)tfeq->semantic(0, sc); -+ tfeq = (TypeFunction *)tfeq->semantic(Loc(), sc); - } - - Identifier *id = Id::eq; -@@ -611,22 +814,31 @@ void StructDeclaration::semantic(Scope * - postblit = buildPostBlit(sc2); - cpctor = buildCpCtor(sc2); - -- hasIdentityAssign = (buildOpAssign(sc2) != NULL); -- hasIdentityEquals = (buildOpEquals(sc2) != NULL); -+ buildOpAssign(sc2); -+ buildOpEquals(sc2); - - xeq = buildXopEquals(sc2); -+ xcmp = buildXopCmp(sc2); -+ -+ /* Even if the struct is merely imported and its semantic3 is not run, -+ * the TypeInfo object would be speculatively stored in each object -+ * files. To set correct function pointer, run semantic3 for xeq and xcmp. -+ */ -+ //if ((xeq && xeq != xerreq || xcmp && xcmp != xerrcmp) && isImportedSym(this)) -+ // Module::addDeferredSemantic3(this); -+ /* Defer requesting semantic3 until TypeInfo generation is actually invoked. -+ * See Type::getTypeInfo(). -+ */ - #endif -+ inv = buildInv(sc2); - - sc2->pop(); - - /* Look for special member functions. - */ --#if DMDV2 -- ctor = search(0, Id::ctor, 0); --#endif -- inv = (InvariantDeclaration *)search(0, Id::classInvariant, 0); -- aggNew = (NewDeclaration *)search(0, Id::classNew, 0); -- aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0); -+ searchCtor(); -+ aggNew = (NewDeclaration *)search(Loc(), Id::classNew, 0); -+ aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete, 0); - - TypeTuple *tup = type->toArgTypes(); - size_t dim = tup->arguments->dim; -@@ -643,9 +855,10 @@ void StructDeclaration::semantic(Scope * - semantic3(sc); - } - -- if (global.gag && global.gaggedErrors != errors) -- { // The type is no good, yet the error messages were gagged. -+ if (global.errors != errors) -+ { // The type is no good. - type = Type::terror; -+ this->errors = true; - } - - if (deferred && !global.gag) -@@ -653,6 +866,13 @@ void StructDeclaration::semantic(Scope * - deferred->semantic2(sc); - deferred->semantic3(sc); - } -+ -+ if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this) -+ { -+ error("failed semantic analysis"); -+ this->errors = true; -+ type = Type::terror; -+ } - } - - Dsymbol *StructDeclaration::search(Loc loc, Identifier *ident, int flags) -@@ -662,7 +882,7 @@ Dsymbol *StructDeclaration::search(Loc l - if (scope && !symtab) - semantic(scope); - -- if (!members || !symtab) -+ if (!members || !symtab) // opaque or semantic() is not yet called - { - error("is forward referenced when looking for '%s'", ident->toChars()); - return NULL; -@@ -705,45 +925,6 @@ void StructDeclaration::finalizeSize(Sco - sizeok = SIZEOKdone; - } - --void StructDeclaration::makeNested() --{ -- if (!isnested && sizeok != SIZEOKdone && !isUnionDeclaration()) -- { -- // If nested struct, add in hidden 'this' pointer to outer scope -- if (!(storage_class & STCstatic)) -- { Dsymbol *s = toParent2(); -- if (s) -- { -- AggregateDeclaration *ad = s->isAggregateDeclaration(); -- FuncDeclaration *fd = s->isFuncDeclaration(); -- -- TemplateInstance *ti; -- if (ad && (ti = ad->parent->isTemplateInstance()) != NULL && ti->isnested || fd) -- { isnested = true; -- Type *t; -- if (ad) -- t = ad->handle; -- else if (fd) -- { AggregateDeclaration *ad = fd->isMember2(); -- if (ad) -- t = ad->handle; -- else -- t = Type::tvoidptr; -- } -- else -- assert(0); -- if (t->ty == Tstruct) -- t = Type::tvoidptr; // t should not be a ref type -- assert(!vthis); -- vthis = new ThisDeclaration(loc, t); -- //vthis->storage_class |= STCref; -- members->push(vthis); -- } -- } -- } -- } --} -- - /*************************************** - * Return true if struct is POD (Plain Old Data). - * This is defined as: -@@ -758,7 +939,7 @@ void StructDeclaration::makeNested() - */ - bool StructDeclaration::isPOD() - { -- if (isnested || cpctor || postblit || ctor || dtor) -+ if (enclosing || cpctor || postblit || ctor || dtor) - return false; - - /* Recursively check any fields have a constructor. -@@ -768,16 +949,13 @@ bool StructDeclaration::isPOD() - { - Dsymbol *s = fields[i]; - VarDeclaration *v = s->isVarDeclaration(); -- assert(v && v->storage_class & STCfield); -+ assert(v && v->isField()); - if (v->storage_class & STCref) - continue; -- Type *tv = v->type->toBasetype(); -- while (tv->ty == Tsarray) -- { TypeSArray *ta = (TypeSArray *)tv; -- tv = tv->nextOf()->toBasetype(); -- } -+ Type *tv = v->type->baseElemOf(); - if (tv->ty == Tstruct) -- { TypeStruct *ts = (TypeStruct *)tv; -+ { -+ TypeStruct *ts = (TypeStruct *)tv; - StructDeclaration *sd = ts->sym; - if (!sd->isPOD()) - return false; ---- a/src/gcc/d/dfrontend/target.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/target.h 2014-04-01 16:32:51.000000000 +0100 -@@ -14,7 +14,7 @@ - // At present it is incomplete, but in future it should grow to contain - // most or all target machine and target O/S specific information. - --struct Type; -+class Type; - - struct Target - { -@@ -22,7 +22,7 @@ struct Target - static int realsize; // size a real consumes in memory - static int realpad; // 'padding' added to the CPU real size to bring it up to realsize - static int realalignsize; // alignment for reals -- -+ - static void init(); - static unsigned alignsize(Type* type); - static unsigned fieldalign(Type* type); ---- a/src/gcc/d/dfrontend/template.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/template.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -32,28 +32,23 @@ - #include "identifier.h" - #include "hdrgen.h" - #include "id.h" -- --#ifdef IN_GCC --#include "d-dmd-gcc.h" --#else --#if WINDOWS_SEH --#include --long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); --#endif --#endif -+#include "attrib.h" - - #define LOG 0 - - #define IDX_NOTFOUND (0x12345678) // index is not found - - size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters); -+int arrayObjectMatch(Objects *oa1, Objects *oa2); -+hash_t arrayObjectHash(Objects *oa1); -+int arrayCheckRecursiveExpansion(Objects *oa1, TemplateDeclaration *tempdecl, Scope *sc); - - /******************************************** - * These functions substitute for dynamic_cast. dynamic_cast does not work - * on earlier versions of gcc. - */ - --Expression *isExpression(Object *o) -+Expression *isExpression(RootObject *o) - { - //return dynamic_cast(o); - if (!o || o->dyncast() != DYNCAST_EXPRESSION) -@@ -61,7 +56,7 @@ Expression *isExpression(Object *o) - return (Expression *)o; - } - --Dsymbol *isDsymbol(Object *o) -+Dsymbol *isDsymbol(RootObject *o) - { - //return dynamic_cast(o); - if (!o || o->dyncast() != DYNCAST_DSYMBOL) -@@ -69,7 +64,7 @@ Dsymbol *isDsymbol(Object *o) - return (Dsymbol *)o; - } - --Type *isType(Object *o) -+Type *isType(RootObject *o) - { - //return dynamic_cast(o); - if (!o || o->dyncast() != DYNCAST_TYPE) -@@ -77,7 +72,7 @@ Type *isType(Object *o) - return (Type *)o; - } - --Tuple *isTuple(Object *o) -+Tuple *isTuple(RootObject *o) - { - //return dynamic_cast(o); - if (!o || o->dyncast() != DYNCAST_TUPLE) -@@ -85,7 +80,7 @@ Tuple *isTuple(Object *o) - return (Tuple *)o; - } - --Parameter *isParameter(Object *o) -+Parameter *isParameter(RootObject *o) - { - //return dynamic_cast(o); - if (!o || o->dyncast() != DYNCAST_PARAMETER) -@@ -96,7 +91,7 @@ Parameter *isParameter(Object *o) - /************************************** - * Is this Object an error? - */ --int isError(Object *o) -+int isError(RootObject *o) - { - Type *t = isType(o); - if (t) -@@ -107,6 +102,9 @@ int isError(Object *o) - Tuple *v = isTuple(o); - if (v) - return arrayObjectIsError(&v->objects); -+ Dsymbol *s = isDsymbol(o); -+ if (s->errors) -+ return 1; - return 0; - } - -@@ -117,7 +115,7 @@ int arrayObjectIsError(Objects *args) - { - for (size_t i = 0; i < args->dim; i++) - { -- Object *o = (*args)[i]; -+ RootObject *o = (*args)[i]; - if (isError(o)) - return 1; - } -@@ -128,7 +126,7 @@ int arrayObjectIsError(Objects *args) - * Try to get arg as a type. - */ - --Type *getType(Object *o) -+Type *getType(RootObject *o) - { - Type *t = isType(o); - if (!t) -@@ -139,7 +137,7 @@ Type *getType(Object *o) - return t; - } - --Dsymbol *getDsymbol(Object *oarg) -+Dsymbol *getDsymbol(RootObject *oarg) - { - //printf("getDsymbol()\n"); - //printf("e %p s %p t %p v %p\n", isExpression(oarg), isDsymbol(oarg), isType(oarg), isTuple(oarg)); -@@ -181,9 +179,8 @@ Expression *getValue(Expression *e) - { - VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration(); - if (v && v->storage_class & STCmanifest) -- { ExpInitializer *ei = v->init->isExpInitializer(); -- if (ei) -- e = ei->exp; -+ { -+ e = v->getConstInitializer(); - } - } - return e; -@@ -195,9 +192,8 @@ Expression *getValue(Dsymbol *&s) - { - VarDeclaration *v = s->isVarDeclaration(); - if (v && v->storage_class & STCmanifest) -- { ExpInitializer *ei = v->init->isExpInitializer(); -- if (ei) -- e = ei->exp, s = NULL; -+ { -+ e = v->getConstInitializer(); - } - } - return e; -@@ -208,7 +204,7 @@ Expression *getValue(Dsymbol *&s) - * Else, return 0. - */ - --int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc) -+int match(RootObject *o1, RootObject *o2) - { - Type *t1 = isType(o1); - Type *t2 = isType(o2); -@@ -232,25 +228,6 @@ int match(Object *o1, Object *o2, Templa - - if (t1) - { -- /* if t1 is an instance of ti, then give error -- * about recursive expansions. -- */ -- Dsymbol *s = t1->toDsymbol(sc); -- if (s && s->parent) -- { TemplateInstance *ti1 = s->parent->isTemplateInstance(); -- if (ti1 && ti1->tempdecl == tempdecl) -- { -- for (Scope *sc1 = sc; sc1; sc1 = sc1->enclosing) -- { -- if (sc1->scopesym == ti1) -- { -- tempdecl->error("recursive template expansion for template argument %s", t1->toChars()); -- return 1; // fake a match -- } -- } -- } -- } -- - //printf("t1 = %s\n", t1->toChars()); - //printf("t2 = %s\n", t2->toChars()); - if (!t2 || !t1->equals(t2)) -@@ -273,22 +250,26 @@ int match(Object *o1, Object *o2, Templa - } - else if (s1) - { -- if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) -+ if (s2) -+ { -+ if (!s1->equals(s2)) -+ goto Lnomatch; -+ if (s1->parent != s2->parent && -+ !s1->isFuncDeclaration() && -+ !s2->isFuncDeclaration()) -+ { -+ goto Lnomatch; -+ } -+ } -+ else - goto Lnomatch; - } - else if (u1) - { - if (!u2) - goto Lnomatch; -- if (u1->objects.dim != u2->objects.dim) -+ if (!arrayObjectMatch(&u1->objects, &u2->objects)) - goto Lnomatch; -- for (size_t i = 0; i < u1->objects.dim; i++) -- { -- if (!match(u1->objects[i], -- u2->objects[i], -- tempdecl, sc)) -- goto Lnomatch; -- } - } - //printf("match\n"); - return 1; // match -@@ -302,16 +283,16 @@ Lnomatch: - /************************************ - * Match an array of them. - */ --int arrayObjectMatch(Objects *oa1, Objects *oa2, TemplateDeclaration *tempdecl, Scope *sc) -+int arrayObjectMatch(Objects *oa1, Objects *oa2) - { - if (oa1 == oa2) - return 1; - if (oa1->dim != oa2->dim) - return 0; - for (size_t j = 0; j < oa1->dim; j++) -- { Object *o1 = (*oa1)[j]; -- Object *o2 = (*oa2)[j]; -- if (!match(o1, o2, tempdecl, sc)) -+ { RootObject *o1 = (*oa1)[j]; -+ RootObject *o2 = (*oa2)[j]; -+ if (!match(o1, o2)) - { - return 0; - } -@@ -319,12 +300,105 @@ int arrayObjectMatch(Objects *oa1, Objec - return 1; - } - -+ -+/************************************ -+ * Return hash of Objects. -+ */ -+hash_t arrayObjectHash(Objects *oa1) -+{ -+ hash_t hash = 0; -+ for (size_t j = 0; j < oa1->dim; j++) -+ { /* Must follow the logic of match() -+ */ -+ RootObject *o1 = (*oa1)[j]; -+ if (Type *t1 = isType(o1)) -+ hash += (size_t)t1->deco; -+ else -+ { -+ Dsymbol *s1 = isDsymbol(o1); -+ Expression *e1 = s1 ? getValue(s1) : getValue(isExpression(o1)); -+ if (e1) -+ { -+ if (e1->op == TOKint64) -+ { -+ IntegerExp *ne = (IntegerExp *)e1; -+ hash += (size_t)ne->value; -+ } -+ } -+ else if (s1) -+ { -+ FuncAliasDeclaration *fa1 = s1->isFuncAliasDeclaration(); -+ if (fa1) -+ s1 = fa1->toAliasFunc(); -+ hash += (size_t)(void *)s1->getIdent() + (size_t)(void *)s1->parent; -+ } -+ else if (Tuple *u1 = isTuple(o1)) -+ hash += arrayObjectHash(&u1->objects); -+ } -+ } -+ return hash; -+} -+ -+ -+/****************************** -+ * Check template argument o1 to see if it is a recursive expansion of tempdecl in scope sc. -+ * If so, issue error and return 1. -+ */ -+ -+int checkRecursiveExpansion(RootObject *o1, TemplateDeclaration *tempdecl, Scope *sc) -+{ -+ if (Type *t1 = isType(o1)) -+ { -+ /* if t1 is an instance of ti, then give error -+ * about recursive expansions. -+ */ -+ Dsymbol *s = t1->toDsymbol(sc); -+ if (s && s->parent) -+ { -+ TemplateInstance *ti1 = s->parent->isTemplateInstance(); -+ if (ti1 && ti1->tempdecl == tempdecl) -+ { -+ for (Scope *sc1 = sc; sc1; sc1 = sc1->enclosing) -+ { -+ if (sc1->scopesym == ti1) -+ { -+ tempdecl->error("recursive template expansion for template argument %s", t1->toChars()); -+ return 1; -+ } -+ } -+ } -+ } -+ } -+ else if (Tuple *u1 = isTuple(o1)) -+ { -+ return arrayCheckRecursiveExpansion(&u1->objects, tempdecl, sc); -+ } -+ return 0; // no error -+} -+ -+ -+/************************************ -+ * Match an array of them. -+ */ -+int arrayCheckRecursiveExpansion(Objects *oa1, TemplateDeclaration *tempdecl, Scope *sc) -+{ -+ for (size_t j = 0; j < oa1->dim; j++) -+ { -+ RootObject *o1 = (*oa1)[j]; -+ if (checkRecursiveExpansion(o1, tempdecl, sc)) -+ return 1; -+ } -+ return 0; -+} -+ -+ -+ - /**************************************** - * This makes a 'pretty' version of the template arguments. - * It's analogous to genIdent() which makes a mangled version. - */ - --void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg) -+void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, RootObject *oarg) - { - //printf("ObjectToCBuffer()\n"); - Type *t = isType(oarg); -@@ -357,8 +431,8 @@ void ObjectToCBuffer(OutBuffer *buf, Hdr - for (size_t i = 0; i < args->dim; i++) - { - if (i) -- buf->writeByte(','); -- Object *o = (*args)[i]; -+ buf->writestring(", "); -+ RootObject *o = (*args)[i]; - ObjectToCBuffer(buf, hgs, o); - } - } -@@ -376,7 +450,7 @@ void ObjectToCBuffer(OutBuffer *buf, Hdr - } - - #if DMDV2 --Object *objectSyntaxCopy(Object *o) -+RootObject *objectSyntaxCopy(RootObject *o) - { - if (!o) - return NULL; -@@ -420,14 +494,17 @@ TemplateDeclaration::TemplateDeclaration - this->members = decldefs; - this->overnext = NULL; - this->overroot = NULL; -- this->semanticRun = PASSinit; -+ this->funcroot = NULL; - this->onemember = NULL; - this->literal = 0; - this->ismixin = ismixin; - this->previous = NULL; -+ this->protection = PROTundefined; -+ this->numinstances = 0; - - // Compute in advance for Ddoc's use -- if (members) -+ // Bugzilla 11153: ident could be NULL if parsing fails. -+ if (members && ident) - { - Dsymbol *s; - if (Dsymbol::oneMembers(members, &s, ident) && s) -@@ -470,7 +547,7 @@ void TemplateDeclaration::semantic(Scope - printf("sc->stc = %llx\n", sc->stc); - printf("sc->module = %s\n", sc->module->toChars()); - #endif -- if (semanticRun) -+ if (semanticRun != PASSinit) - return; // semantic() already run - semanticRun = PASSsemantic; - -@@ -525,7 +602,6 @@ void TemplateDeclaration::semantic(Scope - ScopeDsymbol *paramsym = new ScopeDsymbol(); - paramsym->parent = sc->parent; - Scope *paramscope = sc->push(paramsym); -- paramscope->parameterSpecialization = 1; - paramscope->stc = 0; - - if (!parent) -@@ -555,7 +631,7 @@ void TemplateDeclaration::semantic(Scope - { - TemplateParameter *tp = (*parameters)[i]; - -- tp->semantic(paramscope); -+ tp->semantic(paramscope, parameters); - if (i + 1 != parameters->dim && tp->isTemplateTupleParameter()) - { error("template tuple parameter must be last one"); - errors = true; -@@ -590,34 +666,42 @@ const char *TemplateDeclaration::kind() - - /********************************** - * Overload existing TemplateDeclaration 'this' with the new one 's'. -- * Return !=0 if successful; i.e. no conflict. -+ * Return true if successful; i.e. no conflict. - */ - --int TemplateDeclaration::overloadInsert(Dsymbol *s) -+bool TemplateDeclaration::overloadInsert(Dsymbol *s) - { -- TemplateDeclaration **pf; -- TemplateDeclaration *f; -- - #if LOG - printf("TemplateDeclaration::overloadInsert('%s')\n", s->toChars()); - #endif -- f = s->isTemplateDeclaration(); -- if (!f) -- return FALSE; -+ FuncDeclaration *fd = s->isFuncDeclaration(); -+ if (fd) -+ { -+ if (funcroot) -+ return funcroot->overloadInsert(fd); -+ funcroot = fd; -+ return funcroot->overloadInsert(this); -+ } -+ -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (!td) -+ return false; -+ - TemplateDeclaration *pthis = this; -- for (pf = &pthis; *pf; pf = &(*pf)->overnext) -+ TemplateDeclaration **ptd; -+ for (ptd = &pthis; *ptd; ptd = &(*ptd)->overnext) - { - #if 0 - // Conflict if TemplateParameter's match - // Will get caught anyway later with TemplateInstance, but - // should check it now. -- TemplateDeclaration *f2 = *pf; -+ TemplateDeclaration *f2 = *ptd; - -- if (f->parameters->dim != f2->parameters->dim) -+ if (td->parameters->dim != f2->parameters->dim) - goto Lcontinue; - -- for (size_t i = 0; i < f->parameters->dim; i++) -- { TemplateParameter *p1 = (*f->parameters)[i]; -+ for (size_t i = 0; i < td->parameters->dim; i++) -+ { TemplateParameter *p1 = (*td->parameters)[i]; - TemplateParameter *p2 = (*f2->parameters)[i]; - - if (!p1->overloadMatch(p2)) -@@ -627,19 +711,19 @@ int TemplateDeclaration::overloadInsert( - #if LOG - printf("\tfalse: conflict\n"); - #endif -- return FALSE; -+ return false; - - Lcontinue: - ; - #endif - } - -- f->overroot = this; -- *pf = f; -+ td->overroot = this; -+ *ptd = td; - #if LOG - printf("\ttrue: no conflict\n"); - #endif -- return TRUE; -+ return true; - } - - /**************************** -@@ -678,9 +762,6 @@ void TemplateDeclaration::makeParamNames - { - Parameter *fparam = Parameter::getNth(fparameters, i); - // Remove addMod same as func.d L1065 of FuncDeclaration::semantic3 -- //Type *vtype = fparam->type; -- //if (fd->type && fd->isPure()) -- // vtype = vtype->addMod(MODconst); - fparam->storageClass &= (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor); - fparam->storageClass |= STCparameter; - if (fvarargs == 2 && i + 1 == nfparams) -@@ -714,7 +795,7 @@ void TemplateDeclaration::makeParamNames - * Return match level. - */ - --MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti, -+MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti, - Objects *dedtypes, Expressions *fargs, int flag) - { MATCH m; - size_t dedtypes_dim = dedtypes->dim; -@@ -752,16 +833,20 @@ MATCH TemplateDeclaration::matchWithInst - assert(dedtypes_dim >= ti->tiargs->dim || variadic); - - // Set up scope for parameters -- assert((size_t)scope > 0x10000); -+ assert(scope); - ScopeDsymbol *paramsym = new ScopeDsymbol(); - paramsym->parent = scope->parent; - Scope *paramscope = scope->push(paramsym); -+ Module *mi = ti->instantiatingModule ? ti->instantiatingModule : sc->instantiatingModule; -+ paramscope->instantiatingModule = mi; -+ paramscope->callsc = sc; - paramscope->stc = 0; - - // Attempt type deduction - m = MATCHexact; - for (size_t i = 0; i < dedtypes_dim; i++) -- { MATCH m2; -+ { -+ MATCH m2; - TemplateParameter *tp = (*parameters)[i]; - Declaration *sparam; - -@@ -773,7 +858,7 @@ MATCH TemplateDeclaration::matchWithInst - printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); - #endif - -- m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam); -+ m2 = tp->matchArg(ti->loc, paramscope, ti->tiargs, i, parameters, dedtypes, &sparam); - //printf("\tm2 = %d\n", m2); - - if (m2 == MATCHnomatch) -@@ -789,8 +874,9 @@ MATCH TemplateDeclaration::matchWithInst - - if (!flag) - sparam->semantic(paramscope); -- if (!paramscope->insert(sparam)) -- goto Lnomatch; -+ if (!paramscope->insert(sparam)) // TODO: This check can make more early -+ goto Lnomatch; // in TemplateDeclaration::semantic, and -+ // then we don't need to make sparam if flags == 0 - } - - if (!flag) -@@ -809,19 +895,48 @@ MATCH TemplateDeclaration::matchWithInst - - #if DMDV2 - if (m && constraint && !flag) -- { /* Check to see if constraint is satisfied. -+ { -+ /* Check to see if constraint is satisfied. - */ - makeParamNamesVisibleInConstraint(paramscope, fargs); - Expression *e = constraint->syntaxCopy(); -- Scope *sc = paramscope->push(); - - /* There's a chicken-and-egg problem here. We don't know yet if this template -- * instantiation will be a local one (isnested is set), and we won't know until -+ * instantiation will be a local one (enclosing is set), and we won't know until - * after selecting the correct template. Thus, function we're nesting inside - * is not on the sc scope chain, and this can cause errors in FuncDeclaration::getLevel(). - * Workaround the problem by setting a flag to relax the checking on frame errors. - */ -- sc->flags |= SCOPEstaticif; -+ -+ int nmatches = 0; -+ for (Previous *p = previous; p; p = p->prev) -+ { -+ if (arrayCheckRecursiveExpansion(p->dedargs, this, sc)) -+ goto Lnomatch; -+ -+ if (arrayObjectMatch(p->dedargs, dedtypes)) -+ { -+ //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars()); -+ /* It must be a subscope of p->sc, other scope chains are not recursive -+ * instantiations. -+ */ -+ for (Scope *scx = sc; scx; scx = scx->enclosing) -+ { -+ if (scx == p->sc) -+ goto Lnomatch; -+ } -+ } -+ /* BUG: should also check for ref param differences -+ */ -+ } -+ -+ Previous pr; -+ pr.prev = previous; -+ pr.sc = paramscope; -+ pr.dedargs = dedtypes; -+ previous = ≺ // add this to threaded list -+ -+ int nerrors = global.errors; - - FuncDeclaration *fd = onemember && onemember->toAlias() ? - onemember->toAlias()->isFuncDeclaration() : NULL; -@@ -836,14 +951,22 @@ MATCH TemplateDeclaration::matchWithInst - fd->vthis = fd->declareThis(paramscope, ad); - } - -- e = e->semantic(sc); -- if (e->op == TOKerror) -- goto Lnomatch; -+ Scope *scx = paramscope->startCTFE(); -+ scx->flags |= SCOPEstaticif; -+ e = e->semantic(scx); -+ e = resolveProperties(scx, e); -+ scx = scx->endCTFE(); - - if (fd && fd->vthis) - fd->vthis = vthissave; - -- sc->pop(); -+ previous = pr.prev; // unlink from threaded list -+ -+ if (nerrors != global.errors) // if any errors from evaluating the constraint, no match -+ goto Lnomatch; -+ if (e->op == TOKerror) -+ goto Lnomatch; -+ - e = e->ctfeInterpret(); - if (e->isBool(TRUE)) - ; -@@ -866,7 +989,7 @@ MATCH TemplateDeclaration::matchWithInst - for (size_t i = 0; i < dedtypes_dim; i++) - { - TemplateParameter *tp = (*parameters)[i]; -- Object *oarg; -+ RootObject *oarg; - - printf(" [%d]", i); - -@@ -907,7 +1030,7 @@ Lret: - * 0 td2 is more specialized than this - */ - --MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2, Expressions *fargs) -+MATCH TemplateDeclaration::leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs) - { - /* This works by taking the template parameters to this template - * declaration and feeding them to td2 as if it were a template -@@ -916,7 +1039,7 @@ MATCH TemplateDeclaration::leastAsSpecia - * as td2. - */ - -- TemplateInstance ti(0, ident); // create dummy template instance -+ TemplateInstance ti(Loc(), ident); // create dummy template instance - Objects dedtypes; - - #define LOG_LEASTAS 0 -@@ -933,7 +1056,7 @@ MATCH TemplateDeclaration::leastAsSpecia - { - TemplateParameter *tp = (*parameters)[i]; - -- Object *p = (Object *)tp->dummyArg(); -+ RootObject *p = (RootObject *)tp->dummyArg(); - if (p) - (*ti.tiargs)[i] = p; - else -@@ -945,7 +1068,7 @@ MATCH TemplateDeclaration::leastAsSpecia - dedtypes.setDim(td2->parameters->dim); - - // Attempt a type deduction -- MATCH m = td2->matchWithInstance(&ti, &dedtypes, fargs, 1); -+ MATCH m = td2->matchWithInstance(sc, &ti, &dedtypes, fargs, 1); - if (m) - { - /* A non-variadic template is more specialized than a -@@ -971,8 +1094,9 @@ MATCH TemplateDeclaration::leastAsSpecia - * Match function arguments against a specific template function. - * Input: - * loc instantiation location -- * targsi Expression/Type initial list of template arguments -- * ethis 'this' argument if !NULL -+ * sc instantiation scope -+ * tiargs Expression/Type initial list of template arguments -+ * tthis 'this' argument if !NULL - * fargs arguments to function - * Output: - * dedargs Expression/Type deduced template arguments -@@ -982,18 +1106,18 @@ MATCH TemplateDeclaration::leastAsSpecia - * bit 4-7 Match template parameters by initial template arguments - */ - --MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objects *targsi, -- Expression *ethis, Expressions *fargs, -+MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc loc, Scope *sc, Objects *tiargs, -+ Type *tthis, Expressions *fargs, - Objects *dedargs) - { - size_t nfparams; - size_t nfargs; -- size_t nargsi; // array size of targsi -+ size_t ntargs; // array size of tiargs - size_t fptupindex = IDX_NOTFOUND; - size_t tuple_dim = 0; - MATCH match = MATCHexact; -- MATCH matchTargsi = MATCHexact; -- FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); -+ MATCH matchTiargs = MATCHexact; -+ FuncDeclaration *fd = f; - Parameters *fparameters; // function parameter list - int fvarargs; // function varargs - Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T -@@ -1004,17 +1128,17 @@ MATCH TemplateDeclaration::deduceFunctio - - #if 0 - printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); -- for (size_t i = 0; i < fargs->dim; i++) -+ for (size_t i = 0; i < (fargs ? fargs->dim : 0); i++) - { Expression *e = (*fargs)[i]; - printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars()); - } - printf("fd = %s\n", fd->toChars()); - printf("fd->type = %s\n", fd->type->toChars()); -- if (ethis) -- printf("ethis->type = %s\n", ethis->type->toChars()); -+ if (tthis) -+ printf("tthis = %s\n", tthis->toChars()); - #endif - -- assert((size_t)scope > 0x10000); -+ assert(scope); - - dedargs->setDim(parameters->dim); - dedargs->zero(); -@@ -1029,31 +1153,38 @@ MATCH TemplateDeclaration::deduceFunctio - ScopeDsymbol *paramsym = new ScopeDsymbol(); - paramsym->parent = scope->parent; - Scope *paramscope = scope->push(paramsym); -+ -+ paramscope->instantiatingModule = sc->instantiatingModule; -+ Module *mi = sc->instantiatingModule ? sc->instantiatingModule : sc->module; -+ if (!sc->instantiatingModule || sc->instantiatingModule->isRoot()) -+ paramscope->instantiatingModule = mi; -+ -+ paramscope->callsc = sc; - paramscope->stc = 0; - - TemplateTupleParameter *tp = isVariadic(); -- int tp_is_declared = 0; -+ bool tp_is_declared = false; - - #if 0 - for (size_t i = 0; i < dedargs->dim; i++) - { - printf("\tdedarg[%d] = ", i); -- Object *oarg = (*dedargs)[i]; -+ RootObject *oarg = (*dedargs)[i]; - if (oarg) printf("%s", oarg->toChars()); - printf("\n"); - } - #endif - - -- nargsi = 0; -- if (targsi) -+ ntargs = 0; -+ if (tiargs) - { // Set initial template arguments - -- nargsi = targsi->dim; -+ ntargs = tiargs->dim; - size_t n = parameters->dim; - if (tp) - n--; -- if (nargsi > n) -+ if (ntargs > n) - { if (!tp) - goto Lnomatch; - -@@ -1064,19 +1195,19 @@ MATCH TemplateDeclaration::deduceFunctio - assert(parameters->dim); - (*dedargs)[parameters->dim - 1] = t; - -- tuple_dim = nargsi - n; -+ tuple_dim = ntargs - n; - t->objects.setDim(tuple_dim); - for (size_t i = 0; i < tuple_dim; i++) - { -- t->objects[i] = (*targsi)[n + i]; -+ t->objects[i] = (*tiargs)[n + i]; - } - declareParameter(paramscope, tp, t); -- tp_is_declared = 1; -+ tp_is_declared = true; - } - else -- n = nargsi; -+ n = ntargs; - -- memcpy(dedargs->tdata(), targsi->tdata(), n * sizeof(*dedargs->tdata())); -+ memcpy(dedargs->tdata(), tiargs->tdata(), n * sizeof(*dedargs->tdata())); - - for (size_t i = 0; i < n; i++) - { assert(i < parameters->dim); -@@ -1084,18 +1215,18 @@ MATCH TemplateDeclaration::deduceFunctio - MATCH m; - Declaration *sparam = NULL; - -- m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); -+ m = tp->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, &sparam); - //printf("\tdeduceType m = %d\n", m); - if (m == MATCHnomatch) - goto Lnomatch; -- if (m < matchTargsi) -- matchTargsi = m; -+ if (m < matchTiargs) -+ matchTiargs = m; - - sparam->semantic(paramscope); - if (!paramscope->insert(sparam)) - goto Lnomatch; - } -- if (n < parameters->dim) -+ if (n < parameters->dim && !tp_is_declared) - { - inferparams = new TemplateParameters(); - inferparams->setDim(parameters->dim - n); -@@ -1105,12 +1236,13 @@ MATCH TemplateDeclaration::deduceFunctio - } - else - inferparams = NULL; -+ //printf("tiargs matchTiargs = %d\n", matchTiargs); - } - #if 0 - for (size_t i = 0; i < dedargs->dim; i++) - { - printf("\tdedarg[%d] = ", i); -- Object *oarg = (*dedargs)[i]; -+ RootObject *oarg = (*dedargs)[i]; - if (oarg) printf("%s", oarg->toChars()); - printf("\n"); - } -@@ -1123,23 +1255,25 @@ MATCH TemplateDeclaration::deduceFunctio - /* Check for match of function arguments with variadic template - * parameter, such as: - * -- * template Foo(T, A...) { void Foo(T t, A a); } -- * void main() { Foo(1,2,3); } -+ * void foo(T, A...)(T t, A a); -+ * void main() { foo(1,2,3); } - */ - if (tp) // if variadic - { -+ // TemplateTupleParameter always makes most lesser matching. -+ matchTiargs = MATCHconvert; -+ - if (nfparams == 0 && nfargs != 0) // if no function parameters - { -- if (tp_is_declared) -- goto L2; -- Tuple *t = new Tuple(); -- //printf("t = %p\n", t); -- (*dedargs)[parameters->dim - 1] = t; -- declareParameter(paramscope, tp, t); -- goto L2; -+ if (!tp_is_declared) -+ { -+ Tuple *t = new Tuple(); -+ //printf("t = %p\n", t); -+ (*dedargs)[parameters->dim - 1] = t; -+ declareParameter(paramscope, tp, t); -+ tp_is_declared = true; -+ } - } -- else if (nfargs < nfparams - 1) -- goto L1; - else - { - /* Figure out which of the function parameters matches -@@ -1159,22 +1293,127 @@ MATCH TemplateDeclaration::deduceFunctio - if (fvarargs) // variadic function doesn't - goto Lnomatch; // go with variadic template - -- if (tp_is_declared) -- goto L2; -+ goto L1; -+ } -+ fptupindex = IDX_NOTFOUND; -+ L1: -+ ; -+ } -+ } -+ -+#if DMDV2 -+ if (tthis) -+ { -+ bool hasttp = false; -+ -+ // Match 'tthis' to any TemplateThisParameter's -+ for (size_t i = 0; i < parameters->dim; i++) -+ { TemplateParameter *tp = (*parameters)[i]; -+ TemplateThisParameter *ttp = tp->isTemplateThisParameter(); -+ if (ttp) -+ { hasttp = true; -+ -+ Type *t = new TypeIdentifier(Loc(), ttp->ident); -+ MATCH m = tthis->deduceType(paramscope, t, parameters, &dedtypes); -+ if (!m) -+ goto Lnomatch; -+ if (m < match) -+ match = m; // pick worst match -+ } -+ } -+ -+ // Match attributes of tthis against attributes of fd -+ if (fd->type && !fd->isCtorDeclaration()) -+ { -+ unsigned mod = fd->type->mod; -+ StorageClass stc = scope->stc | fd->storage_class2; -+ // Propagate parent storage class (see bug 5504) -+ Dsymbol *p = parent; -+ while (p->isTemplateDeclaration() || p->isTemplateInstance()) -+ p = p->parent; -+ AggregateDeclaration *ad = p->isAggregateDeclaration(); -+ if (ad) -+ stc |= ad->storage_class; -+ -+ if (stc & (STCshared | STCsynchronized)) -+ mod |= MODshared; -+ if (stc & STCimmutable) -+ mod |= MODimmutable; -+ if (stc & STCconst) -+ mod |= MODconst; -+ if (stc & STCwild) -+ mod |= MODwild; -+ // Fix mod -+ if (mod & MODimmutable) -+ mod = MODimmutable; -+ if (mod & MODconst) -+ mod &= ~STCwild; -+ -+ unsigned thismod = tthis->mod; -+ if (hasttp) -+ mod = MODmerge(thismod, mod); -+ if (thismod != mod) -+ { -+ if (!MODmethodConv(thismod, mod)) -+ goto Lnomatch; -+ if (MATCHconst < match) -+ match = MATCHconst; -+ } -+ } -+ } -+#endif -+ -+ // Loop through the function parameters -+ { -+ //printf("%s nfargs=%d, nfparams=%d, tuple_dim = %d\n", toChars(), nfargs, nfparams, tuple_dim); -+ //printf("\ttp = %p, fptupindex = %d, found = %d, tp_is_declared = %d\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, tp_is_declared); -+ size_t argi = 0; -+ for (size_t parami = 0; parami < nfparams; parami++) -+ { -+ Parameter *fparam = Parameter::getNth(fparameters, parami); - -- // Apply function parameter storage classes to parameter type -- tid = (TypeIdentifier *)tid->addStorageClass(fparam->storageClass); -+ // Apply function parameter storage classes to parameter types -+ Type *prmtype = fparam->type->addStorageClass(fparam->storageClass); - -+ /* See function parameters which wound up -+ * as part of a template tuple parameter. -+ */ -+ if (fptupindex != IDX_NOTFOUND && parami == fptupindex) -+ { -+ assert(prmtype->ty == Tident); -+ TypeIdentifier *tid = (TypeIdentifier *)prmtype; -+ if (!tp_is_declared) -+ { - /* The types of the function arguments - * now form the tuple argument. - */ - Tuple *t = new Tuple(); - (*dedargs)[parameters->dim - 1] = t; - -- tuple_dim = nfargs - (nfparams - 1); -+ /* Count function parameters following a tuple parameter. -+ * void foo(U, T...)(int y, T, U, int) {} // rem == 2 (U, int) -+ */ -+ size_t rem = 0; -+ for (size_t j = parami + 1; j < nfparams; j++) -+ { -+ Parameter *p = Parameter::getNth(fparameters, j); -+ if (!inferparams || !p->type->reliesOnTident(inferparams)) -+ { -+ Type *pt = p->type->syntaxCopy()->semantic(fd->loc, paramscope); -+ rem += pt->ty == Ttuple ? ((TypeTuple *)pt)->arguments->dim : 1; -+ } -+ else -+ { -+ ++rem; -+ } -+ } -+ -+ if (nfargs - argi < rem) -+ goto Lnomatch; -+ tuple_dim = nfargs - argi - rem; - t->objects.setDim(tuple_dim); - for (size_t i = 0; i < tuple_dim; i++) -- { Expression *farg = (*fargs)[fptupindex + i]; -+ { Expression *farg = (*fargs)[argi + i]; - - // Check invalid arguments to detect errors early. - if (farg->op == TOKerror || farg->type->ty == Terror) -@@ -1199,7 +1438,6 @@ MATCH TemplateDeclaration::deduceFunctio - case X(MODwild, MODimmutable): - case X(MODwild | MODshared, MODshared): - case X(MODwild | MODshared, MODconst | MODshared): -- - if (mod & MODwild) - wildmatch |= MODwild; - else if (mod == 0) -@@ -1224,14 +1462,13 @@ MATCH TemplateDeclaration::deduceFunctio - case X(0, MODconst | MODshared): - case X(0, MODwild): - case X(0, MODwild | MODshared): -- // foo(U:U) T => T -- // foo(U:U) const(T) => const(T) -- // foo(U:U) immutable(T) => immutable(T) -- // foo(U:U) shared(T) => shared(T) -- // foo(U:U) const(shared(T)) => const(shared(T)) -- // foo(U:U) wild(T) => wild(T) -- // foo(U:U) wild(shared(T)) => wild(shared(T)) -- -+ // foo(U:U) T => T -+ // foo(U:U) const(T) => const(T) -+ // foo(U:U) immutable(T) => immutable(T) -+ // foo(U:U) shared(T) => shared(T) -+ // foo(U:U) const(shared(T)) => const(shared(T)) -+ // foo(U:U) wild(T) => wild(T) -+ // foo(U:U) wild(shared(T)) => wild(shared(T)) - tt = farg->type; - m = MATCHexact; - break; -@@ -1242,13 +1479,12 @@ MATCH TemplateDeclaration::deduceFunctio - case X(MODconst | MODshared, MODconst | MODshared): - case X(MODwild, MODwild): - case X(MODwild | MODshared, MODwild | MODshared): -- // foo(U:const(U)) const(T) => T -- // foo(U:immutable(U)) immutable(T) => T -- // foo(U:shared(U)) shared(T) => T -- // foo(U:const(shared(U)) const(shared(T)) => T -- // foo(U:wild(U)) wild(T) => T -- // foo(U:wild(shared(U)) wild(shared(T)) => T -- -+ // foo(U:const(U)) const(T) => T -+ // foo(U:immutable(U)) immutable(T) => T -+ // foo(U:shared(U)) shared(T) => T -+ // foo(U:const(shared(U))) const(shared(T)) => T -+ // foo(U:wild(U)) wild(T) => T -+ // foo(U:wild(shared(U))) wild(shared(T)) => T - tt = farg->type->mutableOf()->unSharedOf(); - m = MATCHexact; - break; -@@ -1259,12 +1495,11 @@ MATCH TemplateDeclaration::deduceFunctio - case X(MODconst | MODshared, MODimmutable): - case X(MODconst, MODwild): - case X(MODconst, MODwild | MODshared): -- // foo(U:const(U)) T => T -- // foo(U:const(U)) immutable(T) => T -- // foo(U:const(U)) const(shared(T)) => shared(T) -- // foo(U:const(shared(U)) immutable(T) => T -- // foo(U:const(U)) wild(shared(T)) => shared(T) -- -+ // foo(U:const(U)) T => T -+ // foo(U:const(U)) immutable(T) => T -+ // foo(U:const(U)) const(shared(T)) => shared(T) -+ // foo(U:const(shared(U))) immutable(T) => T -+ // foo(U:const(U)) wild(shared(T)) => shared(T) - tt = farg->type->mutableOf(); - m = MATCHconst; - break; -@@ -1272,9 +1507,9 @@ MATCH TemplateDeclaration::deduceFunctio - case X(MODshared, MODconst | MODshared): - case X(MODconst | MODshared, MODshared): - case X(MODshared, MODwild | MODshared): -- // foo(U:shared(U)) const(shared(T)) => const(T) -- // foo(U:const(shared(U)) shared(T) => T -- // foo(U:shared(U)) wild(shared(T)) => wild(T) -+ // foo(U:shared(U)) const(shared(T)) => const(T) -+ // foo(U:const(shared(U))) shared(T) => T -+ // foo(U:shared(U)) wild(shared(T)) => wild(T) - tt = farg->type->unSharedOf(); - m = MATCHconst; - break; -@@ -1306,34 +1541,33 @@ MATCH TemplateDeclaration::deduceFunctio - case X(MODimmutable, MODwild | MODshared): - case X(MODconst | MODshared, MODwild | MODshared): - case X(MODwild, MODwild | MODshared): -- -- // foo(U:immutable(U)) T => nomatch -- // foo(U:immutable(U)) const(T) => nomatch -- // foo(U:immutable(U)) shared(T) => nomatch -- // foo(U:immutable(U)) const(shared(T)) => nomatch -- // foo(U:const(U)) shared(T) => nomatch -- // foo(U:shared(U)) T => nomatch -- // foo(U:shared(U)) const(T) => nomatch -- // foo(U:shared(U)) immutable(T) => nomatch -- // foo(U:const(shared(U)) T => nomatch -- // foo(U:const(shared(U)) const(T) => nomatch -- // foo(U:immutable(U)) wild(T) => nomatch -- // foo(U:shared(U)) wild(T) => nomatch -- // foo(U:const(shared(U)) wild(T) => nomatch -- // foo(U:wild(U)) T => nomatch -- // foo(U:wild(U)) const(T) => nomatch -- // foo(U:wild(U)) immutable(T) => nomatch -- // foo(U:wild(U)) shared(T) => nomatch -- // foo(U:wild(U)) const(shared(T)) => nomatch -- // foo(U:wild(shared(U)) T => nomatch -- // foo(U:wild(shared(U)) const(T) => nomatch -- // foo(U:wild(shared(U)) immutable(T) => nomatch -- // foo(U:wild(shared(U)) shared(T) => nomatch -- // foo(U:wild(shared(U)) const(shared(T)) => nomatch -- // foo(U:wild(shared(U)) wild(T) => nomatch -- // foo(U:immutable(U)) wild(shared(T)) => nomatch -- // foo(U:const(shared(U))) wild(shared(T)) => nomatch -- // foo(U:wild(U)) wild(shared(T)) => nomatch -+ // foo(U:immutable(U)) T => nomatch -+ // foo(U:immutable(U)) const(T) => nomatch -+ // foo(U:immutable(U)) shared(T) => nomatch -+ // foo(U:immutable(U)) const(shared(T)) => nomatch -+ // foo(U:const(U)) shared(T) => nomatch -+ // foo(U:shared(U)) T => nomatch -+ // foo(U:shared(U)) const(T) => nomatch -+ // foo(U:shared(U)) immutable(T) => nomatch -+ // foo(U:const(shared(U))) T => nomatch -+ // foo(U:const(shared(U))) const(T) => nomatch -+ // foo(U:immutable(U)) wild(T) => nomatch -+ // foo(U:shared(U)) wild(T) => nomatch -+ // foo(U:const(shared(U))) wild(T) => nomatch -+ // foo(U:wild(U)) T => nomatch -+ // foo(U:wild(U)) const(T) => nomatch -+ // foo(U:wild(U)) immutable(T) => nomatch -+ // foo(U:wild(U)) shared(T) => nomatch -+ // foo(U:wild(U)) const(shared(T)) => nomatch -+ // foo(U:wild(shared(U))) T => nomatch -+ // foo(U:wild(shared(U))) const(T) => nomatch -+ // foo(U:wild(shared(U))) immutable(T) => nomatch -+ // foo(U:wild(shared(U))) shared(T) => nomatch -+ // foo(U:wild(shared(U))) const(shared(T)) => nomatch -+ // foo(U:wild(shared(U))) wild(T) => nomatch -+ // foo(U:immutable(U)) wild(shared(T)) => nomatch -+ // foo(U:const(shared(U))) wild(shared(T)) => nomatch -+ // foo(U:wild(U)) wild(shared(T)) => nomatch - m = MATCHnomatch; - break; - -@@ -1360,104 +1594,45 @@ MATCH TemplateDeclaration::deduceFunctio - t->objects[i] = tt; - } - declareParameter(paramscope, tp, t); -- goto L2; - } -- fptupindex = IDX_NOTFOUND; -+ argi += tuple_dim; -+ continue; - } -- } - --L1: -- if (nfparams == nfargs) -- ; -- else if (nfargs > nfparams) -- { -- if (fvarargs == 0) -- goto Lnomatch; // too many args, no match -- match = MATCHconvert; // match ... with a conversion -- } -- --L2: --#if DMDV2 -- if (ethis) -- { -- // Match 'ethis' to any TemplateThisParameter's -- for (size_t i = 0; i < parameters->dim; i++) -- { TemplateParameter *tp = (*parameters)[i]; -- TemplateThisParameter *ttp = tp->isTemplateThisParameter(); -- if (ttp) -- { MATCH m; -- -- Type *t = new TypeIdentifier(0, ttp->ident); -- m = ethis->type->deduceType(paramscope, t, parameters, &dedtypes); -- if (!m) -- goto Lnomatch; -- if (m < match) -- match = m; // pick worst match -- } -- } -- -- // Match attributes of ethis against attributes of fd -- if (fd->type && !fd->isCtorDeclaration()) -- { -- Type *tthis = ethis->type; -- unsigned mod = fd->type->mod; -- StorageClass stc = scope->stc | fd->storage_class2; -- // Propagate parent storage class (see bug 5504) -- Dsymbol *p = parent; -- while (p->isTemplateDeclaration() || p->isTemplateInstance()) -- p = p->parent; -- AggregateDeclaration *ad = p->isAggregateDeclaration(); -- if (ad) -- stc |= ad->storage_class; -- -- if (stc & (STCshared | STCsynchronized)) -- mod |= MODshared; -- if (stc & STCimmutable) -- mod |= MODimmutable; -- if (stc & STCconst) -- mod |= MODconst; -- if (stc & STCwild) -- mod |= MODwild; -- // Fix mod -- if (mod & MODimmutable) -- mod = MODimmutable; -- if (mod & MODconst) -- mod &= ~STCwild; -- if (tthis->mod != mod) -- { -- if (!MODmethodConv(tthis->mod, mod)) -- goto Lnomatch; -- if (MATCHconst < match) -- match = MATCHconst; -+ // If parameter type doesn't depend on inferred template parameters, -+ // semantic it to get actual type. -+ if (!inferparams || !prmtype->reliesOnTident(inferparams)) -+ { -+ // should copy prmtype to avoid affecting semantic result -+ prmtype = prmtype->syntaxCopy()->semantic(fd->loc, paramscope); -+ -+ if (prmtype->ty == Ttuple) -+ { -+ TypeTuple *tt = (TypeTuple *)prmtype; -+ size_t tt_dim = tt->arguments->dim; -+ for (size_t j = 0; j < tt_dim; j++, ++argi) -+ { -+ Parameter *p = (*tt->arguments)[j]; -+ if (j == tt_dim - 1 && fvarargs == 2 && parami + 1 == nfparams && argi < nfargs) -+ { -+ prmtype = p->type; -+ goto Lvarargs; -+ } -+ if (argi >= nfargs) -+ { -+ if (p->defaultArg) -+ continue; -+ goto Lnomatch; -+ } -+ Expression *farg = (*fargs)[argi]; -+ if (!farg->implicitConvTo(p->type)) -+ goto Lnomatch; -+ } -+ continue; - } - } -- } --#endif -- -- // Loop through the function parameters -- for (size_t parami = 0; parami < nfparams; parami++) -- { -- /* Skip over function parameters which wound up -- * as part of a template tuple parameter. -- */ -- if (parami == fptupindex) -- continue; -- /* Set i = index into function arguments -- * Function parameters correspond to function arguments as follows. -- * Note that tuple_dim may be zero, and there may be default or -- * variadic arguments at the end. -- * arg [0..fptupindex] == param[0..fptupindex] -- * arg [fptupindex..fptupindex+tuple_dim] == param[fptupindex] -- * arg[fputupindex+dim.. ] == param[fptupindex+1.. ] -- */ -- size_t i = parami; -- if (fptupindex != IDX_NOTFOUND && parami > fptupindex) -- i += tuple_dim - 1; -- -- Parameter *fparam = Parameter::getNth(fparameters, parami); -- Type *prmtype = fparam->type; - -- if (i >= nfargs) // if not enough arguments -+ if (argi >= nfargs) // if not enough arguments - { - if (fparam->defaultArg) - { /* Default arguments do not participate in template argument -@@ -1468,7 +1643,7 @@ L2: - } - else - { -- Expression *farg = (*fargs)[i]; -+ Expression *farg = (*fargs)[argi]; - - // Check invalid arguments to detect errors early. - if (farg->op == TOKerror || farg->type->ty == Terror) -@@ -1481,28 +1656,31 @@ Lretry: - #endif - Type *argtype = farg->type; - -- // Apply function parameter storage classes to parameter types -- prmtype = prmtype->addStorageClass(fparam->storageClass); -- -- // If parameter type doesn't depend on inferred template parameters, -- // semantic it to get actual type. -- if (!inferparams || !prmtype->reliesOnTident(inferparams)) -- { -- // should copy prmtype to avoid affecting semantic result -- prmtype = prmtype->syntaxCopy()->semantic(fd->loc, paramscope); -- } -- - #if DMDV2 -- /* Allow string literals which are type [] to match with [dim] -+ /* Allow expressions that have CT-known boundaries and type [] to match with [dim] - */ -- if (farg->op == TOKstring) -- { StringExp *se = (StringExp *)farg; -- if (!se->committed && argtype->ty == Tarray && -- prmtype->toBasetype()->ty == Tsarray) -- { -- argtype = new TypeSArray(argtype->nextOf(), new IntegerExp(se->loc, se->len, Type::tindex)); -- argtype = argtype->semantic(se->loc, NULL); -- argtype = argtype->invariantOf(); -+ Type *taai; -+ if ( argtype->ty == Tarray && -+ (prmtype->ty == Tsarray || -+ prmtype->ty == Taarray && (taai = ((TypeAArray *)prmtype)->index)->ty == Tident && -+ ((TypeIdentifier *)taai)->idents.dim == 0)) -+ { -+ if (farg->op == TOKstring) -+ { -+ StringExp *se = (StringExp *)farg; -+ argtype = TypeSArray::makeType(se->loc, argtype->nextOf(), se->len); -+ } -+ else if (farg->op == TOKslice) -+ { -+ SliceExp *se = (SliceExp *)farg; -+ Type *tsa = se->toStaticArrayType(); -+ if (tsa) -+ argtype = tsa; -+ } -+ else if (farg->op == TOKarrayliteral) -+ { -+ ArrayLiteralExp *ae = (ArrayLiteralExp *)farg; -+ argtype = TypeSArray::makeType(ae->loc, argtype->nextOf(), ae->elements->dim); - } - } - -@@ -1511,7 +1689,7 @@ Lretry: - if (farg->op == TOKfunction) - { FuncExp *fe = (FuncExp *)farg; - Type *tp = prmtype; -- Expression *e = fe->inferType(tp, 1, parameters); -+ Expression *e = fe->inferType(tp, 1, paramscope, inferparams); - if (!e) - goto Lvarargs; - farg = e; -@@ -1532,7 +1710,7 @@ Lretry: - } - #endif - -- if (fvarargs == 2 && i + 1 == nfparams && i + 1 < nfargs) -+ if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs) - goto Lvarargs; - - unsigned wm = 0; -@@ -1590,9 +1768,17 @@ Lretry: - } - - if (m && (fparam->storageClass & (STCref | STCauto)) == STCref) -- { if (!farg->isLvalue()) -+ { -+ if (!farg->isLvalue()) - { -- goto Lnomatch; -+ if (farg->op == TOKstring && argtype->ty == Tsarray) -+ { -+ } -+ else if (farg->op == TOKslice && argtype->ty == Tsarray) -+ { // Allow conversion from T[lwr .. upr] to ref T[upr-lwr] -+ } -+ else -+ goto Lnomatch; - } - } - if (m && (fparam->storageClass & STCout)) -@@ -1606,6 +1792,7 @@ Lretry: - if (m) - { if (m < match) - match = m; // pick worst match -+ argi++; - continue; - } - } -@@ -1614,7 +1801,7 @@ Lretry: - /* The following code for variadic arguments closely - * matches TypeFunction::callMatch() - */ -- if (!(fvarargs == 2 && i + 1 == nfparams)) -+ if (!(fvarargs == 2 && parami + 1 == nfparams)) - goto Lnomatch; - - /* Check for match with function parameter T... -@@ -1629,12 +1816,12 @@ Lretry: - if (tb->ty == Tsarray) - { TypeSArray *tsa = (TypeSArray *)tb; - dinteger_t sz = tsa->dim->toInteger(); -- if (sz != nfargs - i) -+ if (sz != nfargs - argi) - goto Lnomatch; - } - else if (tb->ty == Taarray) - { TypeAArray *taa = (TypeAArray *)tb; -- Expression *dim = new IntegerExp(loc, nfargs - i, Type::tsize_t); -+ Expression *dim = new IntegerExp(loc, nfargs - argi, Type::tsize_t); - - size_t i = templateParameterLookup(taa->index, parameters); - if (i == IDX_NOTFOUND) -@@ -1644,7 +1831,7 @@ Lretry: - taa->index->resolve(loc, sc, &e, &t, &s); - if (!e) - goto Lnomatch; -- e = e->optimize(WANTvalue | WANTinterpret); -+ e = e->ctfeInterpret(); - e = e->implicitCastTo(sc, Type::tsize_t); - e = e->optimize(WANTvalue); - if (!dim->equals(e)) -@@ -1652,7 +1839,7 @@ Lretry: - } - else - { // This code matches code in TypeInstance::deduceType() -- TemplateParameter *tprm = parameters->tdata()[i]; -+ TemplateParameter *tprm = (*parameters)[i]; - TemplateValueParameter *tvp = tprm->isTemplateValueParameter(); - if (!tvp) - goto Lnomatch; -@@ -1664,7 +1851,7 @@ Lretry: - } - else - { -- Type *vt = tvp->valType->semantic(0, sc); -+ Type *vt = tvp->valType->semantic(Loc(), sc); - MATCH m = (MATCH)dim->implicitConvTo(vt); - if (!m) - goto Lnomatch; -@@ -1676,16 +1863,16 @@ Lretry: - } - case Tarray: - { TypeArray *ta = (TypeArray *)tb; -- for (; i < nfargs; i++) -+ for (; argi < nfargs; argi++) - { -- Expression *arg = (*fargs)[i]; -+ Expression *arg = (*fargs)[argi]; - assert(arg); - - if (arg->op == TOKfunction) - { FuncExp *fe = (FuncExp *)arg; - Type *tp = tb->nextOf(); - -- Expression *e = fe->inferType(tp, 1, parameters); -+ Expression *e = fe->inferType(tp, 1, paramscope, inferparams); - if (!e) - goto Lnomatch; - arg = e; -@@ -1730,19 +1917,24 @@ Lretry: - default: - goto Lnomatch; - } -+ ++argi; -+ } -+ //printf("-> argi = %d, nfargs = %d\n", argi, nfargs); -+ if (argi != nfargs && !fvarargs) -+ goto Lnomatch; - } - - Lmatch: - -- for (size_t i = nargsi; i < dedargs->dim; i++) -+ for (size_t i = ntargs; i < dedargs->dim; i++) - { - TemplateParameter *tparam = (*parameters)[i]; - //printf("tparam[%d] = %s\n", i, tparam->ident->toChars()); - /* For T:T*, the dedargs is the T*, dedtypes is the T - * But for function templates, we really need them to match - */ -- Object *oarg = (*dedargs)[i]; -- Object *oded = dedtypes[i]; -+ RootObject *oarg = (*dedargs)[i]; -+ RootObject *oded = dedtypes[i]; - //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded); - //if (oarg) printf("oarg: %s\n", oarg->toChars()); - //if (oded) printf("oded: %s\n", oded->toChars()); -@@ -1750,21 +1942,25 @@ Lmatch: - { - if (oded) - { -- if (tparam->specialization()) -+ if (tparam->specialization() || !tparam->isTemplateTypeParameter()) - { /* The specialization can work as long as afterwards - * the oded == oarg - */ -- Declaration *sparam; - (*dedargs)[i] = oded; -- MATCH m2 = tparam->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); -+ MATCH m2 = tparam->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, NULL); - //printf("m2 = %d\n", m2); - if (!m2) - goto Lnomatch; -- if (m2 < match) -- match = m2; // pick worst match -+ if (m2 < matchTiargs) -+ matchTiargs = m2; // pick worst match - if (dedtypes[i] != oded) - error("specialization not allowed for deduced parameter %s", tparam->ident->toChars()); - } -+ else -+ { -+ if (MATCHconvert < matchTiargs) -+ matchTiargs = MATCHconvert; -+ } - } - else - { oded = tparam->defaultArg(loc, paramscope); -@@ -1772,9 +1968,9 @@ Lmatch: - { - if (tp && // if tuple parameter and - fptupindex == IDX_NOTFOUND && // tuple parameter was not in function parameter list and -- nargsi == dedargs->dim - 1) // we're one argument short (i.e. no tuple argument) -+ ntargs == dedargs->dim - 1) // we're one argument short (i.e. no tuple argument) - { // make tuple argument an empty tuple -- oded = (Object *)new Tuple(); -+ oded = (RootObject *)new Tuple(); - } - else - goto Lnomatch; -@@ -1787,12 +1983,12 @@ Lmatch: - - #if DMDV2 - if (constraint) -- { /* Check to see if constraint is satisfied. -+ { -+ /* Check to see if constraint is satisfied. - * Most of this code appears twice; this is a good candidate for refactoring. - */ - makeParamNamesVisibleInConstraint(paramscope, fargs); - Expression *e = constraint->syntaxCopy(); -- paramscope->flags |= SCOPEstaticif; - - /* Detect recursive attempts to instantiate this template declaration, - * Bugzilla 4072 -@@ -1803,7 +1999,10 @@ Lmatch: - int nmatches = 0; - for (Previous *p = previous; p; p = p->prev) - { -- if (arrayObjectMatch(p->dedargs, dedargs, this, sc)) -+ if (arrayCheckRecursiveExpansion(p->dedargs, this, sc)) -+ goto Lnomatch; -+ -+ if (arrayObjectMatch(p->dedargs, dedargs)) - { - //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars()); - /* It must be a subscope of p->sc, other scope chains are not recursive -@@ -1827,8 +2026,7 @@ Lmatch: - - int nerrors = global.errors; - -- FuncDeclaration *fd = onemember && onemember->toAlias() ? -- onemember->toAlias()->isFuncDeclaration() : NULL; -+ FuncDeclaration *fd = f; - Dsymbol *s = parent; - while (s->isTemplateInstance() || s->isTemplateMixin()) - s = s->parent; -@@ -1840,7 +2038,11 @@ Lmatch: - fd->vthis = fd->declareThis(paramscope, ad); - } - -- e = e->semantic(paramscope); -+ Scope *scx = paramscope->startCTFE(); -+ scx->flags |= SCOPEstaticif; -+ e = e->semantic(scx); -+ e = resolveProperties(scx, e); -+ scx->endCTFE(); - - if (fd && fd->vthis) - fd->vthis = vthissave; -@@ -1873,7 +2075,7 @@ Lmatch: - - paramscope->pop(); - //printf("\tmatch %d\n", match); -- return (MATCH)(match | (matchTargsi<<4)); -+ return (MATCH)(match | (matchTiargs<<4)); - - Lnomatch: - paramscope->pop(); -@@ -1885,7 +2087,7 @@ Lnomatch: - * Declare template parameter tp with value o, and install it in the scope sc. - */ - --Object *TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o) -+RootObject *TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o) - { - //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o); - -@@ -1897,45 +2099,29 @@ Object *TemplateDeclaration::declarePara - Dsymbol *s; - VarDeclaration *v = NULL; - -- // See if tp->ident already exists with a matching definition -- Dsymbol *scopesym; -- s = sc->search(loc, tp->ident, &scopesym); -- if (s && scopesym == sc->scopesym) -- { -- TupleDeclaration *td = s->isTupleDeclaration(); -- if (va && td) -- { Tuple tup; -- tup.objects = *td->objects; -- if (match(va, &tup, this, sc)) -- { -- return o; -- } -- } -- } - if (ea && ea->op == TOKtype) - targ = ea->type; - else if (ea && ea->op == TOKimport) - sa = ((ScopeExp *)ea)->sds; - else if (ea && (ea->op == TOKthis || ea->op == TOKsuper)) - sa = ((ThisExp *)ea)->var; -+ else if (ea && ea->op == TOKfunction) -+ { -+ if (((FuncExp *)ea)->td) -+ sa = ((FuncExp *)ea)->td; -+ else -+ sa = ((FuncExp *)ea)->fd; -+ } - - if (targ) - { - //printf("type %s\n", targ->toChars()); -- s = new AliasDeclaration(0, tp->ident, targ); -+ s = new AliasDeclaration(Loc(), tp->ident, targ); - } - else if (sa) - { - //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars()); -- s = new AliasDeclaration(0, tp->ident, sa); -- } -- else if (ea && ea->op == TOKfunction) -- { -- if (((FuncExp *)ea)->td) -- sa = ((FuncExp *)ea)->td; -- else -- sa = ((FuncExp *)ea)->fd; -- s = new AliasDeclaration(0, tp->ident, sa); -+ s = new AliasDeclaration(Loc(), tp->ident, sa); - } - else if (ea) - { -@@ -1946,7 +2132,7 @@ Object *TemplateDeclaration::declarePara - Type *t = tvp ? tvp->valType : NULL; - - v = new VarDeclaration(loc, t, tp->ident, init); -- v->storage_class = STCmanifest; -+ v->storage_class = STCmanifest | STCtemplateparameter; - s = v; - } - else if (va) -@@ -1967,7 +2153,7 @@ Object *TemplateDeclaration::declarePara - /* So the caller's o gets updated with the result of semantic() being run on o - */ - if (v) -- return (Object *)v->init->toExpression(); -+ return (RootObject *)v->init->toExpression(); - return o; - } - -@@ -1993,310 +2179,468 @@ TemplateTupleParameter *TemplateDeclarat - * We can overload templates. - */ - --int TemplateDeclaration::isOverloadable() -+bool TemplateDeclaration::isOverloadable() - { -- return 1; -+ return true; - } - - /************************************************* - * Given function arguments, figure out which template function -- * to expand, and return that function. -- * If no match, give error message and return NULL. -+ * to expand, and return matching result. - * Input: -- * sc instantiation scope -+ * m matching result -+ * dstart the root of overloaded function templates - * loc instantiation location -- * targsi initial list of template arguments -- * ethis if !NULL, the 'this' pointer argument -+ * sc instantiation scope -+ * tiargs initial list of template arguments -+ * tthis if !NULL, the 'this' pointer argument - * fargs arguments to function -- * flags 1: do not issue error message on no match, just return NULL - */ - --FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, -- Objects *targsi, Expression *ethis, Expressions *fargs, int flags) -+void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc, -+ Objects *tiargs, Type *tthis, Expressions *fargs) - { -- MATCH m_best = MATCHnomatch; -- MATCH m_best2 = MATCHnomatch; -- TemplateDeclaration *td_ambig = NULL; -- TemplateDeclaration *td_best = NULL; -- Objects *tdargs = new Objects(); -- TemplateInstance *ti; -- FuncDeclaration *fd_best; -- - #if 0 -- printf("TemplateDeclaration::deduceFunctionTemplate() %s\n", toChars()); -- printf(" targsi:\n"); -- if (targsi) -- { for (size_t i = 0; i < targsi->dim; i++) -- { Object *arg = (*targsi)[i]; -+ printf("functionResolve() dstart = %s\n", dstart->toChars()); -+ printf(" tiargs:\n"); -+ if (tiargs) -+ { for (size_t i = 0; i < tiargs->dim; i++) -+ { RootObject *arg = (*tiargs)[i]; - printf("\t%s\n", arg->toChars()); - } - } - printf(" fargs:\n"); -- for (size_t i = 0; i < fargs->dim; i++) -+ for (size_t i = 0; i < (fargs ? fargs->dim : 0); i++) - { Expression *arg = (*fargs)[i]; - printf("\t%s %s\n", arg->type->toChars(), arg->toChars()); - //printf("\tty = %d\n", arg->type->ty); - } -- printf("stc = %llx\n", scope->stc); -+ //printf("stc = %llx\n", dstart->scope->stc); -+ //printf("match:t/f = %d/%d\n", ta_last, m->last); - #endif - -- for (TemplateDeclaration *td = this; td; td = td->overnext) -+ struct ParamDeduce -+ { -+ // context -+ Loc loc; -+ Scope *sc; -+ Type *tthis; -+ Objects *tiargs; -+ Expressions *fargs; -+ // result -+ Match *m; -+ int property; // 0: unintialized -+ // 1: seen @property -+ // 2: not @property -+ size_t ov_index; -+ TemplateDeclaration *td_best; -+ MATCH ta_last; -+ Objects *tdargs; -+ Type *tthis_best; -+ -+ static int fp(void *param, Dsymbol *s) -+ { -+ if (FuncDeclaration *fd = s->isFuncDeclaration()) -+ return ((ParamDeduce *)param)->fp(fd); -+ if (TemplateDeclaration *td = s->isTemplateDeclaration()) -+ return ((ParamDeduce *)param)->fp(td); -+ return 0; -+ } -+ int fp(FuncDeclaration *fd) -+ { -+ // skip duplicates -+ if (fd == m->lastf) -+ return 0; -+ // explicitly specified tiargs never match to non template function -+ if (tiargs && tiargs->dim > 0) -+ return 0; -+ -+ //printf("fd = %s %s\n", fd->toChars(), fd->type->toChars()); -+ m->anyf = fd; -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ -+ int prop = (tf->isproperty) ? 1 : 2; -+ if (property == 0) -+ property = prop; -+ else if (property != prop) -+ error(fd->loc, "cannot overload both property and non-property functions"); -+ -+ /* For constructors, qualifier check will be opposite direction. -+ * Qualified constructor always makes qualified object, then will be checked -+ * that it is implicitly convertible to tthis. -+ */ -+ Type *tthis_fd = fd->needThis() ? tthis : NULL; -+ if (tthis_fd && fd->isCtorDeclaration()) -+ { -+ //printf("%s tf->mod = x%x tthis_fd->mod = x%x %d\n", tf->toChars(), -+ // tf->mod, tthis_fd->mod, fd->isolateReturn()); -+ if (MODimplicitConv(tf->mod, tthis_fd->mod) || -+ tf->isWild() && tf->isShared() == tthis_fd->isShared() || -+ fd->isolateReturn()/* && tf->isShared() == tthis_fd->isShared()*/) -+ { // Uniquely constructed object can ignore shared qualifier. -+ // TODO: Is this appropriate? -+ tthis_fd = NULL; -+ } -+ else -+ return 0; // MATCHnomatch -+ } -+ MATCH mfa = tf->callMatch(tthis_fd, fargs); -+ //printf("test1: mfa = %d\n", mfa); -+ if (mfa != MATCHnomatch) -+ { -+ if (mfa > m->last) goto LfIsBetter; -+ if (mfa < m->last) goto LlastIsBetter; -+ -+ /* See if one of the matches overrides the other. -+ */ -+ assert(m->lastf); -+ if (m->lastf->overrides(fd)) goto LlastIsBetter; -+ if (fd->overrides(m->lastf)) goto LfIsBetter; -+ -+ /* Try to disambiguate using template-style partial ordering rules. -+ * In essence, if f() and g() are ambiguous, if f() can call g(), -+ * but g() cannot call f(), then pick f(). -+ * This is because f() is "more specialized." -+ */ -+ { -+ MATCH c1 = fd->leastAsSpecialized(m->lastf); -+ MATCH c2 = m->lastf->leastAsSpecialized(fd); -+ //printf("c1 = %d, c2 = %d\n", c1, c2); -+ if (c1 > c2) goto LfIsBetter; -+ if (c1 < c2) goto LlastIsBetter; -+ } -+ -+ /* If the two functions are the same function, like: -+ * int foo(int); -+ * int foo(int x) { ... } -+ * then pick the one with the body. -+ */ -+ if (tf->equals(m->lastf->type) && -+ fd->storage_class == m->lastf->storage_class && -+ fd->parent == m->lastf->parent && -+ fd->protection == m->lastf->protection && -+ fd->linkage == m->lastf->linkage) -+ { -+ if ( fd->fbody && !m->lastf->fbody) goto LfIsBetter; -+ if (!fd->fbody && m->lastf->fbody) goto LlastIsBetter; -+ } -+ -+ Lambiguous: -+ m->nextf = fd; -+ m->count++; -+ return 0; -+ -+ LlastIsBetter: -+ return 0; -+ -+ LfIsBetter: -+ td_best = NULL; -+ ta_last = MATCHexact; -+ m->last = mfa; -+ m->lastf = fd; -+ tthis_best = tthis_fd; -+ ov_index = 0; -+ m->count = 1; -+ tdargs->setDim(0); -+ return 0; -+ } -+ return 0; -+ } -+ int fp(TemplateDeclaration *td) - { -- if (!td->semanticRun) -+ // skip duplicates -+ if (td == td_best) -+ return 0; -+ -+ if (!sc) -+ sc = td->scope; // workaround for Type::aliasthisOf -+ -+ if (td->semanticRun == PASSinit) -+ { -+ if (td->scope) -+ { -+ // Try to fix forward reference. Ungag errors while doing so. -+ Ungag ungag = td->ungagSpeculative(); -+ td->semantic(td->scope); -+ } -+ } -+ if (td->semanticRun == PASSinit) - { -- error("forward reference to template %s", td->toChars()); -+ ::error(loc, "forward reference to template %s", td->toChars()); - goto Lerror; - } -- if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration()) -+ FuncDeclaration *f; -+ f = td->onemember ? td->onemember/*->toAlias()*/->isFuncDeclaration() : NULL; -+ if (!f) - { -- if (!targsi) -- targsi = new Objects(); -- TemplateInstance *ti = new TemplateInstance(loc, td, targsi); -+ if (!tiargs) -+ tiargs = new Objects(); -+ TemplateInstance *ti = new TemplateInstance(loc, td, tiargs); - - Objects dedtypes; - dedtypes.setDim(td->parameters->dim); -- assert(td->semanticRun); -- MATCH m2 = td->matchWithInstance(ti, &dedtypes, fargs, 0); -- //printf("matchWithInstance = %d\n", m2); -- if (!m2 || m2 < m_best2) // no match or less match -- continue; -+ assert(td->semanticRun != PASSinit); -+ MATCH mta = td->matchWithInstance(sc, ti, &dedtypes, fargs, 0); -+ //printf("matchWithInstance = %d\n", mta); -+ if (!mta || mta < ta_last) // no match or less match -+ return 0; - - ti->semantic(sc, fargs); - if (!ti->inst) // if template failed to expand -- continue; -+ return 0; - - Dsymbol *s = ti->inst->toAlias(); -- FuncDeclaration *fd = s->isFuncDeclaration(); -- if (!fd) -- { -- td->error("is not a function template"); -+ if (!s->isFuncDeclaration() && !s->isTemplateDeclaration()) - goto Lerror; -- } -- fd = fd->overloadResolve(loc, ethis, fargs, flags); -+ FuncDeclaration *fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1); - if (!fd) -- continue; -+ return 0; -+ -+ Type *tthis_fd = fd->needThis() && !fd->isCtorDeclaration() ? tthis : NULL; - - TypeFunction *tf = (TypeFunction *)fd->type; -- MATCH m = (MATCH) tf->callMatch(fd->needThis() && !fd->isCtorDeclaration() ? ethis : NULL, fargs); -- if (m < m_best) -- continue; -+ MATCH mfa = tf->callMatch(tthis_fd, fargs); -+ if (mfa < m->last) -+ return 0; - - // td is the new best match -- td_ambig = NULL; -- assert((size_t)td->scope > 0x10000); -+ assert(td->scope); - td_best = td; -- fd_best = fd; -- m_best = m; -- m_best2 = m2; -+ property = 0; // (backward compatibility) -+ ta_last = mta; -+ m->last = mfa; -+ m->lastf = fd; -+ tthis_best = tthis_fd; -+ ov_index = 0; -+ m->nextf = NULL; -+ m->count = 1; - tdargs->setDim(dedtypes.dim); - memcpy(tdargs->tdata(), dedtypes.tdata(), tdargs->dim * sizeof(void *)); -- continue; -+ return 0; - } - -- MATCH m, m2; -- Objects dedargs; -- FuncDeclaration *fd = NULL; -- -- m = td->deduceFunctionTemplateMatch(sc, loc, targsi, ethis, fargs, &dedargs); -- m2 = (MATCH)(m >> 4); -- m = (MATCH)(m & 0xF); -- //printf("deduceFunctionTemplateMatch = %d, m2 = %d\n", m, m2); -- if (!m) // if no match -- continue; -- -- if (m2 < m_best2) -- goto Ltd_best; -- if (m2 > m_best2) -- goto Ltd; -- -- if (m < m_best) -- goto Ltd_best; -- if (m > m_best) -- goto Ltd; -- -+ //printf("td = %s\n", td->toChars()); -+ for (size_t ovi = 0; f; f = f->overnext0, ovi++) - { -- // Disambiguate by picking the most specialized TemplateDeclaration -- MATCH c1 = td->leastAsSpecialized(td_best, fargs); -- MATCH c2 = td_best->leastAsSpecialized(td, fargs); -- //printf("1: c1 = %d, c2 = %d\n", c1, c2); -+ Objects dedtypes; -+ FuncDeclaration *fd = NULL; -+ int x = td->deduceFunctionTemplateMatch(f, loc, sc, tiargs, tthis, fargs, &dedtypes); -+ MATCH mta = (MATCH)(x >> 4); -+ MATCH mfa = (MATCH)(x & 0xF); -+ //printf("match:t/f = %d/%d\n", mta, mfa); -+ if (!mfa) // if no match -+ continue; - -- if (c1 > c2) -- goto Ltd; -- else if (c1 < c2) -- goto Ltd_best; -- } -+ Type *tthis_fd = NULL; -+ if (f->isCtorDeclaration()) -+ { -+ // Constructor call requires additional check. -+ // For that, do instantiate in early stage. -+ fd = td->doHeaderInstantiation(sc, &dedtypes, tthis, fargs); -+ if (!fd) -+ goto Lerror; -+ -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ tthis_fd = fd->needThis() ? tthis : NULL; -+ if (tthis_fd) -+ { -+ assert(tf->next); -+ if (MODimplicitConv(tf->mod, tthis_fd->mod) || -+ tf->isWild() && tf->isShared() == tthis_fd->isShared() || -+ fd->isolateReturn()) -+ { -+ tthis_fd = NULL; -+ } -+ else -+ continue; // MATCHnomatch -+ } -+ } - -- if (!fd_best) -- { -- fd_best = td_best->doHeaderInstantiation(sc, tdargs, fargs); -- if (!fd_best) -- goto Lerror; -- } -- { -- fd = td->doHeaderInstantiation(sc, &dedargs, fargs); -- if (!fd) -- goto Lerror; -- } -- assert(fd && fd_best); -+ if (mta < ta_last) goto Ltd_best; -+ if (mta > ta_last) goto Ltd; - -- { -- // Disambiguate by tf->callMatch -- TypeFunction *tf1 = (TypeFunction *)fd->type; -- TypeFunction *tf2 = (TypeFunction *)fd_best->type; -- MATCH c1 = (MATCH) tf1->callMatch(fd->needThis() && !fd->isCtorDeclaration() ? ethis : NULL, fargs); -- MATCH c2 = (MATCH) tf2->callMatch(fd_best->needThis() && !fd_best->isCtorDeclaration() ? ethis : NULL, fargs); -- //printf("2: c1 = %d, c2 = %d\n", c1, c2); -+ if (mfa < m->last) goto Ltd_best; -+ if (mfa > m->last) goto Ltd; - -- if (c1 > c2) -- goto Ltd; -- if (c1 < c2) -- goto Ltd_best; -- } -+ if (td_best) -+ { -+ // Disambiguate by picking the most specialized TemplateDeclaration -+ MATCH c1 = td->leastAsSpecialized(sc, td_best, fargs); -+ MATCH c2 = td_best->leastAsSpecialized(sc, td, fargs); -+ //printf("1: c1 = %d, c2 = %d\n", c1, c2); -+ if (c1 > c2) goto Ltd; -+ if (c1 < c2) goto Ltd_best; -+ } - -- { -- // Disambiguate by picking the most specialized FunctionDeclaration -- MATCH c1 = fd->leastAsSpecialized(fd_best); -- MATCH c2 = fd_best->leastAsSpecialized(fd); -- //printf("3: c1 = %d, c2 = %d\n", c1, c2); -+ if (!m->lastf) -+ { -+ assert(td_best); -+ m->lastf = td_best->doHeaderInstantiation(sc, tdargs, tthis, fargs); -+ if (!m->lastf) goto Lerror; -+ tthis_best = m->lastf->needThis() ? tthis : NULL; -+ } -+ if (!fd) -+ { -+ fd = td->doHeaderInstantiation(sc, &dedtypes, tthis, fargs); -+ if (!fd) goto Lerror; -+ tthis_fd = fd->needThis() ? tthis : NULL; -+ } -+ assert(fd && m->lastf); -+ -+ { -+ // Disambiguate by tf->callMatch -+ TypeFunction *tf1 = (TypeFunction *)fd->type; -+ TypeFunction *tf2 = (TypeFunction *)m->lastf->type; -+ MATCH c1 = tf1->callMatch(tthis_fd, fargs); -+ MATCH c2 = tf2->callMatch(tthis_best, fargs); -+ //printf("2: c1 = %d, c2 = %d\n", c1, c2); -+ if (c1 > c2) goto Ltd; -+ if (c1 < c2) goto Ltd_best; -+ } -+ { -+ // Disambiguate by picking the most specialized FunctionDeclaration -+ MATCH c1 = fd->leastAsSpecialized(m->lastf); -+ MATCH c2 = m->lastf->leastAsSpecialized(fd); -+ //printf("3: c1 = %d, c2 = %d\n", c1, c2); -+ if (c1 > c2) goto Ltd; -+ if (c1 < c2) goto Ltd_best; -+ } -+ -+ Lambig: // td_best and td are ambiguous -+ //printf("Lambig\n"); -+ m->nextf = fd; // Caution! m->nextf isn't complete instantiated fd, so must not call toPrettyChars() -+ m->count++; -+ continue; -+ -+ Ltd_best: // td_best is the best match so far -+ continue; - -- if (c1 > c2) -- goto Ltd; -- if (c1 < c2) -- goto Ltd_best; -+ Ltd: // td is the new best match -+ assert(td->scope); -+ td_best = td; -+ property = 0; // (backward compatibility) -+ ta_last = mta; -+ m->last = mfa; -+ m->lastf = fd; -+ tthis_best = tthis_fd; -+ ov_index = ovi; -+ m->nextf = NULL; -+ m->count = 1; -+ tdargs->setDim(dedtypes.dim); -+ memcpy(tdargs->tdata(), dedtypes.tdata(), tdargs->dim * sizeof(void *)); -+ continue; - } -+ return 0; - -- Lambig: // td_best and td are ambiguous -- td_ambig = td; -- continue; -+ Lerror: -+ m->lastf = NULL; -+ m->count = 0; -+ m->last = MATCHnomatch; -+ return 1; -+ } -+ }; -+ ParamDeduce p; -+ // context -+ p.loc = loc; -+ p.sc = sc; -+ p.tthis = tthis; -+ p.tiargs = tiargs; -+ p.fargs = fargs; -+ -+ // result -+ p.m = m; -+ p.property = 0; -+ p.ov_index = 0; -+ p.td_best = NULL; -+ p.ta_last = m->last ? MATCHexact : MATCHnomatch; -+ p.tdargs = new Objects(); -+ p.tthis_best = NULL; -+ -+ FuncDeclaration *fd = dstart->isFuncDeclaration(); -+ TemplateDeclaration *td = dstart->isTemplateDeclaration(); -+ if (td && td->funcroot) -+ dstart = td->funcroot; -+ overloadApply(dstart, &p, &ParamDeduce::fp); -+ -+ //printf("td_best = %p, m->lastf = %p, match:t/f = %d/%d\n", td_best, m->lastf, mta, mfa); -+ if (p.td_best) -+ { -+ // Matches to template function -+ if (!p.td_best->onemember || !p.td_best->onemember->toAlias()->isFuncDeclaration()) -+ return; // goto Lerror? - -- Ltd_best: // td_best is the best match so far -- td_ambig = NULL; -- continue; -+ /* The best match is td_best with arguments tdargs. -+ * Now instantiate the template. -+ */ -+ assert(p.td_best->scope); -+ if (!sc) sc = p.td_best->scope; // workaround for Type::aliasthisOf -+ TemplateInstance *ti; -+ ti = new TemplateInstance(loc, p.td_best, p.tdargs); -+ ti->semantic(sc, fargs); -+ m->lastf = ti->toAlias()->isFuncDeclaration(); -+ if (!m->lastf) -+ goto Lerror; - -- Ltd: // td is the new best match -- td_ambig = NULL; -- assert((size_t)td->scope > 0x10000); -- td_best = td; -- fd_best = fd; -- m_best = m; -- m_best2 = m2; -- tdargs->setDim(dedargs.dim); -- memcpy(tdargs->tdata(), dedargs.tdata(), tdargs->dim * sizeof(void *)); -- continue; -- } -- if (!td_best) -- { -- if (!(flags & 1)) -+ // look forward instantiated overload function -+ // Dsymbol::oneMembers is alredy called in TemplateInstance::semantic. -+ // it has filled overnext0d -+ while (p.ov_index--) - { -- ::error(loc, "%s %s.%s does not match any function template declaration. Candidates are:", -- kind(), parent->toPrettyChars(), ident->toChars()); -- -- // Display candidate template functions -- int numToDisplay = 5; // sensible number to display -- for (TemplateDeclaration *td = this; td; td = td->overnext) -- { -- ::errorSupplemental(td->loc, "%s", td->toPrettyChars()); -- if (!global.params.verbose && --numToDisplay == 0) -- { -- // Too many overloads to sensibly display. -- // Just show count of remaining overloads. -- int remaining = 0; -- for (; td; td = td->overnext) -- ++remaining; -- if (remaining > 0) -- ::errorSupplemental(loc, "... (%d more, -v to show) ...", remaining); -- break; -- } -- } -+ m->lastf = m->lastf->overnext0; -+ assert(m->lastf); - } -- goto Lerror; -- } -- if (td_ambig) -- { -- ::error(loc, "%s %s.%s matches more than one template declaration, %s(%d):%s and %s(%d):%s", -- kind(), parent->toPrettyChars(), ident->toChars(), -- td_best->loc.filename, td_best->loc.linnum, td_best->toChars(), -- td_ambig->loc.filename, td_ambig->loc.linnum, td_ambig->toChars()); -- } - -- if (!td_best->onemember || !td_best->onemember->toAlias()->isFuncDeclaration()) -- return fd_best; -+ p.tthis_best = m->lastf->needThis() && !m->lastf->isCtorDeclaration() ? tthis : NULL; - -- /* The best match is td_best with arguments tdargs. -- * Now instantiate the template. -- */ -- assert((size_t)td_best->scope > 0x10000); -- ti = new TemplateInstance(loc, td_best, tdargs); -- ti->semantic(sc, fargs); -- fd_best = ti->toAlias()->isFuncDeclaration(); -- if (!fd_best) -- goto Lerror; -+ TypeFunction *tf = (TypeFunction *)m->lastf->type; -+ assert(tf->ty == Tfunction); -+ if (!tf->callMatch(p.tthis_best, fargs)) -+ goto Lerror; - -- if (FuncLiteralDeclaration *fld = fd_best->isFuncLiteralDeclaration()) -- { -- // Inside template constraint, nested reference check doesn't work correctly. -- if (!(sc->flags & SCOPEstaticif) && fld->tok == TOKreserved) -- { // change to non-nested -- fld->tok = TOKfunction; -- fld->vthis = NULL; -+ if (FuncLiteralDeclaration *fld = m->lastf->isFuncLiteralDeclaration()) -+ { -+ if ((sc->flags & SCOPEstaticif) || sc->intypeof) -+ { -+ // Inside template constraint, or inside typeof, -+ // nested reference check doesn't work correctly. -+ } -+ else if (fld->tok == TOKreserved) -+ { -+ // change to non-nested -+ fld->tok = TOKfunction; -+ fld->vthis = NULL; -+ } - } -- } - -- /* As Bugzilla 3682 shows, a template instance can be matched while instantiating -- * that same template. Thus, the function type can be incomplete. Complete it. -- * -- * Bugzilla 9208: For auto function, completion should be deferred to the end of -- * its semantic3. Should not complete it in here. -- */ -- { TypeFunction *tf = (TypeFunction *)fd_best->type; -- assert(tf->ty == Tfunction); -- if (tf->next && !fd_best->inferRetType) -+ /* As Bugzilla 3682 shows, a template instance can be matched while instantiating -+ * that same template. Thus, the function type can be incomplete. Complete it. -+ * -+ * Bugzilla 9208: For auto function, completion should be deferred to the end of -+ * its semantic3. Should not complete it in here. -+ */ -+ if (tf->next && !m->lastf->inferRetType) - { -- fd_best->type = tf->semantic(loc, sc); -+ m->lastf->type = tf->semantic(loc, sc); - } - } -- -- fd_best->functionSemantic(); -- -- return fd_best; -- -- Lerror: --#if DMDV2 -- if (!(flags & 1)) --#endif -+ else if (m->lastf) - { -- HdrGenState hgs; -- -- OutBuffer bufa; -- Objects *args = targsi; -- if (args) -- { for (size_t i = 0; i < args->dim; i++) -- { -- if (i) -- bufa.writeByte(','); -- Object *oarg = (*args)[i]; -- ObjectToCBuffer(&bufa, &hgs, oarg); -- } -- } -- -- OutBuffer buf; -- argExpTypesToCBuffer(&buf, fargs, &hgs); -- if (this->overnext) -- ::error(this->loc, "%s %s.%s cannot deduce template function from argument types !(%s)(%s)", -- kind(), parent->toPrettyChars(), ident->toChars(), -- bufa.toChars(), buf.toChars()); -- else -- error(loc, "cannot deduce template function from argument types !(%s)(%s)", -- bufa.toChars(), buf.toChars()); -+ // Matches to non template function -+ } -+ else -+ { -+ Lerror: -+ m->lastf = NULL; -+ m->count = 0; -+ m->last = MATCHnomatch; - } -- return NULL; - } - - /************************************************* - * Limited function template instantiation for using fd->leastAsSpecialized() - */ - FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(Scope *sc, -- Objects *tdargs, Expressions *fargs) -+ Objects *tdargs, Type *tthis, Expressions *fargs) - { - FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); - if (!fd) -@@ -2305,15 +2649,15 @@ FuncDeclaration *TemplateDeclaration::do - #if 0 - printf("doHeaderInstantiation this = %s\n", toChars()); - for (size_t i = 0; i < tdargs->dim; ++i) -- printf("\ttdargs[%d] = %s\n", i, ((Object *)tdargs->data[i])->toChars()); -+ printf("\ttdargs[%d] = %s\n", i, ((RootObject *)tdargs->data[i])->toChars()); - #endif - -- assert((size_t)scope > 0x10000); -+ assert(scope); - TemplateInstance *ti = new TemplateInstance(loc, this, tdargs); - ti->tinst = sc->tinst; - { -- ti->tdtypes.setDim(ti->tempdecl->parameters->dim); -- if (!ti->tempdecl->matchWithInstance(ti, &ti->tdtypes, fargs, 2)) -+ ti->tdtypes.setDim(parameters->dim); -+ if (!matchWithInstance(sc, ti, &ti->tdtypes, fargs, 2)) - return NULL; - } - -@@ -2321,20 +2665,37 @@ FuncDeclaration *TemplateDeclaration::do - - // function body and contracts are not need - //fd = fd->syntaxCopy(NULL)->isFuncDeclaration(); -- fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, fd->type->syntaxCopy()); -+ if (fd->isCtorDeclaration()) -+ fd = new CtorDeclaration(fd->loc, fd->endloc, fd->storage_class, fd->type->syntaxCopy()); -+ else -+ fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, fd->type->syntaxCopy()); - fd->parent = ti; - -- Scope *scope = this->scope; -+ Module *mi = sc->instantiatingModule ? sc->instantiatingModule : sc->module; - -+ Scope *scope = this->scope; - ti->argsym = new ScopeDsymbol(); - ti->argsym->parent = scope->parent; - scope = scope->push(ti->argsym); -+ scope->instantiatingModule = mi; -+ -+ bool hasttp = false; - - Scope *paramscope = scope->push(); - paramscope->stc = 0; - ti->declareParameters(paramscope); - paramscope->pop(); - -+ if (tthis) -+ { -+ // Match 'tthis' to any TemplateThisParameter's -+ for (size_t i = 0; i < parameters->dim; i++) -+ { TemplateParameter *tp = (*parameters)[i]; -+ TemplateThisParameter *ttp = tp->isTemplateThisParameter(); -+ if (ttp) -+ hasttp = true; -+ } -+ } - { - TypeFunction *tf = (TypeFunction *)fd->type; - if (tf && tf->ty == Tfunction) -@@ -2343,15 +2704,39 @@ FuncDeclaration *TemplateDeclaration::do - - Scope *sc2; - sc2 = scope->push(ti); -- sc2->parent = /*isnested ? sc->parent :*/ ti; -+ sc2->parent = /*enclosing ? sc->parent :*/ ti; - sc2->tinst = ti; - - { - Scope *sc = sc2; - sc = sc->push(); - -+ if (hasttp) -+ fd->type = fd->type->addMod(tthis->mod); -+ //printf("tthis = %s, fdtype = %s\n", tthis->toChars(), fd->type->toChars()); - if (fd->isCtorDeclaration()) -+ { - sc->flags |= SCOPEctor; -+ -+ Dsymbol *parent = toParent2(); -+ Type *tret; -+ AggregateDeclaration *ad = parent->isAggregateDeclaration(); -+ if (!ad || parent->isUnionDeclaration()) -+ { -+ tret = Type::tvoid; -+ } -+ else -+ { tret = ad->handle; -+ assert(tret); -+ tret = tret->addStorageClass(fd->storage_class | sc->stc); -+ tret = tret->addMod(fd->type->mod); -+ } -+ ((TypeFunction *)fd->type)->next = tret; -+ if (ad && ad->isStructDeclaration()) -+ ((TypeFunction *)fd->type)->isref = 1; -+ //printf("fd->type = %s\n", fd->type->toChars()); -+ } -+ fd->type = fd->type->addSTC(sc->stc); - fd->type = fd->type->semantic(fd->loc, sc); - sc = sc->pop(); - } -@@ -2460,6 +2845,117 @@ char *TemplateDeclaration::toChars() - return (char *)buf.extractData(); - } - -+PROT TemplateDeclaration::prot() -+{ -+ return protection; -+} -+ -+/**************************************************** -+ * Given a new instance tithis of this TemplateDeclaration, -+ * see if there already exists an instance. -+ * If so, return that existing instance. -+ */ -+ -+TemplateInstance *TemplateDeclaration::findExistingInstance(TemplateInstance *tithis, Expressions *fargs) -+{ -+ tithis->fargs = fargs; -+ hash_t hash = tithis->hashCode(); -+ -+ if (!buckets.dim) -+ { -+ buckets.setDim(7); -+ buckets.zero(); -+ } -+ size_t bi = hash % buckets.dim; -+ TemplateInstances *instances = buckets[bi]; -+ if (instances) -+ { -+ for (size_t i = 0; i < instances->dim; i++) -+ { -+ TemplateInstance *ti = (*instances)[i]; -+#if LOG -+ printf("\t%s: checking for match with instance %d (%p): '%s'\n", tithis->toChars(), i, ti, ti->toChars()); -+#endif -+ if (hash == ti->hash && -+ tithis->compare(ti) == 0) -+ { -+ //printf("hash = %p yes %d n = %d\n", hash, instances->dim, numinstances); -+ return ti; -+ } -+ } -+ } -+ //printf("hash = %p no\n", hash); -+ return NULL; // didn't find a match -+} -+ -+/******************************************** -+ * Add instance ti to TemplateDeclaration's table of instances. -+ * Return a handle we can use to later remove it if it fails instantiation. -+ */ -+ -+TemplateInstance *TemplateDeclaration::addInstance(TemplateInstance *ti) -+{ -+ /* See if we need to rehash -+ */ -+ if (numinstances > buckets.dim * 4) -+ { // rehash -+ //printf("rehash\n"); -+ size_t newdim = buckets.dim * 2 + 1; -+ TemplateInstances **newp = (TemplateInstances **)::calloc(newdim, sizeof(TemplateInstances *)); -+ assert(newp); -+ for (size_t bi = 0; bi < buckets.dim; ++bi) -+ { -+ TemplateInstances *instances = buckets[bi]; -+ if (instances) -+ { -+ for (size_t i = 0; i < instances->dim; i++) -+ { -+ TemplateInstance *ti1 = (*instances)[i]; -+ size_t newbi = ti1->hash % newdim; -+ TemplateInstances *newinstances = newp[newbi]; -+ if (!newinstances) -+ newp[newbi] = newinstances = new TemplateInstances(); -+ newinstances->push(ti1); -+ } -+ delete instances; -+ } -+ } -+ buckets.setDim(newdim); -+ memcpy(buckets.tdata(), newp, newdim * sizeof(TemplateInstance *)); -+ ::free(newp); -+ } -+ -+ // Insert ti into hash table -+ size_t bi = ti->hash % buckets.dim; -+ TemplateInstances *instances = buckets[bi]; -+ if (!instances) -+ buckets[bi] = instances = new TemplateInstances(); -+ instances->push(ti); -+ ++numinstances; -+ return ti; -+} -+ -+/******************************************* -+ * Remove TemplateInstance from table of instances. -+ * Input: -+ * handle returned by addInstance() -+ */ -+ -+void TemplateDeclaration::removeInstance(TemplateInstance *handle) -+{ -+ size_t bi = handle->hash % buckets.dim; -+ TemplateInstances *instances = buckets[bi]; -+ for (size_t i = 0; i < instances->dim; i++) -+ { -+ TemplateInstance *ti = (*instances)[i]; -+ if (handle == ti) -+ { instances->remove(i); -+ break; -+ } -+ } -+ --numinstances; -+} -+ - /* ======================== Type ============================================ */ - - /**** -@@ -2484,10 +2980,7 @@ size_t templateParameterLookup(Type *tpa - { - TypeIdentifier *tident = (TypeIdentifier *)tparam; - //printf("\ttident = '%s'\n", tident->toChars()); -- if (tident->idents.dim == 0) -- { -- return templateIdentifierLookup(tident->ident, parameters); -- } -+ return templateIdentifierLookup(tident->ident, parameters); - } - return IDX_NOTFOUND; - } -@@ -2549,6 +3042,63 @@ MATCH Type::deduceType(Scope *sc, Type * - - TemplateParameter *tp = (*parameters)[i]; - -+ TypeIdentifier *tident = (TypeIdentifier *)tparam; -+ if (tident->idents.dim > 0) -+ { -+ //printf("matching %s to %s\n", tparam->toChars(), toChars()); -+ Dsymbol *s = this->toDsymbol(sc); -+ for (size_t j = tident->idents.dim; j-- > 0; ) -+ { -+ RootObject *id = tident->idents[j]; -+ if (id->dyncast() == DYNCAST_IDENTIFIER) -+ { -+ if (!s || !s->parent) -+ goto Lnomatch; -+ Dsymbol *s2 = s->parent->searchX(Loc(), sc, id); -+ if (!s2) -+ goto Lnomatch; -+ s2 = s2->toAlias(); -+ //printf("[%d] s = %s %s, s2 = %s %s\n", j, s->kind(), s->toChars(), s2->kind(), s2->toChars()); -+ if (s != s2) -+ { -+ if (Type *t = s2->getType()) -+ { -+ if (s != t->toDsymbol(sc)) -+ goto Lnomatch; -+ } -+ else -+ goto Lnomatch; -+ } -+ s = s->parent; -+ } -+ else -+ goto Lnomatch; -+ } -+ //printf("[e] s = %s\n", s?s->toChars():"(null)"); -+ if (TemplateTypeParameter *ttp = tp->isTemplateTypeParameter()) -+ { -+ Type *tt = s->getType(); -+ if (!tt) -+ goto Lnomatch; -+ Type *at = (Type *)(*dedtypes)[i]; -+ if (!at || tt->equals(at)) -+ { -+ (*dedtypes)[i] = tt; -+ goto Lexact; -+ } -+ } -+ if (TemplateAliasParameter *tap = tp->isTemplateAliasParameter()) -+ { -+ Dsymbol *s2 = (Dsymbol *)(*dedtypes)[i]; -+ if (!s2 || s == s2) -+ { -+ (*dedtypes)[i] = s; -+ goto Lexact; -+ } -+ } -+ goto Lnomatch; -+ } -+ - // Found the corresponding parameter tp - if (!tp->isTemplateTypeParameter()) - goto Lnomatch; -@@ -2624,31 +3174,31 @@ MATCH Type::deduceType(Scope *sc, Type * - case X(0, MODconst | MODshared): - case X(0, MODwild): - case X(0, MODwild | MODshared): -- // foo(U:U) T => T -- // foo(U:U) const(T) => const(T) -- // foo(U:U) immutable(T) => immutable(T) -- // foo(U:U) shared(T) => shared(T) -- // foo(U:U) const(shared(T)) => const(shared(T)) -- // foo(U:U) wild(T) => wild(T) -- // foo(U:U) wild(shared(T)) => wild(shared(T)) -+ // foo(U:U) T => T -+ // foo(U:U) const(T) => const(T) -+ // foo(U:U) immutable(T) => immutable(T) -+ // foo(U:U) shared(T) => shared(T) -+ // foo(U:U) const(shared(T)) => const(shared(T)) -+ // foo(U:U) wild(T) => wild(T) -+ // foo(U:U) wild(shared(T)) => wild(shared(T)) - if (!at) - { (*dedtypes)[i] = tt; - goto Lexact; - } - break; - -- case X(MODconst, MODconst): -- case X(MODimmutable, MODimmutable): -- case X(MODshared, MODshared): -+ case X(MODconst, MODconst): -+ case X(MODimmutable, MODimmutable): -+ case X(MODshared, MODshared): - case X(MODconst | MODshared, MODconst | MODshared): -- case X(MODwild, MODwild): -- case X(MODwild | MODshared, MODwild | MODshared): -- // foo(U:const(U)) const(T) => T -- // foo(U:immutable(U)) immutable(T) => T -- // foo(U:shared(U)) shared(T) => T -- // foo(U:const(shared(U)) const(shared(T)) => T -- // foo(U:wild(U)) wild(T) => T -- // foo(U:wild(shared(U)) wild(shared(T)) => T -+ case X(MODwild, MODwild): -+ case X(MODwild | MODshared, MODwild | MODshared): -+ // foo(U:const(U)) const(T) => T -+ // foo(U:immutable(U)) immutable(T) => T -+ // foo(U:shared(U)) shared(T) => T -+ // foo(U:const(shared(U))) const(shared(T)) => T -+ // foo(U:wild(U)) wild(T) => T -+ // foo(U:wild(shared(U))) wild(shared(T)) => T - tt = mutableOf()->unSharedOf(); - if (!at) - { (*dedtypes)[i] = tt; -@@ -2656,17 +3206,17 @@ MATCH Type::deduceType(Scope *sc, Type * - } - break; - -- case X(MODconst, 0): -- case X(MODconst, MODimmutable): -- case X(MODconst, MODconst | MODshared): -+ case X(MODconst, 0): -+ case X(MODconst, MODimmutable): -+ case X(MODconst, MODconst | MODshared): - case X(MODconst | MODshared, MODimmutable): -- case X(MODconst, MODwild): -- case X(MODconst, MODwild | MODshared): -- // foo(U:const(U)) T => T -- // foo(U:const(U)) immutable(T) => T -- // foo(U:const(U)) const(shared(T)) => shared(T) -- // foo(U:const(shared(U)) immutable(T) => T -- // foo(U:const(U)) wild(shared(T)) => shared(T) -+ case X(MODconst, MODwild): -+ case X(MODconst, MODwild | MODshared): -+ // foo(U:const(U)) T => T -+ // foo(U:const(U)) immutable(T) => T -+ // foo(U:const(U)) const(shared(T)) => shared(T) -+ // foo(U:const(shared(U))) immutable(T) => T -+ // foo(U:const(U)) wild(shared(T)) => shared(T) - tt = mutableOf(); - if (!at) - { (*dedtypes)[i] = tt; -@@ -2674,12 +3224,12 @@ MATCH Type::deduceType(Scope *sc, Type * - } - break; - -- case X(MODshared, MODconst | MODshared): -+ case X(MODshared, MODconst | MODshared): - case X(MODconst | MODshared, MODshared): -- case X(MODshared, MODwild | MODshared): -- // foo(U:shared(U)) const(shared(T)) => const(T) -- // foo(U:const(shared(U)) shared(T) => T -- // foo(U:shared(U)) wild(shared(T)) => wild(T) -+ case X(MODshared, MODwild | MODshared): -+ // foo(U:shared(U)) const(shared(T)) => const(T) -+ // foo(U:const(shared(U))) shared(T) => T -+ // foo(U:shared(U)) wild(shared(T)) => wild(T) - tt = unSharedOf(); - if (!at) - { (*dedtypes)[i] = tt; -@@ -2688,7 +3238,7 @@ MATCH Type::deduceType(Scope *sc, Type * - break; - - case X(MODconst, MODshared): -- // foo(U:const(U)) shared(T) => shared(T) -+ // foo(U:const(U)) shared(T) => shared(T) - if (!at) - { (*dedtypes)[i] = tt; - goto Lconst; -@@ -2721,34 +3271,33 @@ MATCH Type::deduceType(Scope *sc, Type * - case X(MODimmutable, MODwild | MODshared): - case X(MODconst | MODshared, MODwild | MODshared): - case X(MODwild, MODwild | MODshared): -- -- // foo(U:immutable(U)) T => nomatch -- // foo(U:immutable(U)) const(T) => nomatch -- // foo(U:immutable(U)) shared(T) => nomatch -- // foo(U:immutable(U)) const(shared(T)) => nomatch -- // foo(U:const(U)) shared(T) => nomatch -- // foo(U:shared(U)) T => nomatch -- // foo(U:shared(U)) const(T) => nomatch -- // foo(U:shared(U)) immutable(T) => nomatch -- // foo(U:const(shared(U)) T => nomatch -- // foo(U:const(shared(U)) const(T) => nomatch -- // foo(U:immutable(U)) wild(T) => nomatch -- // foo(U:shared(U)) wild(T) => nomatch -- // foo(U:const(shared(U)) wild(T) => nomatch -- // foo(U:wild(U)) T => nomatch -- // foo(U:wild(U)) const(T) => nomatch -- // foo(U:wild(U)) immutable(T) => nomatch -- // foo(U:wild(U)) shared(T) => nomatch -- // foo(U:wild(U)) const(shared(T)) => nomatch -- // foo(U:wild(shared(U)) T => nomatch -- // foo(U:wild(shared(U)) const(T) => nomatch -- // foo(U:wild(shared(U)) immutable(T) => nomatch -- // foo(U:wild(shared(U)) shared(T) => nomatch -- // foo(U:wild(shared(U)) const(shared(T)) => nomatch -- // foo(U:wild(shared(U)) wild(T) => nomatch -- // foo(U:immutable(U)) wild(shared(T)) => nomatch -- // foo(U:const(shared(U))) wild(shared(T)) => nomatch -- // foo(U:wild(U)) wild(shared(T)) => nomatch -+ // foo(U:immutable(U)) T => nomatch -+ // foo(U:immutable(U)) const(T) => nomatch -+ // foo(U:immutable(U)) shared(T) => nomatch -+ // foo(U:immutable(U)) const(shared(T)) => nomatch -+ // foo(U:const(U)) shared(T) => nomatch -+ // foo(U:shared(U)) T => nomatch -+ // foo(U:shared(U)) const(T) => nomatch -+ // foo(U:shared(U)) immutable(T) => nomatch -+ // foo(U:const(shared(U))) T => nomatch -+ // foo(U:const(shared(U))) const(T) => nomatch -+ // foo(U:immutable(U)) wild(T) => nomatch -+ // foo(U:shared(U)) wild(T) => nomatch -+ // foo(U:const(shared(U))) wild(T) => nomatch -+ // foo(U:wild(U)) T => nomatch -+ // foo(U:wild(U)) const(T) => nomatch -+ // foo(U:wild(U)) immutable(T) => nomatch -+ // foo(U:wild(U)) shared(T) => nomatch -+ // foo(U:wild(U)) const(shared(T)) => nomatch -+ // foo(U:wild(shared(U))) T => nomatch -+ // foo(U:wild(shared(U))) const(T) => nomatch -+ // foo(U:wild(shared(U))) immutable(T) => nomatch -+ // foo(U:wild(shared(U))) shared(T) => nomatch -+ // foo(U:wild(shared(U))) const(shared(T)) => nomatch -+ // foo(U:wild(shared(U))) wild(T) => nomatch -+ // foo(U:immutable(U)) wild(shared(T)) => nomatch -+ // foo(U:const(shared(U))) wild(shared(T)) => nomatch -+ // foo(U:wild(U)) wild(shared(T)) => nomatch - //if (!at) - goto Lnomatch; - break; -@@ -2807,7 +3356,12 @@ MATCH Type::deduceType(Scope *sc, Type * - } - - if (nextOf()) -+ { -+ if (tparam->deco && !tparam->hasWild()) -+ return implicitConvTo(tparam); -+ - return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes, wildmatch); -+ } - - Lexact: - return MATCHexact; -@@ -2899,24 +3453,9 @@ MATCH TypeSArray::deduceType(Scope *sc, - size_t i = templateIdentifierLookup(id, parameters); - if (i == IDX_NOTFOUND) - goto Lnomatch; -- TemplateParameter *tprm = (*parameters)[i]; -- TemplateValueParameter *tvp = tprm->isTemplateValueParameter(); -- if (!tvp) -+ TemplateParameter *tp = (*parameters)[i]; -+ if (!tp->matchArg(sc, dim, i, parameters, dedtypes, NULL)) - goto Lnomatch; -- Expression *e = (Expression *)(*dedtypes)[i]; -- if (e) -- { -- if (!dim->equals(e)) -- goto Lnomatch; -- } -- else -- { -- Type *vt = tvp->valType->semantic(0, sc); -- MATCH m = (MATCH)dim->implicitConvTo(vt); -- if (!m) -- goto Lnomatch; -- (*dedtypes)[i] = dim; -- } - return next->deduceType(sc, tparam->nextOf(), parameters, dedtypes, wildmatch); - } - } -@@ -3008,7 +3547,7 @@ MATCH TypeFunction::deduceType(Scope *sc - - /* See if existing tuple, and whether it matches or not - */ -- Object *o = (*dedtypes)[tupi]; -+ RootObject *o = (*dedtypes)[tupi]; - if (o) - { // Existing deduced argument must be a tuple, and must match - Tuple *t = isTuple(o); -@@ -3059,8 +3598,8 @@ MATCH TypeIdentifier::deduceType(Scope * - - for (size_t i = 0; i < idents.dim; i++) - { -- Identifier *id1 = idents[i]; -- Identifier *id2 = tp->idents[i]; -+ RootObject *id1 = idents[i]; -+ RootObject *id2 = tp->idents[i]; - - if (!id1->equals(id2)) - return MATCHnomatch; -@@ -3078,13 +3617,15 @@ MATCH TypeInstance::deduceType(Scope *sc - printf("\tthis = %d, ", ty); print(); - printf("\ttparam = %d, ", tparam->ty); tparam->print(); - #endif -+ TemplateDeclaration *tempdecl = tempinst->tempdecl->isTemplateDeclaration(); -+ assert(tempdecl); - - // Extra check - if (tparam && tparam->ty == Tinstance) - { - TypeInstance *tp = (TypeInstance *)tparam; - -- //printf("tempinst->tempdecl = %p\n", tempinst->tempdecl); -+ //printf("tempinst->tempdecl = %p\n", tempdecl); - //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl); - if (!tp->tempinst->tempdecl) - { //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars()); -@@ -3098,11 +3639,11 @@ MATCH TypeInstance::deduceType(Scope *sc - { /* Didn't find it as a parameter identifier. Try looking - * it up and seeing if is an alias. See Bugzilla 1454 - */ -- TypeIdentifier *tid = new TypeIdentifier(0, tp->tempinst->name); -+ TypeIdentifier *tid = new TypeIdentifier(Loc(), tp->tempinst->name); - Type *t; - Expression *e; - Dsymbol *s; -- tid->resolve(0, sc, &e, &t, &s); -+ tid->resolve(Loc(), sc, &e, &t, &s); - if (t) - { - s = t->toDsymbol(sc); -@@ -3115,32 +3656,17 @@ MATCH TypeInstance::deduceType(Scope *sc - { - s = s->toAlias(); - TemplateDeclaration *td = s->isTemplateDeclaration(); -- if (td && td == tempinst->tempdecl) -+ if (td && td == tempdecl) - goto L2; - } - goto Lnomatch; - } - TemplateParameter *tpx = (*parameters)[i]; -- // This logic duplicates tpx->matchArg() -- TemplateAliasParameter *ta = tpx->isTemplateAliasParameter(); -- if (!ta) -- goto Lnomatch; -- Object *sa = tempinst->tempdecl; -- if (!sa) -+ if (!tpx->matchArg(sc, tempdecl, i, parameters, dedtypes, NULL)) - goto Lnomatch; -- if (ta->specAlias && sa != ta->specAlias) -- goto Lnomatch; -- if ((*dedtypes)[i]) -- { // Must match already deduced symbol -- Object *s = (*dedtypes)[i]; -- -- if (s != sa) -- goto Lnomatch; -- } -- (*dedtypes)[i] = sa; - } - } -- else if (tempinst->tempdecl != tp->tempinst->tempdecl) -+ else if (tempdecl != tp->tempinst->tempdecl) - goto Lnomatch; - - L2: -@@ -3148,7 +3674,7 @@ MATCH TypeInstance::deduceType(Scope *sc - for (size_t i = 0; 1; i++) - { - //printf("\ttest: tempinst->tiargs[%d]\n", i); -- Object *o1 = NULL; -+ RootObject *o1 = NULL; - if (i < tempinst->tiargs->dim) - o1 = (*tempinst->tiargs)[i]; - else if (i < tempinst->tdtypes.dim && i < tp->tempinst->tiargs->dim) -@@ -3160,7 +3686,7 @@ MATCH TypeInstance::deduceType(Scope *sc - if (i >= tp->tempinst->tiargs->dim) - goto Lnomatch; - -- Object *o2 = (*tp->tempinst->tiargs)[i]; -+ RootObject *o2 = (*tp->tempinst->tiargs)[i]; - Type *t2 = isType(o2); - - size_t j; -@@ -3181,12 +3707,12 @@ MATCH TypeInstance::deduceType(Scope *sc - /* Create tuple from remaining args - */ - Tuple *vt = new Tuple(); -- size_t vtdim = (tempinst->tempdecl->isVariadic() -+ size_t vtdim = (tempdecl->isVariadic() - ? tempinst->tiargs->dim : tempinst->tdtypes.dim) - i; - vt->objects.setDim(vtdim); - for (size_t k = 0; k < vtdim; k++) - { -- Object *o; -+ RootObject *o; - if (k < tempinst->tiargs->dim) - o = (*tempinst->tiargs)[i + k]; - else // Pick up default arg -@@ -3197,7 +3723,9 @@ MATCH TypeInstance::deduceType(Scope *sc - Tuple *v = (Tuple *)(*dedtypes)[j]; - if (v) - { -- if (!match(v, vt, tempinst->tempdecl, sc)) -+ if (checkRecursiveExpansion(v, tempdecl, sc)) -+ goto Lnomatch; -+ if (!match(v, vt)) - goto Lnomatch; - } - else -@@ -3234,19 +3762,29 @@ MATCH TypeInstance::deduceType(Scope *sc - { - Le: - e1 = e1->ctfeInterpret(); -+ -+ /* If it is one of the template parameters for this template, -+ * we should not attempt to interpret it. It already has a value. -+ */ -+ if (e2->op == TOKvar && -+ (((VarExp *)e2)->var->storage_class & STCtemplateparameter)) -+ { -+ /* -+ * (T:Number!(e2), int e2) -+ */ -+ j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters); -+ if (j != IDX_NOTFOUND) -+ goto L1; -+ // The template parameter was not from this template -+ // (it may be from a parent template, for example) -+ } -+ - e2 = e2->ctfeInterpret(); - - //printf("e1 = %s, type = %s %d\n", e1->toChars(), e1->type->toChars(), e1->type->ty); - //printf("e2 = %s, type = %s %d\n", e2->toChars(), e2->type->toChars(), e2->type->ty); - if (!e1->equals(e2)) -- { if (e2->op == TOKvar) -- { -- /* -- * (T:Number!(e2), int e2) -- */ -- j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters); -- goto L1; -- } -+ { - if (!e2->implicitConvTo(e1->type)) - goto Lnomatch; - -@@ -3268,35 +3806,7 @@ MATCH TypeInstance::deduceType(Scope *sc - goto Lnomatch; - } - TemplateParameter *tp = (*parameters)[j]; -- // BUG: use tp->matchArg() instead of the following -- TemplateValueParameter *tv = tp->isTemplateValueParameter(); -- TemplateAliasParameter *ta = tp->isTemplateAliasParameter(); -- if (tv) -- { -- Expression *e = (Expression *)(*dedtypes)[j]; -- if (e) -- { -- if (!e1->equals(e)) -- goto Lnomatch; -- } -- else -- { Type *vt = tv->valType->semantic(0, sc); -- MATCH m = (MATCH)e1->implicitConvTo(vt); -- if (!m) -- goto Lnomatch; -- (*dedtypes)[j] = e1; -- } -- } -- else if (ta) -- { -- if (ta->specType) -- { -- if (!e1->type->equals(ta->specType)) -- goto Lnomatch; -- } -- (*dedtypes)[j] = e1; -- } -- else -+ if (!tp->matchArg(sc, e1, j, parameters, dedtypes, NULL)) - goto Lnomatch; - } - else if (s1 && s2) -@@ -3316,20 +3826,8 @@ MATCH TypeInstance::deduceType(Scope *sc - goto Lnomatch; - } - TemplateParameter *tp = (*parameters)[j]; -- // BUG: use tp->matchArg() instead of the following -- TemplateAliasParameter *ta = tp->isTemplateAliasParameter(); -- if (!ta) -+ if (!tp->matchArg(sc, s1, j, parameters, dedtypes, NULL)) - goto Lnomatch; -- Dsymbol *s = (Dsymbol *)(*dedtypes)[j]; -- if (s) -- { -- if (!s1->equals(s)) -- goto Lnomatch; -- } -- else -- { -- (*dedtypes)[j] = s1; -- } - } - else - goto Lnomatch; -@@ -3358,7 +3856,7 @@ MATCH TypeStruct::deduceType(Scope *sc, - { - if (ti && ti->toAlias() == sym) - { -- TypeInstance *t = new TypeInstance(0, ti); -+ TypeInstance *t = new TypeInstance(Loc(), ti); - return t->deduceType(sc, tparam, parameters, dedtypes, wildmatch); - } - -@@ -3367,8 +3865,8 @@ MATCH TypeStruct::deduceType(Scope *sc, - */ - TypeInstance *tpi = (TypeInstance *)tparam; - if (tpi->idents.dim) -- { Identifier *id = tpi->idents[tpi->idents.dim - 1]; -- if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id)) -+ { RootObject *id = tpi->idents[tpi->idents.dim - 1]; -+ if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals((Identifier *)id)) - { - Type *tparent = sym->parent->getType(); - if (tparent) -@@ -3405,6 +3903,12 @@ MATCH TypeEnum::deduceType(Scope *sc, Ty - if (sym != tp->sym) - return MATCHnomatch; - } -+ Type *tb = toBasetype(); -+ if (tb->ty == tparam->ty || -+ tb->ty == Tsarray && tparam->ty == Taarray) -+ { -+ return tb->deduceType(sc, tparam, parameters, dedtypes, wildmatch); -+ } - return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch); - } - -@@ -3451,7 +3955,7 @@ void deduceBaseClassParameters(BaseClass - tmpdedtypes->setDim(dedtypes->dim); - memcpy(tmpdedtypes->tdata(), dedtypes->tdata(), dedtypes->dim * sizeof(void *)); - -- TypeInstance *t = new TypeInstance(0, parti); -+ TypeInstance *t = new TypeInstance(Loc(), parti); - MATCH m = t->deduceType(sc, tparam, parameters, tmpdedtypes); - if (m != MATCHnomatch) - { -@@ -3492,7 +3996,7 @@ MATCH TypeClass::deduceType(Scope *sc, T - { - if (ti && ti->toAlias() == sym) - { -- TypeInstance *t = new TypeInstance(0, ti); -+ TypeInstance *t = new TypeInstance(Loc(), ti); - MATCH m = t->deduceType(sc, tparam, parameters, dedtypes, wildmatch); - // Even if the match fails, there is still a chance it could match - // a base class. -@@ -3505,8 +4009,8 @@ MATCH TypeClass::deduceType(Scope *sc, T - */ - TypeInstance *tpi = (TypeInstance *)tparam; - if (tpi->idents.dim) -- { Identifier *id = tpi->idents[tpi->idents.dim - 1]; -- if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id)) -+ { RootObject *id = tpi->idents[tpi->idents.dim - 1]; -+ if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals((Identifier *)id)) - { - Type *tparent = sym->parent->getType(); - if (tparent) -@@ -3610,6 +4114,45 @@ TemplateThisParameter *TemplateParamete - } - #endif - -+/******************************************* -+ * Match to a particular TemplateParameter. -+ * Input: -+ * i i'th argument -+ * tiargs[] actual arguments to template instance -+ * parameters[] template parameters -+ * dedtypes[] deduced arguments to template instance -+ * *psparam set to symbol declared and initialized to dedtypes[i] -+ */ -+ -+MATCH TemplateParameter::matchArg(Loc loc, Scope *sc, Objects *tiargs, -+ size_t i, TemplateParameters *parameters, Objects *dedtypes, -+ Declaration **psparam) -+{ -+ RootObject *oarg; -+ -+ if (i < tiargs->dim) -+ oarg = (*tiargs)[i]; -+ else -+ { -+ // Get default argument instead -+ oarg = defaultArg(loc, sc); -+ if (!oarg) -+ { -+ assert(i < dedtypes->dim); -+ // It might have already been deduced -+ oarg = (*dedtypes)[i]; -+ if (!oarg) -+ goto Lnomatch; -+ } -+ } -+ return matchArg(sc, oarg, i, parameters, dedtypes, psparam); -+ -+Lnomatch: -+ if (psparam) -+ *psparam = NULL; -+ return MATCHnomatch; -+} -+ - /* ======================== TemplateTypeParameter =========================== */ - - // type-parameter -@@ -3649,10 +4192,10 @@ void TemplateTypeParameter::declareParam - error(loc, "parameter '%s' multiply defined", ident->toChars()); - } - --void TemplateTypeParameter::semantic(Scope *sc) -+void TemplateTypeParameter::semantic(Scope *sc, TemplateParameters *parameters) - { - //printf("TemplateTypeParameter::semantic('%s')\n", ident->toChars()); -- if (specType) -+ if (specType && !specType->reliesOnTident(parameters)) - { - specType = specType->semantic(loc, sc); - } -@@ -3691,42 +4234,13 @@ Lnomatch: - return 0; - } - --/******************************************* -- * Match to a particular TemplateParameter. -- * Input: -- * i i'th argument -- * tiargs[] actual arguments to template instance -- * parameters[] template parameters -- * dedtypes[] deduced arguments to template instance -- * *psparam set to symbol declared and initialized to dedtypes[i] -- */ -- --MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, -+MATCH TemplateTypeParameter::matchArg(Scope *sc, RootObject *oarg, - size_t i, TemplateParameters *parameters, Objects *dedtypes, - Declaration **psparam) - { - //printf("TemplateTypeParameter::matchArg()\n"); -- Object *oarg; - MATCH m = MATCHexact; -- Type *ta; -- -- if (i < tiargs->dim) -- oarg = (*tiargs)[i]; -- else -- { // Get default argument instead -- oarg = defaultArg(loc, sc); -- if (!oarg) -- { assert(i < dedtypes->dim); -- // It might have already been deduced -- oarg = (*dedtypes)[i]; -- if (!oarg) -- { -- goto Lnomatch; -- } -- } -- } -- -- ta = isType(oarg); -+ Type *ta = isType(oarg); - if (!ta) - { - //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg)); -@@ -3770,18 +4284,20 @@ MATCH TemplateTypeParameter::matchArg(Sc - } - (*dedtypes)[i] = ta; - -- *psparam = new AliasDeclaration(loc, ident, ta); -+ if (psparam) -+ *psparam = new AliasDeclaration(loc, ident, ta); - //printf("\tm = %d\n", m); - return m; - - Lnomatch: -- *psparam = NULL; -+ if (psparam) -+ *psparam = NULL; - //printf("\tm = %d\n", MATCHnomatch); - return MATCHnomatch; - } - - --void TemplateTypeParameter::print(Object *oarg, Object *oded) -+void TemplateTypeParameter::print(RootObject *oarg, RootObject *oded) - { - printf(" %s\n", ident->toChars()); - -@@ -3830,13 +4346,13 @@ void *TemplateTypeParameter::dummyArg() - } - - --Object *TemplateTypeParameter::specialization() -+RootObject *TemplateTypeParameter::specialization() - { - return specType; - } - - --Object *TemplateTypeParameter::defaultArg(Loc loc, Scope *sc) -+RootObject *TemplateTypeParameter::defaultArg(Loc loc, Scope *sc) - { - Type *t; - -@@ -3890,7 +4406,7 @@ void TemplateThisParameter::toCBuffer(Ou - Dsymbol *TemplateAliasParameter::sdummy = NULL; - - TemplateAliasParameter::TemplateAliasParameter(Loc loc, Identifier *ident, -- Type *specType, Object *specAlias, Object *defaultAlias) -+ Type *specType, RootObject *specAlias, RootObject *defaultAlias) - : TemplateParameter(loc, ident) - { - this->ident = ident; -@@ -3922,13 +4438,13 @@ void TemplateAliasParameter::declarePara - error(loc, "parameter '%s' multiply defined", ident->toChars()); - } - --Object *aliasParameterSemantic(Loc loc, Scope *sc, Object *o) -+RootObject *aliasParameterSemantic(Loc loc, Scope *sc, RootObject *o, TemplateParameters *parameters) - { - if (o) - { - Expression *ea = isExpression(o); - Type *ta = isType(o); -- if (ta) -+ if (ta && (!parameters || !ta->reliesOnTident(parameters))) - { Dsymbol *s = ta->toDsymbol(sc); - if (s) - o = s; -@@ -3937,20 +4453,22 @@ Object *aliasParameterSemantic(Loc loc, - } - else if (ea) - { -+ sc = sc->startCTFE(); - ea = ea->semantic(sc); -+ sc = sc->endCTFE(); - o = ea->ctfeInterpret(); - } - } - return o; - } - --void TemplateAliasParameter::semantic(Scope *sc) -+void TemplateAliasParameter::semantic(Scope *sc, TemplateParameters *parameters) - { -- if (specType) -+ if (specType && !specType->reliesOnTident(parameters)) - { - specType = specType->semantic(loc, sc); - } -- specAlias = aliasParameterSemantic(loc, sc, specAlias); -+ specAlias = aliasParameterSemantic(loc, sc, specAlias, parameters); - #if 0 // Don't do semantic() until instantiation - if (defaultAlias) - defaultAlias = defaultAlias->semantic(loc, sc); -@@ -3985,7 +4503,7 @@ Lnomatch: - * } // because Sym template cannot - * void main() { S s; s.foo(); } // access to the valid 'this' symbol. - */ --bool isPseudoDsymbol(Object *o) -+bool isPseudoDsymbol(RootObject *o) - { - Dsymbol *s = isDsymbol(o); - Expression *e = isExpression(o); -@@ -4012,33 +4530,13 @@ bool isPseudoDsymbol(Object *o) - return false; - } - --MATCH TemplateAliasParameter::matchArg(Scope *sc, Objects *tiargs, -+MATCH TemplateAliasParameter::matchArg(Scope *sc, RootObject *oarg, - size_t i, TemplateParameters *parameters, Objects *dedtypes, - Declaration **psparam) - { -- Object *sa; -- Object *oarg; -- Expression *ea; -- Dsymbol *s; -- - //printf("TemplateAliasParameter::matchArg()\n"); -- -- if (i < tiargs->dim) -- oarg = (*tiargs)[i]; -- else -- { // Get default argument instead -- oarg = defaultArg(loc, sc); -- if (!oarg) -- { assert(i < dedtypes->dim); -- // It might have already been deduced -- oarg = (*dedtypes)[i]; -- if (!oarg) -- goto Lnomatch; -- } -- } -- -- sa = getDsymbol(oarg); -- ea = isExpression(oarg); -+ RootObject *sa = getDsymbol(oarg); -+ Expression *ea = isExpression(oarg); - if (ea && (ea->op == TOKthis || ea->op == TOKsuper)) - sa = ((ThisExp *)ea)->var; - else if (ea && ea->op == TOKimport) -@@ -4080,7 +4578,7 @@ MATCH TemplateAliasParameter::matchArg(S - Type *ta = isType(specAlias); - if (!ti || !ta) - goto Lnomatch; -- Type *t = new TypeInstance(0, ti); -+ Type *t = new TypeInstance(Loc(), ti); - MATCH m = t->deduceType(sc, ta, parameters, dedtypes); - if (m == MATCHnomatch) - goto Lnomatch; -@@ -4088,37 +4586,42 @@ MATCH TemplateAliasParameter::matchArg(S - } - else if ((*dedtypes)[i]) - { // Must match already deduced symbol -- Object *si = (*dedtypes)[i]; -+ RootObject *si = (*dedtypes)[i]; - - if (!sa || si != sa) - goto Lnomatch; - } - (*dedtypes)[i] = sa; - -- s = isDsymbol(sa); -- if (s) -- *psparam = new AliasDeclaration(loc, ident, s); -- else -+ if (psparam) - { -- assert(ea); -+ if (Dsymbol *s = isDsymbol(sa)) -+ { -+ *psparam = new AliasDeclaration(loc, ident, s); -+ } -+ else -+ { -+ assert(ea); - -- // Declare manifest constant -- Initializer *init = new ExpInitializer(loc, ea); -- VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init); -- v->storage_class = STCmanifest; -- v->semantic(sc); -- *psparam = v; -+ // Declare manifest constant -+ Initializer *init = new ExpInitializer(loc, ea); -+ VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init); -+ v->storage_class = STCmanifest; -+ v->semantic(sc); -+ *psparam = v; -+ } - } - return MATCHexact; - - Lnomatch: -- *psparam = NULL; -+ if (psparam) -+ *psparam = NULL; - //printf("\tm = %d\n", MATCHnomatch); - return MATCHnomatch; - } - - --void TemplateAliasParameter::print(Object *oarg, Object *oded) -+void TemplateAliasParameter::print(RootObject *oarg, RootObject *oded) - { - printf(" %s\n", ident->toChars()); - -@@ -4151,7 +4654,7 @@ void TemplateAliasParameter::toCBuffer(O - - - void *TemplateAliasParameter::dummyArg() --{ Object *s; -+{ RootObject *s; - - s = specAlias; - if (!s) -@@ -4164,15 +4667,15 @@ void *TemplateAliasParameter::dummyArg() - } - - --Object *TemplateAliasParameter::specialization() -+RootObject *TemplateAliasParameter::specialization() - { - return specAlias; - } - - --Object *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc) -+RootObject *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc) - { -- Object *da = defaultAlias; -+ RootObject *da = defaultAlias; - Type *ta = isType(defaultAlias); - if (ta) - { -@@ -4183,7 +4686,7 @@ Object *TemplateAliasParameter::defaultA - } - } - -- Object *o = aliasParameterSemantic(loc, sc, da); -+ RootObject *o = aliasParameterSemantic(loc, sc, da, NULL); - return o; - } - -@@ -4229,7 +4732,7 @@ void TemplateValueParameter::declarePara - sparam = v; - } - --void TemplateValueParameter::semantic(Scope *sc) -+void TemplateValueParameter::semantic(Scope *sc, TemplateParameters *parameters) - { - bool wasSame = (sparam->type == valType); - sparam->semantic(sc); -@@ -4251,9 +4754,11 @@ void TemplateValueParameter::semantic(Sc - - #if 0 // defer semantic analysis to arg match - if (specValue) -- { Expression *e = specValue; -- -+ { -+ Expression *e = specValue; -+ sc = sc->startCTFE(); - e = e->semantic(sc); -+ sc = sc->endCTFE(); - e = e->implicitCastTo(sc, valType); - e = e->ctfeInterpret(); - if (e->op == TOKint64 || e->op == TOKfloat64 || -@@ -4263,9 +4768,11 @@ void TemplateValueParameter::semantic(Sc - } - - if (defaultValue) -- { Expression *e = defaultValue; -- -+ { -+ Expression *e = defaultValue; -+ sc = sc->startCTFE(); - e = e->semantic(sc); -+ sc = sc->endCTFE(); - e = e->implicitCastTo(sc, valType); - e = e->ctfeInterpret(); - if (e->op == TOKint64) -@@ -4297,34 +4804,15 @@ Lnomatch: - return 0; - } - -- --MATCH TemplateValueParameter::matchArg(Scope *sc, -- Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, -+MATCH TemplateValueParameter::matchArg(Scope *sc, RootObject *oarg, -+ size_t i, TemplateParameters *parameters, Objects *dedtypes, - Declaration **psparam) - { - //printf("TemplateValueParameter::matchArg()\n"); - -- Initializer *init; -- Declaration *sparam; - MATCH m = MATCHexact; -- Expression *ei; -- Object *oarg; -- -- if (i < tiargs->dim) -- oarg = (*tiargs)[i]; -- else -- { // Get default argument instead -- oarg = defaultArg(loc, sc); -- if (!oarg) -- { assert(i < dedtypes->dim); -- // It might have already been deduced -- oarg = (*dedtypes)[i]; -- if (!oarg) -- goto Lnomatch; -- } -- } - -- ei = isExpression(oarg); -+ Expression *ei = isExpression(oarg); - Type *vt; - - if (!ei && oarg) -@@ -4337,6 +4825,11 @@ MATCH TemplateValueParameter::matchArg(S - ei = ei->semantic(sc); - if (!f->needThis()) - ei = resolveProperties(sc, ei); -+ /* If it was really a property, it will become a CallExp. -+ * If it stayed as a var, it cannot be interpreted. -+ */ -+ if (ei->op == TOKvar) -+ goto Lnomatch; - ei = ei->ctfeInterpret(); - } - else -@@ -4349,7 +4842,7 @@ MATCH TemplateValueParameter::matchArg(S - } - - //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty); -- vt = valType->semantic(0, sc); -+ vt = valType->semantic(loc, sc); - //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars()); - //printf("vt = %s\n", vt->toChars()); - -@@ -4359,6 +4852,11 @@ MATCH TemplateValueParameter::matchArg(S - //printf("m: %d\n", m); - if (!m) - goto Lnomatch; -+ if (m != MATCHexact) -+ { -+ ei = ei->implicitCastTo(sc, vt); -+ ei = ei->ctfeInterpret(); -+ } - } - - if (specValue) -@@ -4368,13 +4866,17 @@ MATCH TemplateValueParameter::matchArg(S - - Expression *e = specValue; - -+ sc = sc->startCTFE(); - e = e->semantic(sc); - e = resolveProperties(sc, e); -+ sc = sc->endCTFE(); - e = e->implicitCastTo(sc, vt); - e = e->ctfeInterpret(); - - ei = ei->syntaxCopy(); -+ sc = sc->startCTFE(); - ei = ei->semantic(sc); -+ sc = sc->endCTFE(); - ei = ei->implicitCastTo(sc, vt); - ei = ei->ctfeInterpret(); - //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars()); -@@ -4391,28 +4893,27 @@ MATCH TemplateValueParameter::matchArg(S - if (!ei || !ei->equals(e)) - goto Lnomatch; - } -- else if (m != MATCHexact) -- { -- ei = ei->implicitCastTo(sc, vt); -- ei = ei->ctfeInterpret(); -- } - } - (*dedtypes)[i] = ei; - -- init = new ExpInitializer(loc, ei); -- sparam = new VarDeclaration(loc, vt, ident, init); -- sparam->storage_class = STCmanifest; -- *psparam = sparam; -+ if (psparam) -+ { -+ Initializer *init = new ExpInitializer(loc, ei); -+ Declaration *sparam = new VarDeclaration(loc, vt, ident, init); -+ sparam->storage_class = STCmanifest; -+ *psparam = sparam; -+ } - return m; - - Lnomatch: - //printf("\tno match\n"); -- *psparam = NULL; -+ if (psparam) -+ *psparam = NULL; - return MATCHnomatch; - } - - --void TemplateValueParameter::print(Object *oarg, Object *oded) -+void TemplateValueParameter::print(RootObject *oarg, RootObject *oded) - { - printf(" %s\n", ident->toChars()); - -@@ -4456,13 +4957,13 @@ void *TemplateValueParameter::dummyArg() - } - - --Object *TemplateValueParameter::specialization() -+RootObject *TemplateValueParameter::specialization() - { - return specValue; - } - - --Object *TemplateValueParameter::defaultArg(Loc loc, Scope *sc) -+RootObject *TemplateValueParameter::defaultArg(Loc loc, Scope *sc) - { - Expression *e = defaultValue; - if (e) -@@ -4506,7 +5007,7 @@ void TemplateTupleParameter::declarePara - error(loc, "parameter '%s' multiply defined", ident->toChars()); - } - --void TemplateTupleParameter::semantic(Scope *sc) -+void TemplateTupleParameter::semantic(Scope *sc, TemplateParameters *parameters) - { - } - -@@ -4522,12 +5023,10 @@ int TemplateTupleParameter::overloadMatc - return 0; - } - --MATCH TemplateTupleParameter::matchArg(Scope *sc, Objects *tiargs, -+MATCH TemplateTupleParameter::matchArg(Loc loc, Scope *sc, Objects *tiargs, - size_t i, TemplateParameters *parameters, Objects *dedtypes, - Declaration **psparam) - { -- //printf("TemplateTupleParameter::matchArg()\n"); -- - /* The rest of the actual arguments (tiargs[]) form the match - * for the variadic parameter. - */ -@@ -4551,13 +5050,26 @@ MATCH TemplateTupleParameter::matchArg(S - ovar->objects[j] = (*tiargs)[i + j]; - } - } -- *psparam = new TupleDeclaration(loc, ident, &ovar->objects); -+ return matchArg(sc, ovar, i, parameters, dedtypes, psparam); -+} -+ -+MATCH TemplateTupleParameter::matchArg(Scope *sc, RootObject *oarg, -+ size_t i, TemplateParameters *parameters, Objects *dedtypes, -+ Declaration **psparam) -+{ -+ //printf("TemplateTupleParameter::matchArg()\n"); -+ Tuple *ovar = isTuple(oarg); -+ if (!ovar) -+ return MATCHnomatch; - (*dedtypes)[i] = ovar; -+ -+ if (psparam) -+ *psparam = new TupleDeclaration(loc, ident, &ovar->objects); - return MATCHexact; - } - - --void TemplateTupleParameter::print(Object *oarg, Object *oded) -+void TemplateTupleParameter::print(RootObject *oarg, RootObject *oded) - { - printf(" %s... [", ident->toChars()); - Tuple *v = isTuple(oded); -@@ -4569,7 +5081,7 @@ void TemplateTupleParameter::print(Objec - if (i) - printf(", "); - -- Object *o = v->objects[i]; -+ RootObject *o = v->objects[i]; - - Dsymbol *sa = isDsymbol(o); - if (sa) -@@ -4602,13 +5114,13 @@ void *TemplateTupleParameter::dummyArg() - } - - --Object *TemplateTupleParameter::specialization() -+RootObject *TemplateTupleParameter::specialization() - { - return NULL; - } - - --Object *TemplateTupleParameter::defaultArg(Loc loc, Scope *sc) -+RootObject *TemplateTupleParameter::defaultArg(Loc loc, Scope *sc) - { - return NULL; - } -@@ -4625,20 +5137,19 @@ TemplateInstance::TemplateInstance(Loc l - this->name = ident; - this->tiargs = NULL; - this->tempdecl = NULL; -+ this->instantiatingModule = NULL; - this->inst = NULL; - this->tinst = NULL; - this->argsym = NULL; - this->aliasdecl = NULL; -- this->semanticRun = PASSinit; -- this->semantictiargsdone = 0; -+ this->semantictiargsdone = false; - this->withsym = NULL; - this->nest = 0; --#ifdef IN_GCC -- this->objFileModule = NULL; --#endif -- this->havetempdecl = 0; -- this->isnested = NULL; -- this->speculative = 0; -+ this->havetempdecl = false; -+ this->enclosing = NULL; -+ this->speculative = false; -+ this->hash = 0; -+ this->fargs = NULL; - } - - /***************** -@@ -4656,22 +5167,21 @@ TemplateInstance::TemplateInstance(Loc l - this->name = td->ident; - this->tiargs = tiargs; - this->tempdecl = td; -+ this->instantiatingModule = NULL; - this->inst = NULL; - this->tinst = NULL; - this->argsym = NULL; - this->aliasdecl = NULL; -- this->semanticRun = PASSinit; -- this->semantictiargsdone = 1; -+ this->semantictiargsdone = true; - this->withsym = NULL; - this->nest = 0; --#ifdef IN_GCC -- this->objFileModule = NULL; --#endif -- this->havetempdecl = 1; -- this->isnested = NULL; -- this->speculative = 0; -+ this->havetempdecl = true; -+ this->enclosing = NULL; -+ this->speculative = false; -+ this->hash = 0; -+ this->fargs = NULL; - -- assert((size_t)tempdecl->scope > 0x10000); -+ assert(tempdecl->scope); - } - - -@@ -4700,8 +5210,9 @@ Dsymbol *TemplateInstance::syntaxCopy(Ds - - ti->tiargs = arraySyntaxCopy(tiargs); - -- if (inst) -- tempdecl->ScopeDsymbol::syntaxCopy(ti); -+ TemplateDeclaration *td; -+ if (inst && tempdecl && (td = tempdecl->isTemplateDeclaration()) != NULL) -+ td->ScopeDsymbol::syntaxCopy(ti); - else - ScopeDsymbol::syntaxCopy(ti); - return ti; -@@ -4723,12 +5234,12 @@ void TemplateInstance::expandMembers(Sco - { - Dsymbol *s = (*members)[i]; - //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars()); -- //printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars()); --// if (isnested) -+ //printf("test: enclosing = %d, sc2->parent = %s\n", enclosing, sc2->parent->toChars()); -+// if (enclosing) - // s->parent = sc->parent; -- //printf("test3: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); -+ //printf("test3: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars()); - s->semantic(sc2); -- //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); -+ //printf("test4: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars()); - sc2->module->runDeferredSemantic(); - } - } -@@ -4745,27 +5256,7 @@ void TemplateInstance::tryExpandMembers( - fatal(); - } - --#ifndef IN_GCC --#if WINDOWS_SEH -- if(nest == 1) -- { -- // do not catch at every nesting level, because generating the output error might cause more stack -- // errors in the __except block otherwise -- __try -- { -- expandMembers(sc2); -- } -- __except (__ehfilter(GetExceptionInformation())) -- { -- global.gag = 0; // ensure error message gets printed -- error("recursive expansion"); -- fatal(); -- } -- } -- else --#endif --#endif -- expandMembers(sc2); -+ expandMembers(sc2); - nest--; - } - -@@ -4779,27 +5270,7 @@ void TemplateInstance::trySemantic3(Scop - error("recursive expansion"); - fatal(); - } --#ifndef IN_GCC --#if WINDOWS_SEH -- if(nest == 1) -- { -- // do not catch at every nesting level, because generating the output error might cause more stack -- // errors in the __except block otherwise -- __try -- { -- semantic3(sc2); -- } -- __except (__ehfilter(GetExceptionInformation())) -- { -- global.gag = 0; // ensure error message gets printed -- error("recursive expansion"); -- fatal(); -- } -- } -- else --#endif --#endif -- semantic3(sc2); -+ semantic3(sc2); - - --nest; - } -@@ -4807,6 +5278,28 @@ void TemplateInstance::trySemantic3(Scop - void TemplateInstance::semantic(Scope *sc, Expressions *fargs) - { - //printf("TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", toChars(), this, global.gag, sc); -+#if 0 -+ for (Dsymbol *s = this; s; s = s->parent) -+ { -+ printf("\t%s\n", s->toChars()); -+ } -+ printf("Scope\n"); -+ for (Scope *scx = sc; scx; scx = scx->enclosing) -+ { -+ printf("\t%s parent %s instantiatingModule %p\n", scx->module ? scx->module->toChars() : "null", scx->parent ? scx->parent->toChars() : "null", scx->instantiatingModule); -+ } -+#endif -+ -+ Module *mi = sc->instantiatingModule ? sc->instantiatingModule : sc->module; -+ -+ /* If a TemplateInstance is ever instantiated by non-root modules, -+ * we do not have to generate code for it, -+ * because it will be generated when the non-root module is compiled. -+ */ -+ if (!instantiatingModule || instantiatingModule->isRoot()) -+ instantiatingModule = mi; -+ //printf("mi = %s\n", mi->toChars()); -+ - #if LOG - printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); - #endif -@@ -4835,52 +5328,20 @@ void TemplateInstance::semantic(Scope *s - #if LOG - printf("\tdo semantic\n"); - #endif -- if (havetempdecl) -- { -- assert((size_t)tempdecl->scope > 0x10000); -- // Deduce tdtypes -- tdtypes.setDim(tempdecl->parameters->dim); -- if (!tempdecl->matchWithInstance(this, &tdtypes, fargs, 2)) -- { -- error("incompatible arguments for template instantiation"); -- inst = this; -- return; -- } -- } -- else -- { -- /* Find template declaration first. -- */ -- tempdecl = findTemplateDeclaration(sc); -- if (!tempdecl) -- { if (!sc->parameterSpecialization) -- inst = this; -- //printf("error return %p, %d\n", tempdecl, global.errors); -- return; // error recovery -- } -- -- /* Run semantic on each argument, place results in tiargs[] -- * (if we have tempdecl, then tiargs is already evaluated) -- */ -- semanticTiargs(sc); -- if (arrayObjectIsError(tiargs)) -- { if (!sc->parameterSpecialization) -- inst = this; -- //printf("error return %p, %d\n", tempdecl, global.errors); -- if (inst) -- inst->errors = true; -- return; // error recovery -- } -- -- unsigned errs = global.errors; -- tempdecl = findBestMatch(sc, fargs); -- if (!tempdecl || (errs != global.errors)) -- { if (!sc->parameterSpecialization) -- inst = this; -- //printf("error return %p, %d\n", tempdecl, global.errors); -- return; // error recovery -- } -+ /* Find template declaration first, -+ * then run semantic on each argument (place results in tiargs[]), -+ * last find most specialized template from overload list/set. -+ */ -+ if (!findTemplateDeclaration(sc) || -+ !semanticTiargs(sc) || -+ !findBestMatch(sc, fargs)) -+ { -+ inst = this; -+ inst->errors = true; -+ return; // error recovery - } -+ TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); -+ assert(tempdecl); - - // If tempdecl is a mixin, disallow it - if (tempdecl->ismixin) -@@ -4888,88 +5349,47 @@ void TemplateInstance::semantic(Scope *s - - hasNestedArgs(tiargs); - -+ arrayCheckRecursiveExpansion(&tdtypes, tempdecl, sc); -+ - /* See if there is an existing TemplateInstantiation that already - * implements the typeargs. If so, just refer to that one instead. - */ -- -- for (size_t i = 0; i < tempdecl->instances.dim; i++) - { -- TemplateInstance *ti = tempdecl->instances[i]; --#if LOG -- printf("\t%s: checking for match with instance %d (%p): '%s'\n", toChars(), i, ti, ti->toChars()); --#endif -- assert(tdtypes.dim == ti->tdtypes.dim); -- -- // Nesting must match -- if (isnested != ti->isnested) -+ TemplateInstance *ti = tempdecl->findExistingInstance(this, fargs); -+ if (ti) - { -- //printf("test2 isnested %s ti->isnested %s\n", isnested ? isnested->toChars() : "", ti->isnested ? ti->isnested->toChars() : ""); -- continue; -- } -- //printf("parent = %s, ti->parent = %s\n", tempdecl->parent->toPrettyChars(), ti->parent->toPrettyChars()); -- -- if (!arrayObjectMatch(&tdtypes, &ti->tdtypes, tempdecl, sc)) -- goto L1; -+ // It's a match -+ inst = ti; -+ parent = ti->parent; - -- /* Template functions may have different instantiations based on -- * "auto ref" parameters. -- */ -- if (fargs) -- { -- FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration(); -- if (fd) -+ // If both this and the previous instantiation were speculative, -+ // use the number of errors that happened last time. -+ if (inst->speculative && global.gag) - { -- Parameters *fparameters = fd->getParameters(NULL); -- size_t nfparams = Parameter::dim(fparameters); // Num function parameters -- for (size_t j = 0; j < nfparams && j < fargs->dim; j++) -- { Parameter *fparam = Parameter::getNth(fparameters, j); -- Expression *farg = (*fargs)[j]; -- if (fparam->storageClass & STCauto) // if "auto ref" -- { -- if (farg->isLvalue()) -- { if (!(fparam->storageClass & STCref)) -- goto L1; // auto ref's don't match -- } -- else -- { if (fparam->storageClass & STCref) -- goto L1; // auto ref's don't match -- } -- } -- } -+ global.errors += inst->errors; -+ global.gaggedErrors += inst->errors; - } -- } -- -- // It's a match -- inst = ti; -- parent = ti->parent; -- -- // If both this and the previous instantiation were speculative, -- // use the number of errors that happened last time. -- if (inst->speculative && global.gag) -- { -- global.errors += inst->errors; -- global.gaggedErrors += inst->errors; -- } - -- // If the first instantiation was speculative, but this is not: -- if (inst->speculative && !global.gag) -- { -- // If the first instantiation had failed, re-run semantic, -- // so that error messages are shown. -- if (inst->errors) -- goto L1; -- // It had succeeded, mark it is a non-speculative instantiation, -- // and reuse it. -- inst->speculative = 0; -- } -+ // If the first instantiation was speculative, but this is not: -+ if (inst->speculative && !global.gag) -+ { -+ // If the first instantiation had failed, re-run semantic, -+ // so that error messages are shown. -+ if (inst->errors) -+ goto L1; -+ // It had succeeded, mark it is a non-speculative instantiation, -+ // and reuse it. -+ inst->speculative = 0; -+ } - - #if LOG -- printf("\tit's a match with instance %p, %d\n", inst, inst->semanticRun); -+ printf("\tit's a match with instance %p, %d\n", inst, inst->semanticRun); - #endif -- return; -- -- L1: -- ; -+ if (!inst->instantiatingModule || inst->instantiatingModule->isRoot()) -+ inst->instantiatingModule = mi; -+ return; -+ } -+ L1: ; - } - - /* So, we need to implement 'this' instance. -@@ -4984,29 +5404,21 @@ void TemplateInstance::semantic(Scope *s - if (global.gag && sc->speculative) - speculative = 1; - -- size_t tempdecl_instance_idx = tempdecl->instances.dim; -- tempdecl->instances.push(this); -- parent = tempdecl->parent; -- //printf("parent = '%s'\n", parent->kind()); -- -- ident = genIdent(tiargs); // need an identifier for name mangling purposes. -+ TemplateInstance *tempdecl_instance_idx = tempdecl->addInstance(this); - --#if 1 -- if (isnested) -- parent = isnested; --#endif -+ parent = enclosing ? enclosing : tempdecl->parent; - //printf("parent = '%s'\n", parent->kind()); - -+ //getIdent(); -+ - // Add 'this' to the enclosing scope's members[] so the semantic routines - // will get called on the instance members. Store the place we added it to - // in target_symbol_list(_idx) so we can remove it later if we encounter - // an error. - #if 1 -- int dosemantic3 = 0; - Dsymbols *target_symbol_list = NULL; - size_t target_symbol_list_idx; - -- if (!sc->parameterSpecialization) - { Dsymbols *a; - - Scope *scx = sc; -@@ -5016,22 +5428,9 @@ void TemplateInstance::semantic(Scope *s - break; - #endif - --#ifdef IN_GCC -- /* For -femit-templates, templates are always emitted. -- Problem: This picks up templates that aren't even -- needed in the current module. */ -- if (d_gcc_force_templates() && scx && scx->scopesym) -- { -- //fprintf(stderr, "\t0: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars()); -- objFileModule = d_gcc_get_output_module(); -- a = objFileModule->members; -- } -- else --#endif -- - //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); -- if (scx && scx->scopesym && -- scx->scopesym->members && !scx->scopesym->isTemplateMixin() -+ if (scx && scx->scopesym && scx->scopesym->members && -+ !scx->scopesym->isTemplateMixin() - #if 0 // removed because it bloated compile times - /* The problem is if A imports B, and B imports A, and both A - * and B instantiate the same template, does the compilation of A -@@ -5043,45 +5442,43 @@ void TemplateInstance::semantic(Scope *s - #endif - ) - { -+ /* A module can have explicit template instance and its alias -+ * in module scope (e,g, `alias Base64Impl!('+', '/') Base64;`). -+ * When the module is just imported, compiler can assume that -+ * its instantiated code would be contained in the separately compiled -+ * obj/lib file (e.g. phobos.lib). So we can omit their semantic3 running. -+ */ -+ //if (scx->scopesym->isModule()) -+ // printf("module level instance %s\n", toChars()); -+ - //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); - a = scx->scopesym->members; --#ifdef IN_GCC -- Dsymbol * p = scx->scopesym; -- while (p) -- { -- TemplateInstance *i = p->isTemplateInstance(); -- Module *m = p->isModule(); -- if (i != NULL) -- { -- if (i->objFileModule) -- { -- objFileModule = i->objFileModule; -- break; -- } -- } -- else if (m != NULL) -- { -- objFileModule = m; // %% importedFrom ? -- break; -- } -- p = p->parent; -- } -- //fprintf(stderr, "\t1: adding %s to module %s via %s %s\n", tempdecl->toChars(), -- // objFileModule ? objFileModule->toChars() : "", sc->scopesym->kind(), sc->scopesym->toChars()); --#endif - } - else - { -- Module *m = (isnested ? sc : tempdecl->scope)->module->importedFrom; -- //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); -- a = m->members; -- if (m->semanticRun >= 3) -+ Dsymbol *s = enclosing ? enclosing : tempdecl->parent; -+ for (; s; s = s->toParent2()) - { -- dosemantic3 = 1; -+ if (s->isModule()) -+ break; - } --#ifdef IN_GCC -- objFileModule = m; --#endif -+ assert(s); -+ Module *m = (Module *)s; -+ if (!m->isRoot()) -+ { -+ //if (tinst && tinst->objFileModule) -+ // m = tinst->objFileModule; -+ //else -+ m = m->importedFrom; -+ } -+ //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); -+ a = m->members; -+ -+ /* Defer semantic3 running in order to avoid mutual forward reference. -+ * See test/runnable/test10736.d -+ */ -+ if (m->semanticRun >= PASSsemantic3done) -+ Module::addDeferredSemantic3(this); - } - for (size_t i = 0; 1; i++) - { -@@ -5099,11 +5496,45 @@ void TemplateInstance::semantic(Scope *s - #endif - - // Copy the syntax trees from the TemplateDeclaration -- members = Dsymbol::arraySyntaxCopy(tempdecl->members); -+ if (members && speculative) -+ {} // Don't copy again so they were previously created. -+ else -+ members = Dsymbol::arraySyntaxCopy(tempdecl->members); -+ -+ // todo for TemplateThisParameter -+ for (size_t i = 0; i < tempdecl->parameters->dim; i++) -+ { -+ if ((*tempdecl->parameters)[i]->isTemplateThisParameter() == NULL) -+ continue; -+ Type *t = isType((*tiargs)[i]); -+ assert(t); -+ -+ StorageClass stc = 0; -+ if (t->mod & MODimmutable) -+ stc |= STCimmutable; -+ else -+ { -+ if (t->mod & MODconst) -+ stc |= STCconst; -+ else if (t->mod & MODwild) -+ stc |= STCwild; -+ -+ if (t->mod & MODshared) -+ stc |= STCshared; -+ } -+ if (stc != 0) -+ { -+ //printf("t = %s, stc = x%llx\n", t->toChars(), stc); -+ Dsymbols *s = new Dsymbols(); -+ s->push(new StorageClassDeclaration(stc, members)); -+ members = s; -+ } -+ break; -+ } - - // Create our own scope for the template parameters - Scope *scope = tempdecl->scope; -- if (!tempdecl->semanticRun) -+ if (tempdecl->semanticRun == PASSinit) - { - error("template instantiation %s forward references template declaration %s", toChars(), tempdecl->toChars()); - return; -@@ -5115,6 +5546,7 @@ void TemplateInstance::semantic(Scope *s - argsym = new ScopeDsymbol(); - argsym->parent = scope->parent; - scope = scope->push(argsym); -+ scope->instantiatingModule = mi; - // scope->stc = 0; - - // Declare each template parameter as an alias for the argument type -@@ -5179,8 +5611,8 @@ void TemplateInstance::semantic(Scope *s - #endif - Scope *sc2; - sc2 = scope->push(this); -- //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars()); -- sc2->parent = /*isnested ? sc->parent :*/ this; -+ //printf("enclosing = %d, sc->parent = %s\n", enclosing, sc->parent->toChars()); -+ sc2->parent = /*enclosing ? sc->parent :*/ this; - sc2->tinst = this; - sc2->speculative = speculative; - -@@ -5194,8 +5626,8 @@ void TemplateInstance::semantic(Scope *s - */ - bool found_deferred_ad = false; - for (size_t i = 0; i < Module::deferred.dim; i++) -- { Dsymbol *sd = Module::deferred[i]; -- -+ { -+ Dsymbol *sd = Module::deferred[i]; - AggregateDeclaration *ad = sd->isAggregateDeclaration(); - if (ad && ad->parent && ad->parent->isTemplateInstance()) - { -@@ -5209,7 +5641,7 @@ void TemplateInstance::semantic(Scope *s - } - } - } -- if (found_deferred_ad) -+ if (found_deferred_ad || Module::deferred.dim) - goto Laftersemantic; - - /* ConditionalDeclaration may introduce eponymous declaration, -@@ -5238,14 +5670,15 @@ void TemplateInstance::semantic(Scope *s - * for initializers inside a function. - */ - // if (sc->parent->isFuncDeclaration()) -- -+ { - /* BUG 782: this has problems if the classes this depends on - * are forward referenced. Find a way to defer semantic() - * on this template. - */ - semantic2(sc2); -+ } - -- if (sc->func || dosemantic3) -+ if (sc->func) - { - trySemantic3(sc2); - } -@@ -5262,14 +5695,14 @@ void TemplateInstance::semantic(Scope *s - if (tinst) - { tinst->printInstantiationTrace(); - } -- errors = 1; -+ errors = true; - if (global.gag) - { - // Errors are gagged, so remove the template instance from the - // instance/symbol lists we added it to and reset our state to - // finish clean and so we can try to instantiate it again later - // (see bugzilla 4302 and 6602). -- tempdecl->instances.remove(tempdecl_instance_idx); -+ tempdecl->removeInstance(tempdecl_instance_idx); - if (target_symbol_list) - { - // Because we added 'this' in the last position above, we -@@ -5288,89 +5721,351 @@ void TemplateInstance::semantic(Scope *s - } - - --void TemplateInstance::semanticTiargs(Scope *sc) --{ -- //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); -- if (semantictiargsdone) -- return; -- semantictiargsdone = 1; -- semanticTiargs(loc, sc, tiargs, 0); --} -- --/********************************** -- * Input: -- * flags 1: replace const variables with their initializers -- * 2: don't devolve Parameter to Type -+/********************************************** -+ * Find template declaration corresponding to template instance. - */ - --void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags) -+bool TemplateInstance::findTemplateDeclaration(Scope *sc) - { -- // Run semantic on each argument, place results in tiargs[] -- //printf("+TemplateInstance::semanticTiargs()\n"); -- if (!tiargs) -- return; -- for (size_t j = 0; j < tiargs->dim; j++) -+ if (havetempdecl) -+ return true; -+ -+ //printf("TemplateInstance::findTemplateDeclaration() %s\n", toChars()); -+ if (!tempdecl) - { -- Object *o = (*tiargs)[j]; -- Type *ta = isType(o); -- Expression *ea = isExpression(o); -- Dsymbol *sa = isDsymbol(o); -+ /* Given: -+ * foo!( ... ) -+ * figure out which TemplateDeclaration foo refers to. -+ */ -+ Identifier *id = name; -+ Dsymbol *scopesym; -+ Dsymbol *s = sc->search(loc, id, &scopesym); -+ if (!s) -+ { -+ s = sc->search_correct(id); -+ if (s) -+ error("template '%s' is not defined, did you mean %s?", id->toChars(), s->toChars()); -+ else -+ error("template '%s' is not defined", id->toChars()); -+ return false; -+ } - -- //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta); -- if (ta) -+#if LOG -+ printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind()); -+ if (s->parent) -+ printf("s->parent = '%s'\n", s->parent->toChars()); -+#endif -+ withsym = scopesym->isWithScopeSymbol(); -+ -+ /* We might have found an alias within a template when -+ * we really want the template. -+ */ -+ TemplateInstance *ti; -+ if (s->parent && -+ (ti = s->parent->isTemplateInstance()) != NULL) - { -- //printf("type %s\n", ta->toChars()); -- // It might really be an Expression or an Alias -- ta->resolve(loc, sc, &ea, &ta, &sa); -- if (ea) goto Lexpr; -- if (sa) goto Ldsym; -- if (ta == NULL) -+ if (ti->tempdecl && ti->tempdecl->ident == id) - { -- assert(global.errors); -- ta = Type::terror; -+ /* This is so that one can refer to the enclosing -+ * template, even if it has the same name as a member -+ * of the template, if it has a !(arguments) -+ */ -+ TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration(); -+ assert(td); -+ if (td->overroot) // if not start of overloaded list of TemplateDeclaration's -+ td = td->overroot; // then get the start -+ s = td; - } -+ } - -- Ltype: -- if (ta->ty == Ttuple) -- { // Expand tuple -- TypeTuple *tt = (TypeTuple *)ta; -- size_t dim = tt->arguments->dim; -- tiargs->remove(j); -- if (dim) -- { tiargs->reserve(dim); -- for (size_t i = 0; i < dim; i++) -- { Parameter *arg = (*tt->arguments)[i]; -- if (flags & 2 && arg->ident) -- tiargs->insert(j + i, arg); -- else -- tiargs->insert(j + i, arg->type); -- } -- } -- j--; -- continue; -- } -- (*tiargs)[j] = ta; -+ if (!updateTemplateDeclaration(sc, s)) -+ { -+ return false; - } -- else if (ea) -+ } -+ assert(tempdecl); -+ -+ struct ParamFwdTi -+ { -+ static int fp(void *param, Dsymbol *s) -+ { -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (!td) -+ return 0; -+ -+ TemplateInstance *ti = (TemplateInstance *)param; -+ if (td->semanticRun == PASSinit) - { -- Lexpr: -- //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars()); -- ea = ea->semantic(sc); -- if (flags & 1) // only used by __traits, must not interpret the args -- ea = ea->optimize(WANTvalue); -- else if (ea->op == TOKvar) -- { /* This test is to skip substituting a const var with -- * its initializer. The problem is the initializer won't -- * match with an 'alias' parameter. Instead, do the -- * const substitution in TemplateValueParameter::matchArg(). -- */ -+ if (td->scope) -+ { -+ // Try to fix forward reference. Ungag errors while doing so. -+ Ungag ungag = td->ungagSpeculative(); -+ td->semantic(td->scope); - } -- else if (ea->op != TOKtuple && -- ea->op != TOKimport && ea->op != TOKtype && -- ea->op != TOKfunction && ea->op != TOKerror && -- ea->op != TOKthis && ea->op != TOKsuper) -+ if (td->semanticRun == PASSinit) - { -- int olderrs = global.errors; -+ ti->error("%s forward references template declaration %s", ti->toChars(), td->toChars()); -+ return 1; -+ } -+ } -+ return 0; -+ } -+ }; -+ // Look for forward references -+ OverloadSet *tovers = tempdecl->isOverloadSet(); -+ size_t overs_dim = tovers ? tovers->a.dim : 1; -+ for (size_t oi = 0; oi < overs_dim; oi++) -+ { -+ if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdTi::fp)) -+ return false; -+ } -+ return true; -+} -+ -+/********************************************** -+ * Confirm s is a valid template, then store it. -+ */ -+ -+bool TemplateInstance::updateTemplateDeclaration(Scope *sc, Dsymbol *s) -+{ -+ if (s) -+ { -+ Identifier *id = name; -+ s = s->toAlias(); -+ -+ /* If an OverloadSet, look for a unique member that is a template declaration -+ */ -+ OverloadSet *os = s->isOverloadSet(); -+ if (os) -+ { -+ s = NULL; -+ for (size_t i = 0; i < os->a.dim; i++) -+ { -+ Dsymbol *s2 = os->a[i]; -+ if (FuncDeclaration *f = s2->isFuncDeclaration()) -+ s2 = f->findTemplateDeclRoot(); -+ else -+ s2 = s2->isTemplateDeclaration(); -+ if (s2) -+ { -+ if (s) -+ { -+ tempdecl = os; -+ return true; -+ } -+ s = s2; -+ } -+ } -+ if (!s) -+ { -+ error("template '%s' is not defined", id->toChars()); -+ return false; -+ } -+ } -+ -+ /* It should be a TemplateDeclaration, not some other symbol -+ */ -+ if (FuncDeclaration *f = s->isFuncDeclaration()) -+ tempdecl = f->findTemplateDeclRoot(); -+ else -+ tempdecl = s->isTemplateDeclaration(); -+ if (!tempdecl) -+ { -+ if (!s->parent && global.errors) -+ return false; -+ if (!s->parent && s->getType()) -+ { -+ Dsymbol *s2 = s->getType()->toDsymbol(sc); -+ if (!s2) -+ { -+ error("%s is not a template declaration, it is a %s", id->toChars(), s->kind()); -+ return false; -+ } -+ s = s2; -+ } -+#ifdef DEBUG -+ //if (!s->parent) printf("s = %s %s\n", s->kind(), s->toChars()); -+#endif -+ //assert(s->parent); -+ TemplateInstance *ti = s->parent ? s->parent->isTemplateInstance() : NULL; -+ if (ti && -+ (ti->name == s->ident || -+ ti->toAlias()->ident == s->ident) -+ && -+ ti->tempdecl) -+ { -+ /* This is so that one can refer to the enclosing -+ * template, even if it has the same name as a member -+ * of the template, if it has a !(arguments) -+ */ -+ TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration(); -+ assert(td); -+ if (td->overroot) // if not start of overloaded list of TemplateDeclaration's -+ td = td->overroot; // then get the start -+ tempdecl = td; -+ } -+ else -+ { -+ error("%s is not a template declaration, it is a %s", id->toChars(), s->kind()); -+ return false; -+ } -+ } -+ } -+ return (tempdecl != NULL); -+} -+ -+bool TemplateInstance::semanticTiargs(Scope *sc) -+{ -+ //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); -+ if (semantictiargsdone) -+ return true; -+ semantictiargsdone = 1; -+ semanticTiargs(loc, sc, tiargs, 0); -+ return arrayObjectIsError(tiargs) == 0; -+} -+ -+/********************************** -+ * Return true if e could be valid only as a template value parameter. -+ * Return false if it might be an alias or tuple. -+ * (Note that even in this case, it could still turn out to be a value). -+ */ -+bool definitelyValueParameter(Expression *e) -+{ -+ // None of these can be value parameters -+ if (e->op == TOKtuple || e->op == TOKimport || -+ e->op == TOKtype || e->op == TOKdottype || -+ e->op == TOKtemplate || e->op == TOKdottd || -+ e->op == TOKfunction || e->op == TOKerror || -+ e->op == TOKthis || e->op == TOKsuper) -+ return false; -+ -+ if (e->op != TOKdotvar) -+ return true; -+ -+ /* Template instantiations involving a DotVar expression are difficult. -+ * In most cases, they should be treated as a value parameter, and interpreted. -+ * But they might also just be a fully qualified name, which should be treated -+ * as an alias. -+ */ -+ -+ // x.y.f cannot be a value -+ FuncDeclaration *f = ((DotVarExp *)e)->var->isFuncDeclaration(); -+ if (f) -+ return false; -+ -+ while (e->op == TOKdotvar) -+ { -+ e = ((DotVarExp *)e)->e1; -+ } -+ // this.x.y and super.x.y couldn't possibly be valid values. -+ if (e->op == TOKthis || e->op == TOKsuper) -+ return false; -+ -+ // e.type.x could be an alias -+ if (e->op == TOKdottype) -+ return false; -+ -+ // var.x.y is the only other possible form of alias -+ if (e->op != TOKvar) -+ return true; -+ -+ VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration(); -+ -+ // func.x.y is not an alias -+ if (!v) -+ return true; -+ -+ // TODO: Should we force CTFE if it is a global constant? -+ -+ return false; -+} -+ -+/********************************** -+ * Input: -+ * flags 1: replace const variables with their initializers -+ * 2: don't devolve Parameter to Type -+ */ -+ -+void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags) -+{ -+ // Run semantic on each argument, place results in tiargs[] -+ //printf("+TemplateInstance::semanticTiargs()\n"); -+ if (!tiargs) -+ return; -+ for (size_t j = 0; j < tiargs->dim; j++) -+ { -+ RootObject *o = (*tiargs)[j]; -+ Type *ta = isType(o); -+ Expression *ea = isExpression(o); -+ Dsymbol *sa = isDsymbol(o); -+ -+ //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta); -+ if (ta) -+ { -+ //printf("type %s\n", ta->toChars()); -+ // It might really be an Expression or an Alias -+ ta->resolve(loc, sc, &ea, &ta, &sa); -+ if (ea) goto Lexpr; -+ if (sa) goto Ldsym; -+ if (ta == NULL) -+ { -+ assert(global.errors); -+ ta = Type::terror; -+ } -+ -+ Ltype: -+ if (ta->ty == Ttuple) -+ { // Expand tuple -+ TypeTuple *tt = (TypeTuple *)ta; -+ size_t dim = tt->arguments->dim; -+ tiargs->remove(j); -+ if (dim) -+ { tiargs->reserve(dim); -+ for (size_t i = 0; i < dim; i++) -+ { Parameter *arg = (*tt->arguments)[i]; -+ if (flags & 2 && arg->ident) -+ tiargs->insert(j + i, arg); -+ else -+ tiargs->insert(j + i, arg->type); -+ } -+ } -+ j--; -+ continue; -+ } -+ (*tiargs)[j] = ta->merge2(); -+ } -+ else if (ea) -+ { -+ Lexpr: -+ //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars()); -+ if (!(flags & 1)) sc = sc->startCTFE(); -+ ea = ea->semantic(sc); -+ if (!(flags & 1)) sc = sc->endCTFE(); -+ if (flags & 1) // only used by __traits, must not interpret the args -+ { -+ VarDeclaration *v; -+ if (ea->op == TOKvar && (v = ((VarExp *)ea)->var->isVarDeclaration()) != NULL && -+ !(v->storage_class & STCtemplateparameter)) -+ { -+ if (v->sem < SemanticDone) -+ v->semantic(sc); -+ // skip optimization for variable symbols -+ } -+ else -+ { -+ ea = ea->optimize(WANTvalue); -+ } -+ } -+ else if (ea->op == TOKvar) -+ { /* This test is to skip substituting a const var with -+ * its initializer. The problem is the initializer won't -+ * match with an 'alias' parameter. Instead, do the -+ * const substitution in TemplateValueParameter::matchArg(). -+ */ -+ } -+ else if (definitelyValueParameter(ea)) -+ { -+ int olderrs = global.errors; - ea = ea->ctfeInterpret(); - if (global.errors != olderrs) - ea = new ErrorExp(); -@@ -5417,8 +6112,8 @@ void TemplateInstance::semanticTiargs(Lo - else if (fe->td) - { /* If template argument is a template lambda, - * get template declaration itself. */ -- sa = fe->td; -- goto Ldsym; -+ //sa = fe->td; -+ //goto Ldsym; - } - } - if (ea->op == TOKdotvar) -@@ -5453,13 +6148,26 @@ void TemplateInstance::semanticTiargs(Lo - j--; - continue; - } -+ if (FuncAliasDeclaration *fa = sa->isFuncAliasDeclaration()) -+ { -+ FuncDeclaration *f = fa->toAliasFunc(); -+ if (!fa->hasOverloads && f->isUnique()) -+ { -+ // Strip FuncAlias only when the aliased function -+ // does not have any overloads. -+ sa = f; -+ } -+ } - (*tiargs)[j] = sa; - - TemplateDeclaration *td = sa->isTemplateDeclaration(); -- if (td && !td->semanticRun && td->literal) -+ if (td && td->semanticRun == PASSinit && td->literal) - { - td->semantic(sc); - } -+ FuncDeclaration *fd = sa->isFuncDeclaration(); -+ if (fd) -+ fd->functionSemantic(); - } - else if (isParameter(o)) - { -@@ -5474,7 +6182,7 @@ void TemplateInstance::semanticTiargs(Lo - printf("-TemplateInstance::semanticTiargs()\n"); - for (size_t j = 0; j < tiargs->dim; j++) - { -- Object *o = (*tiargs)[j]; -+ RootObject *o = (*tiargs)[j]; - Type *ta = isType(o); - Expression *ea = isExpression(o); - Dsymbol *sa = isDsymbol(o); -@@ -5485,288 +6193,330 @@ void TemplateInstance::semanticTiargs(Lo - #endif - } - --/********************************************** -- * Find template declaration corresponding to template instance. -- */ -- --TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc) -+bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs) - { -- //printf("TemplateInstance::findTemplateDeclaration() %s\n", toChars()); -- if (!tempdecl) -+ if (havetempdecl) - { -- /* Given: -- * foo!( ... ) -- * figure out which TemplateDeclaration foo refers to. -- */ -- Dsymbol *s; -- Dsymbol *scopesym; -- Identifier *id; -- -- id = name; -- s = sc->search(loc, id, &scopesym); -- if (!s) -- { -- s = sc->search_correct(id); -- if (s) -- error("template '%s' is not defined, did you mean %s?", id->toChars(), s->toChars()); -- else -- error("template '%s' is not defined", id->toChars()); -- return NULL; -- } -- -- /* If an OverloadSet, look for a unique member that is a template declaration -- */ -- OverloadSet *os = s->isOverloadSet(); -- if (os) -- { s = NULL; -- for (size_t i = 0; i < os->a.dim; i++) -- { Dsymbol *s2 = os->a[i]; -- if (s2->isTemplateDeclaration()) -- { -- if (s) -- error("ambiguous template declaration %s and %s", s->toPrettyChars(), s2->toPrettyChars()); -- s = s2; -- } -- } -- if (!s) -- { error("template '%s' is not defined", id->toChars()); -- return NULL; -- } -- } -- --#if LOG -- printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind()); -- if (s->parent) -- printf("s->parent = '%s'\n", s->parent->toChars()); --#endif -- withsym = scopesym->isWithScopeSymbol(); -- -- /* We might have found an alias within a template when -- * we really want the template. -- */ -- TemplateInstance *ti; -- if (s->parent && -- (ti = s->parent->isTemplateInstance()) != NULL) -- { -- if (ti->tempdecl && ti->tempdecl->ident == id) -- { -- /* This is so that one can refer to the enclosing -- * template, even if it has the same name as a member -- * of the template, if it has a !(arguments) -- */ -- tempdecl = ti->tempdecl; -- if (tempdecl->overroot) // if not start of overloaded list of TemplateDeclaration's -- tempdecl = tempdecl->overroot; // then get the start -- s = tempdecl; -- } -- } -- -- s = s->toAlias(); -- -- /* It should be a TemplateDeclaration, not some other symbol -- */ -- tempdecl = s->isTemplateDeclaration(); -- if (!tempdecl) -+ TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); -+ assert(tempdecl); -+ assert(tempdecl->scope); -+ // Deduce tdtypes -+ tdtypes.setDim(tempdecl->parameters->dim); -+ if (!tempdecl->matchWithInstance(sc, this, &tdtypes, fargs, 2)) - { -- if (!s->parent && global.errors) -- return NULL; -- if (!s->parent && s->getType()) -- { Dsymbol *s2 = s->getType()->toDsymbol(sc); -- if (!s2) -- { -- error("%s is not a template declaration, it is a %s", id->toChars(), s->kind()); -- return NULL; -- } -- s = s2; -- } --#ifdef DEBUG -- //if (!s->parent) printf("s = %s %s\n", s->kind(), s->toChars()); --#endif -- //assert(s->parent); -- TemplateInstance *ti = s->parent ? s->parent->isTemplateInstance() : NULL; -- if (ti && -- (ti->name == id || -- ti->toAlias()->ident == id) -- && -- ti->tempdecl) -- { -- /* This is so that one can refer to the enclosing -- * template, even if it has the same name as a member -- * of the template, if it has a !(arguments) -- */ -- tempdecl = ti->tempdecl; -- if (tempdecl->overroot) // if not start of overloaded list of TemplateDeclaration's -- tempdecl = tempdecl->overroot; // then get the start -- } -- else -- { -- error("%s is not a template declaration, it is a %s", id->toChars(), s->kind()); -- return NULL; -- } -+ error("incompatible arguments for template instantiation"); -+ return false; - } -+ return true; - } -- else -- assert(tempdecl->isTemplateDeclaration()); -- return tempdecl; --} -- --TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs) --{ -- /* Since there can be multiple TemplateDeclaration's with the same -- * name, look for the best match. -- */ -- TemplateDeclaration *td_ambig = NULL; -- TemplateDeclaration *td_best = NULL; -- MATCH m_best = MATCHnomatch; -- Objects dedtypes; - - #if LOG - printf("TemplateInstance::findBestMatch()\n"); - #endif -- // First look for forward references -- for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) -- { -- if (!td->semanticRun) -- { -- if (td->scope) -- { // Try to fix forward reference. Ungag errors while doing so. -- int oldgag = global.gag; -- if (global.isSpeculativeGagging() && !td->isSpeculative()) -- global.gag = 0; -+ unsigned errs = global.errors; - -- td->semantic(td->scope); -+ struct ParamBest -+ { -+ // context -+ Scope *sc; -+ TemplateInstance *ti; -+ Objects dedtypes; -+ // result -+ TemplateDeclaration *td_best; -+ TemplateDeclaration *td_ambig; -+ MATCH m_best; - -- global.gag = oldgag; -- } -- if (!td->semanticRun) -- { -- error("%s forward references template declaration %s", toChars(), td->toChars()); -- return NULL; -- } -- } -+ static int fp(void *param, Dsymbol *s) -+ { -+ return ((ParamBest *)param)->fp(s); - } -- -- for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) -+ int fp(Dsymbol *s) - { -- MATCH m; -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (!td) -+ return 0; -+ -+ if (td == td_best) // skip duplicates -+ return 0; - --//if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, (*tiargs)[0]); -+ //printf("td = %s\n", td->toPrettyChars()); - - // If more arguments than parameters, - // then this is no match. -- if (td->parameters->dim < tiargs->dim) -+ if (td->parameters->dim < ti->tiargs->dim) - { - if (!td->isVariadic()) -- continue; -+ return 0; - } - - dedtypes.setDim(td->parameters->dim); - dedtypes.zero(); -- assert(td->semanticRun); -- m = td->matchWithInstance(this, &dedtypes, fargs, 0); -+ assert(td->semanticRun != PASSinit); -+ MATCH m = td->matchWithInstance(sc, ti, &dedtypes, ti->fargs, 0); - //printf("matchWithInstance = %d\n", m); - if (!m) // no match at all -- continue; -+ return 0; - -- if (m < m_best) -- goto Ltd_best; -- if (m > m_best) -- goto Ltd; -+ if (m < m_best) goto Ltd_best; -+ if (m > m_best) goto Ltd; - - { - // Disambiguate by picking the most specialized TemplateDeclaration -- MATCH c1 = td->leastAsSpecialized(td_best, fargs); -- MATCH c2 = td_best->leastAsSpecialized(td, fargs); -+ MATCH c1 = td->leastAsSpecialized(sc, td_best, ti->fargs); -+ MATCH c2 = td_best->leastAsSpecialized(sc, td, ti->fargs); - //printf("c1 = %d, c2 = %d\n", c1, c2); -- -- if (c1 > c2) -- goto Ltd; -- else if (c1 < c2) -- goto Ltd_best; -- else -- goto Lambig; -+ if (c1 > c2) goto Ltd; -+ if (c1 < c2) goto Ltd_best; - } - - Lambig: // td_best and td are ambiguous - td_ambig = td; -- continue; -+ return 0; - - Ltd_best: // td_best is the best match so far - td_ambig = NULL; -- continue; -+ return 0; - - Ltd: // td is the new best match - td_ambig = NULL; - td_best = td; - m_best = m; -- tdtypes.setDim(dedtypes.dim); -- memcpy(tdtypes.tdata(), dedtypes.tdata(), tdtypes.dim * sizeof(void *)); -- continue; -+ ti->tdtypes.setDim(dedtypes.dim); -+ memcpy(ti->tdtypes.tdata(), dedtypes.tdata(), ti->tdtypes.dim * sizeof(void *)); -+ return 0; - } -+ }; -+ ParamBest p; -+ // context -+ p.ti = this; -+ p.sc = sc; -+ -+ /* Since there can be multiple TemplateDeclaration's with the same -+ * name, look for the best match. -+ */ -+ TemplateDeclaration *td_last = NULL; - -- if (!td_best) -+ OverloadSet *tovers = tempdecl->isOverloadSet(); -+ size_t overs_dim = tovers ? tovers->a.dim : 1; -+ for (size_t oi = 0; oi < overs_dim; oi++) - { -- if (tempdecl && !tempdecl->overnext) -+ // result -+ p.td_best = NULL; -+ p.td_ambig = NULL; -+ p.m_best = MATCHnomatch; -+ overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamBest::fp); -+ -+ if (p.td_ambig) -+ { -+ ::error(loc, "%s %s.%s matches more than one template declaration:\n\t%s(%d):%s\nand\n\t%s(%d):%s", -+ p.td_best->kind(), p.td_best->parent->toPrettyChars(), p.td_best->ident->toChars(), -+ p.td_best->loc.filename, p.td_best->loc.linnum, p.td_best->toChars(), -+ p.td_ambig->loc.filename, p.td_ambig->loc.linnum, p.td_ambig->toChars()); -+ return false; -+ } -+ if (p.td_best) -+ { -+ if (!td_last) -+ td_last = p.td_best; -+ else if (td_last != p.td_best) -+ { -+ ScopeDsymbol::multiplyDefined(loc, td_last, p.td_best); -+ return false; -+ } -+ } -+ } -+ -+ if (!td_last) -+ { -+ TemplateDeclaration *tdecl = tempdecl->isTemplateDeclaration(); -+ -+ if (errs != global.errors) -+ errorSupplemental(loc, "while looking for match for %s", toChars()); -+ else if (tovers) -+ error("does not match template overload set %s", tovers->toChars()); -+ else if (tdecl && !tdecl->overnext) - // Only one template, so we can give better error message -- error("%s does not match template declaration %s", toChars(), tempdecl->toChars()); -+ error("does not match template declaration %s", tdecl->toChars()); - else - ::error(loc, "%s %s.%s does not match any template declaration", -- tempdecl->kind(), tempdecl->parent->toPrettyChars(), tempdecl->ident->toChars()); -- return NULL; -+ tdecl->kind(), tdecl->parent->toPrettyChars(), tdecl->ident->toChars()); -+ return false; - } -- if (td_ambig) -+ -+ /* The best match is td_last -+ */ -+ tempdecl = td_last; -+ -+#if LOG -+ printf("\tIt's a match with template declaration '%s'\n", tempdecl->toChars()); -+#endif -+ return (errs == global.errors); -+} -+ -+/***************************************************** -+ * Determine if template instance is really a template function, -+ * and that template function needs to infer types from the function -+ * arguments. -+ * -+ * Like findBestMatch, iterate possible template candidates, -+ * but just looks only the necessity of type inference. -+ */ -+ -+bool TemplateInstance::needsTypeInference(Scope *sc, int flag) -+{ -+ //printf("TemplateInstance::needsTypeInference() %s\n", toChars()); -+ -+ struct ParamNeedsInf -+ { -+ // context -+ Scope *sc; -+ TemplateInstance *ti; -+ int flag; -+ // result -+ Objects dedtypes; -+ size_t count; -+ -+ static int fp(void *param, Dsymbol *s) - { -- ::error(loc, "%s %s.%s matches more than one template declaration, %s(%d):%s and %s(%d):%s", -- td_best->kind(), td_best->parent->toPrettyChars(), td_best->ident->toChars(), -- td_best->loc.filename, td_best->loc.linnum, td_best->toChars(), -- td_ambig->loc.filename, td_ambig->loc.linnum, td_ambig->toChars()); -+ return ((ParamNeedsInf *)param)->fp(s); - } -+ int fp(Dsymbol *s) -+ { -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (!td) -+ { -+ Lcontinue: -+ return 0; -+ } - -- /* The best match is td_best -- */ -- tempdecl = td_best; -+ /* If any of the overloaded template declarations need inference, -+ * then return true -+ */ -+ FuncDeclaration *fd; -+ if (!td->onemember) -+ return 0; -+ if (TemplateDeclaration *td2 = td->onemember->isTemplateDeclaration()) -+ { -+ if (!td2->onemember || !td2->onemember->isFuncDeclaration()) -+ return 0; -+ if (ti->tiargs->dim > td->parameters->dim && !td->isVariadic()) -+ return 0; -+ return 1; -+ } -+ if ((fd = td->onemember->isFuncDeclaration()) == NULL || -+ fd->type->ty != Tfunction) -+ { -+ return 0; -+ } - --#if 0 -- /* Cast any value arguments to be same type as value parameter -- */ -- for (size_t i = 0; i < tiargs->dim; i++) -- { Object *o = (*tiargs)[i]; -- Expression *ea = isExpression(o); // value argument -- TemplateParameter *tp = (*tempdecl->parameters)[i]; -- assert(tp); -- TemplateValueParameter *tvp = tp->isTemplateValueParameter(); -- if (tvp) -+ for (size_t i = 0; i < td->parameters->dim; i++) - { -- assert(ea); -- ea = ea->castTo(tvp->valType); -- ea = ea->ctfeInterpret(); -- (*tiargs)[i] = (Object *)ea; -+ if ((*td->parameters)[i]->isTemplateThisParameter()) -+ return 1; - } -- } --#endif - --#if LOG -- printf("\tIt's a match with template declaration '%s'\n", tempdecl->toChars()); --#endif -- return tempdecl; -+ /* Determine if the instance arguments, tiargs, are all that is necessary -+ * to instantiate the template. -+ */ -+ //printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, ti->tiargs->dim); -+ TypeFunction *tf = (TypeFunction *)fd->type; -+ if (size_t dim = Parameter::dim(tf->parameters)) -+ { -+ TemplateParameter *tp = td->isVariadic(); -+ if (tp && td->parameters->dim > 1) -+ return 1; -+ -+ if (ti->tiargs->dim < td->parameters->dim) -+ { -+ // Can remain tiargs be filled by default arguments? -+ for (size_t i = ti->tiargs->dim; i < td->parameters->dim; i++) -+ { -+ tp = (*td->parameters)[i]; -+ if (TemplateTypeParameter *ttp = tp->isTemplateTypeParameter()) -+ { -+ if (!ttp->defaultType) -+ return 1; -+ } -+ else if (TemplateAliasParameter *tap = tp->isTemplateAliasParameter()) -+ { -+ if (!tap->defaultAlias) -+ return 1; -+ } -+ else if (TemplateValueParameter *tvp = tp->isTemplateValueParameter()) -+ { -+ if (!tvp->defaultValue) -+ return 1; -+ } -+ } -+ } -+ -+ for (size_t i = 0; i < dim; i++) -+ { -+ // 'auto ref' needs inference. -+ if (Parameter::getNth(tf->parameters, i)->storageClass & STCauto) -+ return 1; -+ } -+ } -+ -+ if (!flag) -+ { -+ /* Calculate the need for overload resolution. -+ * When only one template can match with tiargs, inference is not necessary. -+ */ -+ dedtypes.setDim(td->parameters->dim); -+ dedtypes.zero(); -+ assert(td->semanticRun != PASSinit); -+ MATCH m = td->matchWithInstance(sc, ti, &dedtypes, NULL, 0); -+ if (m == MATCHnomatch) -+ return 0; -+ } -+ -+ /* If there is more than one function template which matches, we may -+ * need type inference (see Bugzilla 4430) -+ */ -+ if (++count > 1) -+ return 1; -+ -+ return 0; -+ } -+ }; -+ ParamNeedsInf p; -+ // context -+ p.ti = this; -+ p.sc = sc; -+ p.flag = flag; -+ // result -+ p.count = 0; -+ -+ OverloadSet *tovers = tempdecl->isOverloadSet(); -+ size_t overs_dim = tovers ? tovers->a.dim : 1; -+ for (size_t oi = 0; oi < overs_dim; oi++) -+ { -+ if (int r = overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamNeedsInf::fp)) -+ return true; -+ } -+ //printf("false\n"); -+ return false; - } - - - /***************************************** - * Determines if a TemplateInstance will need a nested - * generation of the TemplateDeclaration. -- * Sets isnested property if so, and returns != 0; -+ * Sets enclosing property if so, and returns != 0; - */ - --int TemplateInstance::hasNestedArgs(Objects *args) --{ int nested = 0; -+bool TemplateInstance::hasNestedArgs(Objects *args) -+{ -+ int nested = 0; - //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars()); - - /* A nested instance happens when an argument references a local - * symbol that is on the stack. - */ - for (size_t i = 0; i < args->dim; i++) -- { Object *o = (*args)[i]; -+ { -+ RootObject *o = (*args)[i]; - Expression *ea = isExpression(o); - Dsymbol *sa = isDsymbol(o); - Tuple *va = isTuple(o); -@@ -5808,14 +6558,35 @@ int TemplateInstance::hasNestedArgs(Obje - sa = ((FuncExp *)ea)->fd; - goto Lsa; - } -+ // Emulate Expression::toMangleBuffer call that had exist in TemplateInstance::genIdent. -+ if (ea->op != TOKint64 && // IntegerExp -+ ea->op != TOKfloat64 && // RealExp -+ ea->op != TOKcomplex80 && // CompexExp -+ ea->op != TOKnull && // NullExp -+ ea->op != TOKstring && // StringExp -+ ea->op != TOKarrayliteral && // ArrayLiteralExp -+ ea->op != TOKassocarrayliteral && // AssocArrayLiteralExp -+ ea->op != TOKstructliteral) // StructLiteralExp -+ { -+ ea->error("expression %s is not a valid template value argument", ea->toChars()); -+ } - } - else if (sa) - { - Lsa: -+ sa = sa->toAlias(); - TemplateDeclaration *td = sa->isTemplateDeclaration(); -+ if (td) -+ { -+ TemplateInstance *ti = sa->toParent()->isTemplateInstance(); -+ if (ti && ti->enclosing) -+ sa = ti; -+ } -+ TemplateInstance *ti = sa->isTemplateInstance(); - AggregateDeclaration *ad = sa->isAggregateDeclaration(); - Declaration *d = sa->isDeclaration(); - if ((td && td->literal) || -+ (ti && ti->enclosing) || - #if FIXBUG8863 - (ad && ad->isNested()) || - #endif -@@ -5829,31 +6600,32 @@ int TemplateInstance::hasNestedArgs(Obje - { - // if module level template - if (tempdecl->toParent()->isModule()) -- { Dsymbol *dparent = sa->toParent(); -- if (!isnested) -- isnested = dparent; -- else if (isnested != dparent) -+ { -+ Dsymbol *dparent = sa->toParent2(); -+ if (!enclosing) -+ enclosing = dparent; -+ else if (enclosing != dparent) - { - /* Select the more deeply nested of the two. - * Error if one is not nested inside the other. - */ -- for (Dsymbol *p = isnested; p; p = p->parent) -+ for (Dsymbol *p = enclosing; p; p = p->parent) - { - if (p == dparent) -- goto L1; // isnested is most nested -+ goto L1; // enclosing is most nested - } - for (Dsymbol *p = dparent; p; p = p->parent) - { -- if (p == isnested) -- { isnested = dparent; -+ if (p == enclosing) -+ { enclosing = dparent; - goto L1; // dparent is most nested - } - } - error("%s is nested in both %s and %s", -- toChars(), isnested->toChars(), dparent->toChars()); -+ toChars(), enclosing->toChars(), dparent->toChars()); - } - L1: -- //printf("\tnested inside %s\n", isnested->toChars()); -+ //printf("\tnested inside %s\n", enclosing->toChars()); - nested |= 1; - } - else -@@ -5866,7 +6638,7 @@ int TemplateInstance::hasNestedArgs(Obje - } - } - //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested); -- return nested; -+ return nested != 0; - } - - /**************************************** -@@ -5876,13 +6648,16 @@ int TemplateInstance::hasNestedArgs(Obje - */ - - Identifier *TemplateInstance::genIdent(Objects *args) --{ OutBuffer buf; -+{ -+ assert(tempdecl); - - //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); -+ OutBuffer buf; - char *id = tempdecl->ident->toChars(); - buf.printf("__T%llu%s", (ulonglong)strlen(id), id); - for (size_t i = 0; i < args->dim; i++) -- { Object *o = (*args)[i]; -+ { -+ RootObject *o = (*args)[i]; - Type *ta = isType(o); - Expression *ea = isExpression(o); - Dsymbol *sa = isDsymbol(o); -@@ -5955,15 +6730,10 @@ Identifier *TemplateInstance::genIdent(O - { - Lsa: - buf.writeByte('S'); -+ sa = sa->toAlias(); - Declaration *d = sa->isDeclaration(); -- Lsa2: - if (d && (!d->type || !d->type->deco)) - { -- FuncAliasDeclaration *fad = d->isFuncAliasDeclaration(); -- if (fad) -- { d = fad->toAliasFunc(); -- goto Lsa2; -- } - error("forward reference of %s %s", d->kind(), d->toChars()); - continue; - } -@@ -6005,6 +6775,17 @@ Identifier *TemplateInstance::genIdent(O - return Lexer::idPool(id); - } - -+/************************************* -+ * Lazily generate identifier for template instance. -+ * This is because 75% of the ident's are never needed. -+ */ -+ -+Identifier *TemplateInstance::getIdent() -+{ -+ if (!ident && inst) -+ ident = genIdent(tiargs); // need an identifier for name mangling purposes. -+ return ident; -+} - - /**************************************************** - * Declare parameters of template instance, initialize them with the -@@ -6013,90 +6794,21 @@ Identifier *TemplateInstance::genIdent(O - - void TemplateInstance::declareParameters(Scope *sc) - { -+ TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); -+ assert(tempdecl); -+ - //printf("TemplateInstance::declareParameters()\n"); - for (size_t i = 0; i < tdtypes.dim; i++) - { - TemplateParameter *tp = (*tempdecl->parameters)[i]; -- //Object *o = (*tiargs)[i]; -- Object *o = tdtypes[i]; // initializer for tp -+ //RootObject *o = (*tiargs)[i]; -+ RootObject *o = tdtypes[i]; // initializer for tp - - //printf("\ttdtypes[%d] = %p\n", i, o); - tempdecl->declareParameter(sc, tp, o); - } - } - --/***************************************************** -- * Determine if template instance is really a template function, -- * and that template function needs to infer types from the function -- * arguments. -- */ -- --int TemplateInstance::needsTypeInference(Scope *sc) --{ -- //printf("TemplateInstance::needsTypeInference() %s\n", toChars()); -- if (!tempdecl) -- tempdecl = findTemplateDeclaration(sc); -- int multipleMatches = FALSE; -- for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) -- { -- /* If any of the overloaded template declarations need inference, -- * then return TRUE -- */ -- FuncDeclaration *fd; -- if (!td->onemember || -- (fd = td->onemember/*->toAlias()*/->isFuncDeclaration()) == NULL || -- fd->type->ty != Tfunction) -- { -- /* Not a template function, therefore type inference is not possible. -- */ -- //printf("false\n"); -- return FALSE; -- } -- -- for (size_t i = 0; i < td->parameters->dim; i++) -- if ((*td->parameters)[i]->isTemplateThisParameter()) -- return TRUE; -- -- /* Determine if the instance arguments, tiargs, are all that is necessary -- * to instantiate the template. -- */ -- //printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, tiargs->dim); -- TypeFunction *fdtype = (TypeFunction *)fd->type; -- if (Parameter::dim(fdtype->parameters)) -- { -- TemplateParameter *tp = td->isVariadic(); -- if (tp && td->parameters->dim > 1) -- return TRUE; -- -- if (tiargs->dim < td->parameters->dim) -- { // Can remain tiargs be filled by default arguments? -- for (size_t i = tiargs->dim; i < td->parameters->dim; i++) -- { tp = (*td->parameters)[i]; -- if (TemplateTypeParameter *ttp = tp->isTemplateTypeParameter()) -- { if (!ttp->defaultType) -- return TRUE; -- } -- else if (TemplateAliasParameter *tap = tp->isTemplateAliasParameter()) -- { if (!tap->defaultAlias) -- return TRUE; -- } -- else if (TemplateValueParameter *tvp = tp->isTemplateValueParameter()) -- { if (!tvp->defaultValue) -- return TRUE; -- } -- } -- } -- } -- /* If there is more than one function template which matches, we may -- * need type inference (see Bugzilla 4430) -- */ -- if (td != tempdecl) -- multipleMatches = TRUE; -- } -- //printf("false\n"); -- return multipleMatches; --} -- - void TemplateInstance::semantic2(Scope *sc) - { - if (semanticRun >= PASSsemantic2) -@@ -6110,6 +6822,7 @@ void TemplateInstance::semantic2(Scope * - sc = tempdecl->scope; - assert(sc); - sc = sc->push(argsym); -+ sc->instantiatingModule = instantiatingModule; - sc = sc->push(this); - sc->tinst = this; - for (size_t i = 0; i < members->dim; i++) -@@ -6141,17 +6854,19 @@ void TemplateInstance::semantic3(Scope * - { - sc = tempdecl->scope; - sc = sc->push(argsym); -+ sc->instantiatingModule = instantiatingModule; - sc = sc->push(this); - sc->tinst = this; -- int oldgag = global.gag; -+ int needGagging = (speculative && !global.gag); - int olderrors = global.errors; -+ int oldGaggedErrors; - /* If this is a speculative instantiation, gag errors. - * Future optimisation: If the results are actually needed, errors - * would already be gagged, so we don't really need to run semantic - * on the members. - */ -- if (speculative && !oldgag) -- olderrors = global.startGagging(); -+ if (needGagging) -+ oldGaggedErrors = global.startGagging(); - for (size_t i = 0; i < members->dim; i++) - { - Dsymbol *s = (*members)[i]; -@@ -6159,10 +6874,10 @@ void TemplateInstance::semantic3(Scope * - if (speculative && global.errors != olderrors) - break; - } -- if (speculative && !oldgag) -+ if (needGagging) - { // If errors occurred, this instantiation failed -- errors += global.errors - olderrors; -- global.endGagging(olderrors); -+ if (global.endGagging(oldGaggedErrors)) -+ errors = true; - } - sc = sc->pop(); - sc->pop(); -@@ -6265,23 +6980,57 @@ void TemplateInstance::toCBuffer(OutBuff - { - Identifier *id = name; - buf->writestring(id->toChars()); -- buf->writestring("!("); -+ toCBufferTiargs(buf, hgs); -+} -+ -+void TemplateInstance::toCBufferTiargs(OutBuffer *buf, HdrGenState *hgs) -+{ -+ buf->writeByte('!'); - if (nest) -- buf->writestring("..."); -+ buf->writestring("(...)"); -+ else if (!tiargs) -+ buf->writestring("()"); - else - { -+ if (tiargs->dim == 1) -+ { -+ RootObject *oarg = (*tiargs)[0]; -+ if (Type *t = isType(oarg)) -+ { -+ if (t->equals(Type::tstring) || -+ t->mod == 0 && -+ (t->isTypeBasic() || -+ t->ty == Tident && ((TypeIdentifier *)t)->idents.dim == 0)) -+ { -+ buf->writestring(t->toChars()); -+ return; -+ } -+ } -+ else if (Expression *e = isExpression(oarg)) -+ { -+ if (e->op == TOKint64 || // IntegerExp(10, true, false, 'c') -+ e->op == TOKfloat64 || // RealExp(3.14, 1.4i) -+ e->op == TOKnull || // NullExp -+ e->op == TOKstring || // StringExp -+ e->op == TOKthis) -+ { -+ buf->writestring(e->toChars()); -+ return; -+ } -+ } -+ } -+ buf->writeByte('('); - nest++; -- Objects *args = tiargs; -- for (size_t i = 0; i < args->dim; i++) -+ for (size_t i = 0; i < tiargs->dim; i++) - { - if (i) - buf->writestring(", "); -- Object *oarg = (*args)[i]; -+ RootObject *oarg = (*tiargs)[i]; - ObjectToCBuffer(buf, hgs, oarg); - } - nest--; -+ buf->writeByte(')'); - } -- buf->writeByte(')'); - } - - -@@ -6305,8 +7054,9 @@ Dsymbol *TemplateInstance::toAlias() - // inst = NULL; // trigger fwd ref error - } - if (!inst) -- { error("cannot resolve forward reference"); -- errors = 1; -+ { -+ error("cannot resolve forward reference"); -+ errors = true; - return this; - } - } -@@ -6332,10 +7082,10 @@ const char *TemplateInstance::kind() - return "template instance"; - } - --int TemplateInstance::oneMember(Dsymbol **ps, Identifier *ident) -+bool TemplateInstance::oneMember(Dsymbol **ps, Identifier *ident) - { - *ps = NULL; -- return TRUE; -+ return true; - } - - char *TemplateInstance::toChars() -@@ -6350,42 +7100,170 @@ char *TemplateInstance::toChars() - return s; - } - -+int TemplateInstance::compare(RootObject *o) -+{ -+ TemplateInstance *ti = (TemplateInstance *)o; -+ -+ //printf("this = %p, ti = %p\n", this, ti); -+ assert(tdtypes.dim == ti->tdtypes.dim); -+ -+ // Nesting must match -+ if (enclosing != ti->enclosing) -+ { -+ //printf("test2 enclosing %s ti->enclosing %s\n", enclosing ? enclosing->toChars() : "", ti->enclosing ? ti->enclosing->toChars() : ""); -+ goto Lnotequals; -+ } -+ //printf("parent = %s, ti->parent = %s\n", parent->toPrettyChars(), ti->parent->toPrettyChars()); -+ -+ if (!arrayObjectMatch(&tdtypes, &ti->tdtypes)) -+ goto Lnotequals; -+ -+ /* Template functions may have different instantiations based on -+ * "auto ref" parameters. -+ */ -+ if (fargs) -+ { -+ FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration(); -+ if (fd) -+ { -+ Parameters *fparameters = fd->getParameters(NULL); -+ size_t nfparams = Parameter::dim(fparameters); // Num function parameters -+ for (size_t j = 0; j < nfparams && j < fargs->dim; j++) -+ { -+ Parameter *fparam = Parameter::getNth(fparameters, j); -+ Expression *farg = (*fargs)[j]; -+ if (Expression *e = farg->isTemp()) -+ farg = e; -+ if (fparam->storageClass & STCauto) // if "auto ref" -+ { -+ if (farg->isLvalue()) -+ { -+ if (!(fparam->storageClass & STCref)) -+ goto Lnotequals; // auto ref's don't match -+ } -+ else -+ { -+ if (fparam->storageClass & STCref) -+ goto Lnotequals; // auto ref's don't match -+ } -+ } -+ } -+ } -+ } -+ return 0; -+ -+ Lnotequals: -+ return 1; -+} -+ -+hash_t TemplateInstance::hashCode() -+{ -+ if (!hash) -+ { -+ hash = (size_t)(void *)enclosing; -+ hash += arrayObjectHash(&tdtypes); -+ } -+ return hash; -+} -+ -+ -+ - /* ======================== TemplateMixin ================================ */ - --TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, -- Identifiers *idents, Objects *tiargs) -- : TemplateInstance(loc, (*idents)[idents->dim - 1]) -+TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs) -+ : TemplateInstance(loc, tqual->idents.dim ? (Identifier *)tqual->idents[tqual->idents.dim - 1] -+ : ((TypeIdentifier *)tqual)->ident) - { - //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); - this->ident = ident; - this->tqual = tqual; -- this->idents = idents; - this->tiargs = tiargs ? tiargs : new Objects(); - } - - Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) --{ TemplateMixin *tm; -+{ -+ TemplateMixin *tm = new TemplateMixin(loc, ident, -+ (TypeQualified *)tqual->syntaxCopy(), tiargs); -+ TemplateInstance::syntaxCopy(tm); -+ return tm; -+} - -- Identifiers *ids = new Identifiers(); -- ids->setDim(idents->dim); -- for (size_t i = 0; i < idents->dim; i++) -- { // Matches TypeQualified::syntaxCopyHelper() -- Identifier *id = (*idents)[i]; -- if (id->dyncast() == DYNCAST_DSYMBOL) -+bool TemplateMixin::findTemplateDeclaration(Scope *sc) -+{ -+ // Follow qualifications to find the TemplateDeclaration -+ if (!tempdecl) -+ { -+ Expression *e; -+ Type *t; -+ Dsymbol *s; -+ tqual->resolve(loc, sc, &e, &t, &s); -+ if (!s) - { -- TemplateInstance *ti = (TemplateInstance *)id; -+ error("is not defined"); -+ return false; -+ } -+ s = s->toAlias(); -+ tempdecl = s->isTemplateDeclaration(); -+ OverloadSet *os = s->isOverloadSet(); - -- ti = (TemplateInstance *)ti->syntaxCopy(NULL); -- id = (Identifier *)ti; -+ /* If an OverloadSet, look for a unique member that is a template declaration -+ */ -+ if (os) -+ { -+ Dsymbol *s = NULL; -+ for (size_t i = 0; i < os->a.dim; i++) -+ { -+ Dsymbol *s2 = os->a[i]->isTemplateDeclaration(); -+ if (s2) -+ { -+ if (s) -+ { -+ tempdecl = os; -+ break; -+ } -+ s = s2; -+ } -+ } -+ } -+ if (!tempdecl) -+ { -+ error("%s isn't a template", s->toChars()); -+ return false; - } -- (*ids)[i] = id; - } -+ assert(tempdecl); - -- tm = new TemplateMixin(loc, ident, -- (Type *)(tqual ? tqual->syntaxCopy() : NULL), -- ids, tiargs); -- TemplateInstance::syntaxCopy(tm); -- return tm; -+ struct ParamFwdResTm -+ { -+ static int fp(void *param, Dsymbol *s) -+ { -+ TemplateDeclaration *td = s->isTemplateDeclaration(); -+ if (!td) -+ return 0; -+ -+ TemplateMixin *tm = (TemplateMixin *)param; -+ if (td->semanticRun == PASSinit) -+ { -+ if (td->scope) -+ td->semantic(td->scope); -+ else -+ { -+ tm->semanticRun = PASSinit; -+ return 1; -+ } -+ } -+ return 0; -+ } -+ }; -+ // Look for forward references -+ OverloadSet *tovers = tempdecl->isOverloadSet(); -+ size_t overs_dim = tovers ? tovers->a.dim : 1; -+ for (size_t oi = 0; oi < overs_dim; oi++) -+ { -+ if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdResTm::fp)) -+ return false; -+ } -+ return true; - } - - void TemplateMixin::semantic(Scope *sc) -@@ -6394,7 +7272,7 @@ void TemplateMixin::semantic(Scope *sc) - printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this); - fflush(stdout); - #endif -- if (semanticRun) -+ if (semanticRun != PASSinit) - { - // This for when a class/struct contains mixin members, and - // is done over because of forward references -@@ -6412,81 +7290,29 @@ void TemplateMixin::semantic(Scope *sc) - return; - } - } -- if (!semanticRun) -+ if (semanticRun == PASSinit) - semanticRun = PASSsemantic; - #if LOG - printf("\tdo semantic\n"); - #endif --#ifndef IN_GCC -- util_progress(); --#endif - - Scope *scx = NULL; - if (scope) -- { sc = scope; -+ { -+ sc = scope; - scx = scope; // save so we don't make redundant copies - scope = NULL; - } - -- // Follow qualifications to find the TemplateDeclaration -- if (!tempdecl) -- { Dsymbol *s; -- size_t i; -- Identifier *id; -- -- if (tqual) -- { s = tqual->toDsymbol(sc); -- i = 0; -- } -- else -- { -- i = 1; -- id = (*idents)[0]; -- switch (id->dyncast()) -- { -- case DYNCAST_IDENTIFIER: -- s = sc->search(loc, id, NULL); -- break; -- -- case DYNCAST_DSYMBOL: -- { -- TemplateInstance *ti = (TemplateInstance *)id; -- ti->semantic(sc); -- s = ti; -- break; -- } -- default: -- assert(0); -- } -- } -- -- for (; i < idents->dim; i++) -- { -- if (!s) -- break; -- id = (*idents)[i]; -- s = s->searchX(loc, sc, id); -- } -- if (!s) -- { -- error("is not defined"); -- inst = this; -- return; -- } -- tempdecl = s->toAlias()->isTemplateDeclaration(); -- if (!tempdecl) -- { -- error("%s isn't a template", s->toChars()); -- inst = this; -- return; -- } -- } - -- // Look for forward reference -- assert(tempdecl); -- for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) -+ /* Run semantic on each argument, place results in tiargs[], -+ * then find best match template with tiargs -+ */ -+ if (!findTemplateDeclaration(sc) || -+ !semanticTiargs(sc) || -+ !findBestMatch(sc, NULL)) - { -- if (!td->semanticRun) -+ if (semanticRun == PASSinit) // forward reference had occured - { - /* Cannot handle forward references if mixin is a struct member, - * because addField must happen during struct's semantic, not -@@ -6494,7 +7320,6 @@ void TemplateMixin::semantic(Scope *sc) - * runDeferred will re-run mixin's semantic outside of the struct's - * semantic. - */ -- semanticRun = PASSinit; - AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); - if (ad) - ad->sizeok = SIZEOKfwd; -@@ -6508,18 +7333,13 @@ void TemplateMixin::semantic(Scope *sc) - } - return; - } -- } -- -- // Run semantic on each argument, place results in tiargs[] -- semanticTiargs(sc); -- if (errors || arrayObjectIsError(tiargs)) -- return; - -- tempdecl = findBestMatch(sc, NULL); -- if (!tempdecl) -- { inst = this; -+ inst = this; -+ inst->errors = true; - return; // error recovery - } -+ TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); -+ assert(tempdecl); - - if (!ident) - ident = genIdent(tiargs); -@@ -6542,11 +7362,12 @@ void TemplateMixin::semantic(Scope *sc) - continue; - - for (size_t i = 0; i < tiargs->dim; i++) -- { Object *o = (*tiargs)[i]; -+ { -+ RootObject *o = (*tiargs)[i]; - Type *ta = isType(o); - Expression *ea = isExpression(o); - Dsymbol *sa = isDsymbol(o); -- Object *tmo = (*tm->tiargs)[i]; -+ RootObject *tmo = (*tm->tiargs)[i]; - if (ta) - { - Type *tmta = isType(tmo); -@@ -6556,7 +7377,8 @@ void TemplateMixin::semantic(Scope *sc) - goto Lcontinue; - } - else if (ea) -- { Expression *tme = isExpression(tmo); -+ { -+ Expression *tme = isExpression(tmo); - if (!tme || !ea->equals(tme)) - goto Lcontinue; - } -@@ -6577,7 +7399,10 @@ void TemplateMixin::semantic(Scope *sc) - } - - // Copy the syntax trees from the TemplateDeclaration -- members = Dsymbol::arraySyntaxCopy(tempdecl->members); -+ if (scx && members) -+ {} // Don't copy again so they were previously created. -+ else -+ members = Dsymbol::arraySyntaxCopy(tempdecl->members); - if (!members) - return; - -@@ -6610,9 +7435,9 @@ void TemplateMixin::semantic(Scope *sc) - - // Add members to enclosing scope, as well as this scope - for (size_t i = 0; i < members->dim; i++) -- { Dsymbol *s = (*members)[i]; -+ { -+ Dsymbol *s = (*members)[i]; - s->addMember(argscope, this, i); -- //sc->insert(s); - //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); - //printf("s->parent = %s\n", s->parent->toChars()); - } -@@ -6676,16 +7501,10 @@ void TemplateMixin::semantic(Scope *sc) - return; - } - -- /* The problem is when to parse the initializer for a variable. -- * Perhaps VarDeclaration::semantic() should do it like it does -- * for initializers inside a function. -- */ --// if (sc->parent->isFuncDeclaration()) -- -- semantic2(sc2); -- -- if (sc->func) -+ AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); -+ if (sc->func && !ad) - { -+ semantic2(sc2); - semantic3(sc2); - } - -@@ -6696,13 +7515,9 @@ void TemplateMixin::semantic(Scope *sc) - } - - sc2->pop(); -- - argscope->pop(); -+ scy->pop(); - --// if (!isAnonymous()) -- { -- scy->pop(); -- } - #if LOG - printf("-TemplateMixin::semantic('%s', this=%p)\n", toChars(), this); - #endif -@@ -6748,6 +7563,7 @@ void TemplateMixin::semantic3(Scope *sc) - if (members) - { - sc = sc->push(argsym); -+ sc->instantiatingModule = instantiatingModule; - sc = sc->push(this); - for (size_t i = 0; i < members->dim; i++) - { -@@ -6769,7 +7585,7 @@ const char *TemplateMixin::kind() - return "mixin"; - } - --int TemplateMixin::oneMember(Dsymbol **ps, Identifier *ident) -+bool TemplateMixin::oneMember(Dsymbol **ps, Identifier *ident) - { - return Dsymbol::oneMember(ps, ident); - } -@@ -6790,21 +7606,23 @@ int TemplateMixin::apply(Dsymbol_apply_f - return 0; - } - --int TemplateMixin::hasPointers() -+bool TemplateMixin::hasPointers() - { - //printf("TemplateMixin::hasPointers() %s\n", toChars()); - - if (members) -+ { - for (size_t i = 0; i < members->dim; i++) - { - Dsymbol *s = (*members)[i]; - //printf(" s = %s %s\n", s->kind(), s->toChars()); - if (s->hasPointers()) - { -- return 1; -+ return true; - } - } -- return 0; -+ } -+ return false; - } - - void TemplateMixin::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion) -@@ -6838,43 +7656,9 @@ void TemplateMixin::toCBuffer(OutBuffer - { - buf->writestring("mixin "); - -- for (size_t i = 0; i < idents->dim; i++) -- { Identifier *id = (*idents)[i]; -+ tqual->toCBuffer(buf, NULL, hgs); -+ toCBufferTiargs(buf, hgs); - -- if (i) -- buf->writeByte('.'); -- buf->writestring(id->toChars()); -- } -- buf->writestring("!("); -- if (tiargs) -- { -- for (size_t i = 0; i < tiargs->dim; i++) -- { if (i) -- buf->writebyte(','); -- Object *oarg = (*tiargs)[i]; -- Type *t = isType(oarg); -- Expression *e = isExpression(oarg); -- Dsymbol *s = isDsymbol(oarg); -- if (t) -- t->toCBuffer(buf, NULL, hgs); -- else if (e) -- e->toCBuffer(buf, hgs); -- else if (s) -- { -- char *p = s->ident ? s->ident->toChars() : s->toChars(); -- buf->writestring(p); -- } -- else if (!oarg) -- { -- buf->writestring("NULL"); -- } -- else -- { -- assert(0); -- } -- } -- } -- buf->writebyte(')'); - if (ident) - { - buf->writebyte(' '); -@@ -6884,3 +7668,4 @@ void TemplateMixin::toCBuffer(OutBuffer - buf->writenl(); - } - -+ ---- a/src/gcc/d/dfrontend/template.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/template.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,6 +1,6 @@ - - // Compiler implementation of the D programming language --// Copyright (c) 1999-2012 by Digital Mars -+// Copyright (c) 1999-2013 by Digital Mars - // All Rights Reserved - // written by Walter Bright - // http://www.digitalmars.com -@@ -21,51 +21,56 @@ - - - struct OutBuffer; --struct Identifier; --struct TemplateInstance; --struct TemplateParameter; --struct TemplateTypeParameter; --struct TemplateThisParameter; --struct TemplateValueParameter; --struct TemplateAliasParameter; --struct TemplateTupleParameter; --struct Type; --struct TypeTypeof; -+class Identifier; -+class TemplateInstance; -+class TemplateParameter; -+class TemplateTypeParameter; -+class TemplateThisParameter; -+class TemplateValueParameter; -+class TemplateAliasParameter; -+class TemplateTupleParameter; -+class Type; -+class TypeQualified; -+class TypeTypeof; - struct Scope; --struct Expression; --struct AliasDeclaration; --struct FuncDeclaration; -+class Expression; -+class AliasDeclaration; -+class FuncDeclaration; - struct HdrGenState; --struct Parameter; -+class Parameter; - enum MATCH; - enum PASS; - --struct Tuple : Object -+class Tuple : public RootObject - { -+public: - Objects objects; - - int dyncast() { return DYNCAST_TUPLE; } // kludge for template.isType() - }; - - --struct TemplateDeclaration : ScopeDsymbol -+class TemplateDeclaration : public ScopeDsymbol - { -+public: - TemplateParameters *parameters; // array of TemplateParameter's - - TemplateParameters *origParameters; // originals for Ddoc - Expression *constraint; -- TemplateInstances instances; // array of TemplateInstance's -+ -+ // Hash table to look up TemplateInstance's of this TemplateDeclaration -+ Array buckets; -+ size_t numinstances; // number of instances in the hash table - - TemplateDeclaration *overnext; // next overloaded TemplateDeclaration - TemplateDeclaration *overroot; // first in overnext list -- -- enum PASS semanticRun; // 1 semantic() run -+ FuncDeclaration *funcroot; // first function in unified overload list - - Dsymbol *onemember; // if !=NULL then one member of this template - - int literal; // this template declaration is a literal - int ismixin; // template declaration is only to be used as a mixin -- enum PROT protection; -+ PROT protection; - - struct Previous - { Previous *prev; -@@ -78,7 +83,7 @@ struct TemplateDeclaration : ScopeDsymbo - Expression *constraint, Dsymbols *decldefs, int ismixin); - Dsymbol *syntaxCopy(Dsymbol *); - void semantic(Scope *sc); -- int overloadInsert(Dsymbol *s); -+ bool overloadInsert(Dsymbol *s); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - bool hasStaticCtorOrDtor(); - const char *kind(); -@@ -86,26 +91,31 @@ struct TemplateDeclaration : ScopeDsymbo - - void emitComment(Scope *sc); - void toJson(JsonOut *json); -+ virtual void jsonProperties(JsonOut *json); -+ PROT prot(); - // void toDocBuffer(OutBuffer *buf); - -- MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag); -- MATCH leastAsSpecialized(TemplateDeclaration *td2, Expressions *fargs); -+ MATCH matchWithInstance(Scope *sc, TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag); -+ MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs); - -- MATCH deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs); -- FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0); -- Object *declareParameter(Scope *sc, TemplateParameter *tp, Object *o); -- FuncDeclaration *doHeaderInstantiation(Scope *sc, Objects *tdargs, Expressions *fargs); -+ MATCH deduceFunctionTemplateMatch(FuncDeclaration *f, Loc loc, Scope *sc, Objects *tiargs, Type *tthis, Expressions *fargs, Objects *dedargs); -+ RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o); -+ FuncDeclaration *doHeaderInstantiation(Scope *sc, Objects *tdargs, Type *tthis, Expressions *fargs); -+ TemplateInstance *findExistingInstance(TemplateInstance *tithis, Expressions *fargs); -+ TemplateInstance *addInstance(TemplateInstance *ti); -+ void removeInstance(TemplateInstance *handle); - - TemplateDeclaration *isTemplateDeclaration() { return this; } - - TemplateTupleParameter *isVariadic(); -- int isOverloadable(); -+ bool isOverloadable(); - - void makeParamNamesVisibleInConstraint(Scope *paramscope, Expressions *fargs); - }; - --struct TemplateParameter -+class TemplateParameter - { -+public: - /* For type-parameter: - * template Foo(ident) // specType is set to NULL - * template Foo(ident : specType) -@@ -135,11 +145,11 @@ struct TemplateParameter - - virtual TemplateParameter *syntaxCopy() = 0; - virtual void declareParameter(Scope *sc) = 0; -- virtual void semantic(Scope *) = 0; -- virtual void print(Object *oarg, Object *oded) = 0; -+ virtual void semantic(Scope *sc, TemplateParameters *parameters) = 0; -+ virtual void print(RootObject *oarg, RootObject *oded) = 0; - virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0; -- virtual Object *specialization() = 0; -- virtual Object *defaultArg(Loc loc, Scope *sc) = 0; -+ virtual RootObject *specialization() = 0; -+ virtual RootObject *defaultArg(Loc loc, Scope *sc) = 0; - - /* If TemplateParameter's match as far as overloading goes. - */ -@@ -147,15 +157,17 @@ struct TemplateParameter - - /* Match actual argument against parameter. - */ -- virtual MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0; -+ virtual MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); -+ virtual MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0; - - /* Create dummy argument based on parameter. - */ - virtual void *dummyArg() = 0; - }; - --struct TemplateTypeParameter : TemplateParameter -+class TemplateTypeParameter : public TemplateParameter - { -+public: - /* Syntax: - * ident : specType = defaultType - */ -@@ -169,19 +181,20 @@ struct TemplateTypeParameter : TemplateP - TemplateTypeParameter *isTemplateTypeParameter(); - TemplateParameter *syntaxCopy(); - void declareParameter(Scope *sc); -- void semantic(Scope *); -- void print(Object *oarg, Object *oded); -+ void semantic(Scope *sc, TemplateParameters *parameters); -+ void print(RootObject *oarg, RootObject *oded); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- Object *specialization(); -- Object *defaultArg(Loc loc, Scope *sc); -+ RootObject *specialization(); -+ RootObject *defaultArg(Loc loc, Scope *sc); - int overloadMatch(TemplateParameter *); -- MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); -+ MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); - void *dummyArg(); - }; - - #if DMDV2 --struct TemplateThisParameter : TemplateTypeParameter -+class TemplateThisParameter : public TemplateTypeParameter - { -+public: - /* Syntax: - * this ident : specType = defaultType - */ -@@ -194,8 +207,9 @@ struct TemplateThisParameter : TemplateT - }; - #endif - --struct TemplateValueParameter : TemplateParameter -+class TemplateValueParameter : public TemplateParameter - { -+public: - /* Syntax: - * valType ident : specValue = defaultValue - */ -@@ -211,45 +225,47 @@ struct TemplateValueParameter : Template - TemplateValueParameter *isTemplateValueParameter(); - TemplateParameter *syntaxCopy(); - void declareParameter(Scope *sc); -- void semantic(Scope *); -- void print(Object *oarg, Object *oded); -+ void semantic(Scope *sc, TemplateParameters *parameters); -+ void print(RootObject *oarg, RootObject *oded); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- Object *specialization(); -- Object *defaultArg(Loc loc, Scope *sc); -+ RootObject *specialization(); -+ RootObject *defaultArg(Loc loc, Scope *sc); - int overloadMatch(TemplateParameter *); -- MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); -+ MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); - void *dummyArg(); - }; - --struct TemplateAliasParameter : TemplateParameter -+class TemplateAliasParameter : public TemplateParameter - { -+public: - /* Syntax: - * specType ident : specAlias = defaultAlias - */ - - Type *specType; -- Object *specAlias; -- Object *defaultAlias; -+ RootObject *specAlias; -+ RootObject *defaultAlias; - - static Dsymbol *sdummy; - -- TemplateAliasParameter(Loc loc, Identifier *ident, Type *specType, Object *specAlias, Object *defaultAlias); -+ TemplateAliasParameter(Loc loc, Identifier *ident, Type *specType, RootObject *specAlias, RootObject *defaultAlias); - - TemplateAliasParameter *isTemplateAliasParameter(); - TemplateParameter *syntaxCopy(); - void declareParameter(Scope *sc); -- void semantic(Scope *); -- void print(Object *oarg, Object *oded); -+ void semantic(Scope *sc, TemplateParameters *parameters); -+ void print(RootObject *oarg, RootObject *oded); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- Object *specialization(); -- Object *defaultArg(Loc loc, Scope *sc); -+ RootObject *specialization(); -+ RootObject *defaultArg(Loc loc, Scope *sc); - int overloadMatch(TemplateParameter *); -- MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); -+ MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); - void *dummyArg(); - }; - --struct TemplateTupleParameter : TemplateParameter -+class TemplateTupleParameter : public TemplateParameter - { -+public: - /* Syntax: - * ident ... - */ -@@ -259,25 +275,26 @@ struct TemplateTupleParameter : Template - TemplateTupleParameter *isTemplateTupleParameter(); - TemplateParameter *syntaxCopy(); - void declareParameter(Scope *sc); -- void semantic(Scope *); -- void print(Object *oarg, Object *oded); -+ void semantic(Scope *sc, TemplateParameters *parameters); -+ void print(RootObject *oarg, RootObject *oded); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -- Object *specialization(); -- Object *defaultArg(Loc loc, Scope *sc); -+ RootObject *specialization(); -+ RootObject *defaultArg(Loc loc, Scope *sc); - int overloadMatch(TemplateParameter *); -- MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); -+ MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); -+ MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); - void *dummyArg(); - }; - --struct TemplateInstance : ScopeDsymbol -+class TemplateInstance : public ScopeDsymbol - { -+public: - /* Given: - * foo!(args) => - * name = foo - * tiargs = args - */ - Identifier *name; -- //Identifiers idents; - Objects *tiargs; // Array of Types/Expressions of template - // instance arguments [int*, char, 10*10] - -@@ -285,25 +302,21 @@ struct TemplateInstance : ScopeDsymbol - // to TemplateDeclaration.parameters - // [int, char, 100] - -- TemplateDeclaration *tempdecl; // referenced by foo.bar.abc -+ Dsymbol *tempdecl; // referenced by foo.bar.abc - TemplateInstance *inst; // refer to existing instance - TemplateInstance *tinst; // enclosing template instance - ScopeDsymbol *argsym; // argument symbol table - AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its - // sole member - WithScopeSymbol *withsym; // if a member of a with statement -- enum PASS semanticRun; // has semantic() been done? -- int semantictiargsdone; // has semanticTiargs() been done? -- int nest; // for recursion detection -- int havetempdecl; // 1 if used second constructor -- Dsymbol *isnested; // if referencing local symbols, this is the context -- int speculative; // 1 if only instantiated with errors gagged --#ifdef IN_GCC -- /* On some targets, it is necessary to know whether a symbol -- will be emitted in the output or not before the symbol -- is used. This can be different from getModule(). */ -- Module * objFileModule; --#endif -+ int nest; // for recursion detection -+ bool semantictiargsdone; // has semanticTiargs() been done? -+ bool havetempdecl; // if used second constructor -+ bool speculative; // if only instantiated with errors gagged -+ Dsymbol *enclosing; // if referencing local symbols, this is the context -+ hash_t hash; // cached result of hashCode() -+ Expressions *fargs; // for function template, these are the function arguments -+ Module *instantiatingModule; // the top module that instantiated this instance - - TemplateInstance(Loc loc, Identifier *temp_id); - TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs); -@@ -315,23 +328,28 @@ struct TemplateInstance : ScopeDsymbol - void semantic3(Scope *sc); - void inlineScan(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -+ void toCBufferTiargs(OutBuffer *buf, HdrGenState *hgs); - Dsymbol *toAlias(); // resolve real symbol - const char *kind(); -- int oneMember(Dsymbol **ps, Identifier *ident); -- int needsTypeInference(Scope *sc); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - char *toChars(); -- char *mangle(bool isv = false); -+ const char *mangle(bool isv = false); - void printInstantiationTrace(); -+ Identifier *getIdent(); -+ int compare(RootObject *o); -+ hash_t hashCode(); - - void toObjFile(int multiobj); // compile to .obj file - - // Internal -+ bool findTemplateDeclaration(Scope *sc); -+ bool updateTemplateDeclaration(Scope *sc, Dsymbol *s); - static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags); -- void semanticTiargs(Scope *sc); -- TemplateDeclaration *findTemplateDeclaration(Scope *sc); -- TemplateDeclaration *findBestMatch(Scope *sc, Expressions *fargs); -+ bool semanticTiargs(Scope *sc); -+ bool findBestMatch(Scope *sc, Expressions *fargs); -+ bool needsTypeInference(Scope *sc, int flag = 0); -+ bool hasNestedArgs(Objects *tiargs); - void declareParameters(Scope *sc); -- int hasNestedArgs(Objects *tiargs); - Identifier *genIdent(Objects *args); - void expandMembers(Scope *sc); - void tryExpandMembers(Scope *sc); -@@ -341,21 +359,21 @@ struct TemplateInstance : ScopeDsymbol - AliasDeclaration *isAliasDeclaration(); - }; - --struct TemplateMixin : TemplateInstance -+class TemplateMixin : public TemplateInstance - { -- Identifiers *idents; -- Type *tqual; -+public: -+ TypeQualified *tqual; - -- TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Identifiers *idents, Objects *tiargs); -+ TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs); - Dsymbol *syntaxCopy(Dsymbol *s); - void semantic(Scope *sc); - void semantic2(Scope *sc); - void semantic3(Scope *sc); - void inlineScan(); - const char *kind(); -- int oneMember(Dsymbol **ps, Identifier *ident); -+ bool oneMember(Dsymbol **ps, Identifier *ident); - int apply(Dsymbol_apply_ft_t fp, void *param); -- int hasPointers(); -+ bool hasPointers(); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); - char *toChars(); - void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -@@ -363,20 +381,22 @@ struct TemplateMixin : TemplateInstance - - void toObjFile(int multiobj); // compile to .obj file - -+ bool findTemplateDeclaration(Scope *sc); -+ - TemplateMixin *isTemplateMixin() { return this; } - }; - --Expression *isExpression(Object *o); --Dsymbol *isDsymbol(Object *o); --Type *isType(Object *o); --Tuple *isTuple(Object *o); --Parameter *isParameter(Object *o); -+Expression *isExpression(RootObject *o); -+Dsymbol *isDsymbol(RootObject *o); -+Type *isType(RootObject *o); -+Tuple *isTuple(RootObject *o); -+Parameter *isParameter(RootObject *o); - int arrayObjectIsError(Objects *args); --int isError(Object *o); --Type *getType(Object *o); --Dsymbol *getDsymbol(Object *o); -+int isError(RootObject *o); -+Type *getType(RootObject *o); -+Dsymbol *getDsymbol(RootObject *o); - --void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg); --Object *objectSyntaxCopy(Object *o); -+void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, RootObject *oarg); -+RootObject *objectSyntaxCopy(RootObject *o); - - #endif /* DMD_TEMPLATE_H */ ---- a/src/gcc/d/dfrontend/traits.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/traits.c 2014-04-01 16:32:51.000000000 +0100 -@@ -15,6 +15,7 @@ - #include - - #include "rmem.h" -+#include "aav.h" - - //#include "port.h" - #include "mtype.h" -@@ -51,9 +52,13 @@ struct Ptrait - Identifier *ident; // which trait we're looking for - }; - --static int fptraits(void *param, FuncDeclaration *f) --{ Ptrait *p = (Ptrait *)param; -+static int fptraits(void *param, Dsymbol *s) -+{ -+ FuncDeclaration *f = s->isFuncDeclaration(); -+ if (!f) -+ return 0; - -+ Ptrait *p = (Ptrait *)param; - if (p->ident == Id::getVirtualFunctions && !f->isVirtual()) - return 0; - -@@ -61,14 +66,62 @@ static int fptraits(void *param, FuncDec - return 0; - - Expression *e; -+ FuncAliasDeclaration* alias = new FuncAliasDeclaration(f, 0); -+ alias->protection = f->protection; - if (p->e1) -- e = new DotVarExp(0, p->e1, new FuncAliasDeclaration(f, 0)); -+ e = new DotVarExp(Loc(), p->e1, alias); - else -- e = new DsymbolExp(0, new FuncAliasDeclaration(f, 0)); -+ e = new DsymbolExp(Loc(), alias); - p->exps->push(e); - return 0; - } - -+/** -+ * Collects all unit test functions from the given array of symbols. -+ * -+ * This is a helper function used by the implementation of __traits(getUnitTests). -+ * -+ * Input: -+ * symbols array of symbols to collect the functions from -+ * uniqueUnitTests an associative array (should actually be a set) to -+ * keep track of already collected functions. We're -+ * using an AA here to avoid doing a linear search of unitTests -+ * -+ * Output: -+ * unitTests array of DsymbolExp's of the collected unit test functions -+ * uniqueUnitTests updated with symbols from unitTests[ ] -+ */ -+static void collectUnitTests(Dsymbols *symbols, AA *uniqueUnitTests, Expressions *unitTests) -+{ -+ for (size_t i = 0; i < symbols->dim; i++) -+ { -+ Dsymbol *symbol = (*symbols)[i]; -+ UnitTestDeclaration *unitTest = symbol->isUnitTestDeclaration(); -+ if (unitTest) -+ { -+ if (!_aaGetRvalue(uniqueUnitTests, unitTest)) -+ { -+ FuncAliasDeclaration* alias = new FuncAliasDeclaration(unitTest, 0); -+ alias->protection = unitTest->protection; -+ Expression* e = new DsymbolExp(Loc(), alias); -+ unitTests->push(e); -+ bool* value = (bool*) _aaGet(&uniqueUnitTests, unitTest); -+ *value = true; -+ } -+ } -+ else -+ { -+ AttribDeclaration *attrDecl = symbol->isAttribDeclaration(); -+ -+ if (attrDecl) -+ { -+ Dsymbols *decl = attrDecl->include(NULL, NULL); -+ collectUnitTests(decl, uniqueUnitTests, unitTests); -+ } -+ } -+ } -+} -+ - /************************ TraitsExp ************************************/ - - Expression *TraitsExp::semantic(Scope *sc) -@@ -77,7 +130,7 @@ Expression *TraitsExp::semantic(Scope *s - printf("TraitsExp::semantic() %s\n", toChars()); - #endif - if (ident != Id::compiles && ident != Id::isSame && -- ident != Id::identifier) -+ ident != Id::identifier && ident != Id::getProtection) - { - TemplateInstance::semanticTiargs(loc, sc, args, 1); - } -@@ -150,7 +203,7 @@ Expression *TraitsExp::semantic(Scope *s - { - if (dim != 1) - goto Ldimerror; -- Object *o = (*args)[0]; -+ RootObject *o = (*args)[0]; - Type *t = isType(o); - StructDeclaration *sd; - if (!t) -@@ -168,6 +221,34 @@ Expression *TraitsExp::semantic(Scope *s - } - goto Ltrue; - } -+ else if (ident == Id::isNested) -+ { -+ if (dim != 1) -+ goto Ldimerror; -+ RootObject *o = (*args)[0]; -+ Dsymbol *s = getDsymbol(o); -+ AggregateDeclaration *a; -+ FuncDeclaration *f; -+ -+ if (!s) { } -+ else if ((a = s->isAggregateDeclaration()) != NULL) -+ { -+ if (a->isNested()) -+ goto Ltrue; -+ else -+ goto Lfalse; -+ } -+ else if ((f = s->isFuncDeclaration()) != NULL) -+ { -+ if (f->isNested()) -+ goto Ltrue; -+ else -+ goto Lfalse; -+ } -+ -+ error("aggregate or function expected instead of '%s'", o->toChars()); -+ goto Lfalse; -+ } - else if (ident == Id::isAbstractFunction) - { - FuncDeclaration *f; -@@ -186,7 +267,7 @@ Expression *TraitsExp::semantic(Scope *s - else if (ident == Id::isFinalFunction) - { - FuncDeclaration *f; -- ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isFinal()) -+ ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isFinalFunc()) - } - #if DMDV2 - else if (ident == Id::isStaticFunction) -@@ -217,7 +298,7 @@ Expression *TraitsExp::semantic(Scope *s - - if (dim != 1) - goto Ldimerror; -- Object *o = (*args)[0]; -+ RootObject *o = (*args)[0]; - Parameter *po = isParameter(o); - Identifier *id; - if (po) -@@ -241,7 +322,13 @@ Expression *TraitsExp::semantic(Scope *s - { - if (dim != 1) - goto Ldimerror; -- Object *o = (*args)[0]; -+ -+ Scope *sc2 = sc->push(); -+ sc2->flags = sc->flags | SCOPEnoaccesscheck; -+ TemplateInstance::semanticTiargs(loc, sc2, args, 1); -+ sc2->pop(); -+ -+ RootObject *o = (*args)[0]; - Dsymbol *s = getDsymbol(o); - if (!s) - { -@@ -249,11 +336,13 @@ Expression *TraitsExp::semantic(Scope *s - error("argument %s has no protection", o->toChars()); - goto Lfalse; - } -- -+ if (s->scope) -+ s->semantic(s->scope); - PROT protection = s->prot(); - - const char *protName = Pprotectionnames[protection]; - -+ assert(protName); - StringExp *se = new StringExp(loc, (char *) protName); - return se->semantic(sc); - } -@@ -261,7 +350,7 @@ Expression *TraitsExp::semantic(Scope *s - { - if (dim != 1) - goto Ldimerror; -- Object *o = (*args)[0]; -+ RootObject *o = (*args)[0]; - Dsymbol *s = getDsymbol(o); - if (s) - { -@@ -286,7 +375,7 @@ Expression *TraitsExp::semantic(Scope *s - { - if (dim != 2) - goto Ldimerror; -- Object *o = (*args)[0]; -+ RootObject *o = (*args)[0]; - Expression *e = isExpression((*args)[1]); - if (!e) - { error("expression expected as second argument of __traits %s", ident->toChars()); -@@ -305,17 +394,17 @@ Expression *TraitsExp::semantic(Scope *s - } - Identifier *id = Lexer::idPool((char *)se->string); - -- Type *t = isType(o); -- e = isExpression(o); -- Dsymbol *s = isDsymbol(o); -- if (t) -- e = typeDotIdExp(loc, t, id); -- else if (e) -- e = new DotIdExp(loc, e, id); -- else if (s) -- { e = new DsymbolExp(loc, s); -+ /* Prefer dsymbol, because it might need some runtime contexts. -+ */ -+ Dsymbol *sym = getDsymbol(o); -+ if (sym) -+ { e = new DsymbolExp(loc, sym); - e = new DotIdExp(loc, e, id); - } -+ else if (Type *t = isType(o)) -+ e = typeDotIdExp(loc, t, id); -+ else if (Expression *ex = isExpression(o)) -+ e = new DotIdExp(loc, ex, id); - else - { error("invalid first argument"); - goto Lfalse; -@@ -323,21 +412,16 @@ Expression *TraitsExp::semantic(Scope *s - - if (ident == Id::hasMember) - { -- if (t) -+ if (sym) - { -- Dsymbol *sym = t->toDsymbol(sc); -- if (sym) -- { -- Dsymbol *sm = sym->search(loc, id, 0); -- if (sm) -- goto Ltrue; -- } -+ Dsymbol *sm = sym->search(loc, id, 0); -+ if (sm) -+ goto Ltrue; - } - - /* Take any errors as meaning it wasn't found - */ - Scope *sc2 = sc->push(); -- //sc2->inHasMember++; - e = e->trySemantic(sc2); - sc2->pop(); - if (!e) -@@ -384,7 +468,7 @@ Expression *TraitsExp::semantic(Scope *s - p.exps = exps; - p.e1 = e; - p.ident = ident; -- overloadApply(f, fptraits, &p); -+ overloadApply(f, &p, &fptraits); - - TupleExp *tup = new TupleExp(loc, exps); - return tup->semantic(sc); -@@ -396,7 +480,7 @@ Expression *TraitsExp::semantic(Scope *s - { - if (dim != 1) - goto Ldimerror; -- Object *o = (*args)[0]; -+ RootObject *o = (*args)[0]; - Dsymbol *s = getDsymbol(o); - ClassDeclaration *cd; - if (!s || (cd = s->isClassDeclaration()) == NULL) -@@ -410,10 +494,16 @@ Expression *TraitsExp::semantic(Scope *s - { - if (dim != 1) - goto Ldimerror; -- Object *o = (*args)[0]; -+ RootObject *o = (*args)[0]; - Dsymbol *s = getDsymbol(o); - if (!s) - { -+ #if 0 -+ Expression *e = isExpression(o); -+ Type *t = isType(o); -+ if (e) printf("e = %s %s\n", Token::toChars(e->op), e->toChars()); -+ if (t) printf("t = %d %s\n", t->ty, t->toChars()); -+ #endif - error("first argument is not a symbol"); - goto Lfalse; - } -@@ -427,7 +517,7 @@ Expression *TraitsExp::semantic(Scope *s - { - if (dim != 1) - goto Ldimerror; -- Object *o = (*args)[0]; -+ RootObject *o = (*args)[0]; - Dsymbol *s = getDsymbol(o); - ScopeDsymbol *sd; - if (!s) -@@ -435,7 +525,12 @@ Expression *TraitsExp::semantic(Scope *s - error("argument has no members"); - goto Lfalse; - } -- if ((sd = s->isScopeDsymbol()) == NULL) -+ Import *import; -+ if ((import = s->isImport()) != NULL) -+ { // Bugzilla 9692 -+ sd = import->mod; -+ } -+ else if ((sd = s->isScopeDsymbol()) == NULL) - { - error("%s %s has no members", s->kind(), s->toChars()); - goto Lfalse; -@@ -451,6 +546,14 @@ Expression *TraitsExp::semantic(Scope *s - //printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars()); - if (sm->ident) - { -+ if (sm->ident != Id::ctor && // backword compatibility -+ sm->ident != Id::dtor && // backword compatibility -+ sm->ident != Id::_postblit && // backword compatibility -+ memcmp(sm->ident->string, "__", 2) == 0) -+ { -+ return 0; -+ } -+ - //printf("\t%s\n", sm->ident->toChars()); - Identifiers *idents = (Identifiers *)ctx; - -@@ -468,6 +571,14 @@ Expression *TraitsExp::semantic(Scope *s - - idents->push(sm->ident); - } -+ else -+ { -+ EnumDeclaration *ed = sm->isEnumDeclaration(); -+ if (ed) -+ { -+ ScopeDsymbol::foreach(NULL, ed->members, &PushIdentsDg::dg, (Identifiers *)ctx); -+ } -+ } - return 0; - } - }; -@@ -525,37 +636,42 @@ Expression *TraitsExp::semantic(Scope *s - goto Lfalse; - - for (size_t i = 0; i < dim; i++) -- { Object *o = (*args)[i]; -- Expression *e; -- -+ { - unsigned errors = global.startGagging(); - unsigned oldspec = global.speculativeGag; - global.speculativeGag = global.gag; -- bool scSpec = sc->speculative; -+ sc = sc->push(); - sc->speculative = true; -+ sc->flags = sc->enclosing->flags & ~SCOPEctfe; // inherit without CTFEing -+ bool err = false; - -+ RootObject *o = (*args)[i]; - Type *t = isType(o); -- if (t) -- { Dsymbol *s; -+ Expression *e = t ? t->toExpression() : isExpression(o); -+ if (!e && t) -+ { -+ Dsymbol *s; - t->resolve(loc, sc, &e, &t, &s); - if (t) -+ { - t->semantic(loc, sc); -- else if (e) -- { e = e->semantic(sc); -- e = e->optimize(WANTvalue); -+ if (t->ty == Terror) -+ err = true; - } -+ else if (s && s->errors) -+ err = true; - } -- else -- { e = isExpression(o); -- if (e) -- { e = e->semantic(sc); -- e = e->optimize(WANTvalue); -- } -+ if (e) -+ { -+ e = e->semantic(sc); -+ e = e->optimize(WANTvalue); -+ if (e->op == TOKerror) -+ err = true; - } - -- sc->speculative = scSpec; -+ sc = sc->pop(); - global.speculativeGag = oldspec; -- if (global.endGagging(errors)) -+ if (global.endGagging(errors) || err) - { - goto Lfalse; - } -@@ -568,8 +684,8 @@ Expression *TraitsExp::semantic(Scope *s - if (dim != 2) - goto Ldimerror; - TemplateInstance::semanticTiargs(loc, sc, args, 0); -- Object *o1 = (*args)[0]; -- Object *o2 = (*args)[1]; -+ RootObject *o1 = (*args)[0]; -+ RootObject *o2 = (*args)[1]; - Dsymbol *s1 = getDsymbol(o1); - Dsymbol *s2 = getDsymbol(o2); - -@@ -615,6 +731,64 @@ Expression *TraitsExp::semantic(Scope *s - else - goto Lfalse; - } -+ else if (ident == Id::getUnitTests) -+ { -+ if (dim != 1) -+ goto Ldimerror; -+ RootObject *o = (*args)[0]; -+ Dsymbol *s = getDsymbol(o); -+ if (!s) -+ { -+ error("argument %s to __traits(getUnitTests) must be a module or aggregate", o->toChars()); -+ goto Lfalse; -+ } -+ -+ Import *imp = s->isImport(); -+ if (imp) // Bugzilla 10990 -+ s = imp->mod; -+ -+ ScopeDsymbol* scope = s->isScopeDsymbol(); -+ -+ if (!scope) -+ { -+ error("argument %s to __traits(getUnitTests) must be a module or aggregate, not a %s", s->toChars(), s->kind()); -+ goto Lfalse; -+ } -+ -+ Expressions* unitTests = new Expressions(); -+ Dsymbols* symbols = scope->members; -+ -+ if (global.params.useUnitTests && symbols) -+ { -+ // Should actually be a set -+ AA* uniqueUnitTests = NULL; -+ collectUnitTests(symbols, uniqueUnitTests, unitTests); -+ } -+ -+ TupleExp *tup = new TupleExp(loc, unitTests); -+ return tup->semantic(sc); -+ } -+ else if (ident == Id::isOverrideFunction) -+ { -+ FuncDeclaration *f; -+ ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isOverride()) -+ } -+ else if(ident == Id::getVirtualIndex) -+ { -+ if (dim != 1) -+ goto Ldimerror; -+ RootObject *o = (*args)[0]; -+ Dsymbol *s = getDsymbol(o); -+ FuncDeclaration *fd; -+ if (!s || (fd = s->isFuncDeclaration()) == NULL) -+ { -+ error("first argument to __traits(getVirtualIndex) must be a function"); -+ goto Lfalse; -+ } -+ fd = fd->toAliasFunc(); // Neccessary to support multiple overloads. -+ ptrdiff_t result = fd->isVirtual() ? fd->vtblIndex : -1; -+ return new IntegerExp(loc, fd->vtblIndex, Type::tptrdiff_t); -+ } - else - { error("unrecognized trait %s", ident->toChars()); - goto Lfalse; -@@ -623,7 +797,7 @@ Expression *TraitsExp::semantic(Scope *s - return NULL; - - Ldimerror: -- error("wrong number of arguments %d", dim); -+ error("wrong number of arguments %d", (int)dim); - goto Lfalse; - - -@@ -634,5 +808,4 @@ Ltrue: - return new IntegerExp(loc, 1, Type::tbool); - } - -- - #endif ---- a/src/gcc/d/dfrontend/utf.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/utf.c 2014-04-01 16:32:51.000000000 +0100 -@@ -19,9 +19,6 @@ - - #include "utf.h" - --namespace --{ -- - /* The following encodings are valid, except for the 5 and 6 byte - * combinations: - * 0xxxxxxx -@@ -51,11 +48,6 @@ const unsigned UTF8_STRIDE[256] = - 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF, - }; - --} // namespace -- --namespace Unicode --{ -- - // UTF-8 decoding errors - char const UTF8_DECODE_OUTSIDE_CODE_SPACE[] = "Outside Unicode code space"; - char const UTF8_DECODE_TRUNCATED_SEQUENCE[] = "Truncated UTF-8 sequence"; -@@ -69,10 +61,6 @@ char const UTF16_DECODE_INVALID_SURROGAT - char const UTF16_DECODE_UNPAIRED_SURROGATE[]= "Unpaired surrogate"; - char const UTF16_DECODE_INVALID_CODE_POINT[]= "Invalid code point decoded"; - --} // namespace Unicode -- --using namespace Unicode; -- - /// The Unicode code space is the range of code points [0x000000,0x10FFFF] - /// except the UTF-16 surrogate pairs in the range [0xD800,0xDFFF] - /// and non-characters (which end in 0xFFFE or 0xFFFF). ---- a/src/gcc/d/dfrontend/utf.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/utf.h 2014-04-01 16:32:51.000000000 +0100 -@@ -20,9 +20,6 @@ typedef unsigned short utf16_t; - typedef unsigned int utf32_t; - typedef utf32_t dchar_t; - --namespace Unicode --{ -- - static utf16_t const ALPHA_TABLE[][2] = - { - { 0x00AA, 0x00AA }, { 0x00B5, 0x00B5 }, { 0x00B7, 0x00B7 }, { 0x00BA, 0x00BA }, -@@ -102,8 +99,6 @@ extern char const UTF16_DECODE_INVALID_S - extern char const UTF16_DECODE_UNPAIRED_SURROGATE[]; - extern char const UTF16_DECODE_INVALID_CODE_POINT[]; - --} // namespace Unicode -- - /// \return true if \a c is a valid, non-private UTF-32 code point - bool utf_isValidDchar(dchar_t c); - ---- a/src/gcc/d/dfrontend/version.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/version.c 2014-04-01 16:32:51.000000000 +0100 -@@ -57,11 +57,17 @@ int DebugSymbol::addMember(Scope *sc, Sc - if (ident) - { - if (!m) -+ { - error("declaration must be at module level"); -+ errors = true; -+ } - else - { - if (findCondition(m->debugidsNot, ident)) -+ { - error("defined after use"); -+ errors = true; -+ } - if (!m->debugids) - m->debugids = new Strings(); - m->debugids->push(ident->toChars()); -@@ -70,7 +76,10 @@ int DebugSymbol::addMember(Scope *sc, Sc - else - { - if (!m) -+ { - error("level declaration must be at module level"); -+ errors = true; -+ } - else - m->debuglevel = level; - } -@@ -138,11 +147,17 @@ int VersionSymbol::addMember(Scope *sc, - { - VersionCondition::checkPredefined(loc, ident->toChars()); - if (!m) -+ { - error("declaration must be at module level"); -+ errors = true; -+ } - else - { - if (findCondition(m->versionidsNot, ident)) -+ { - error("defined after use"); -+ errors = true; -+ } - if (!m->versionids) - m->versionids = new Strings(); - m->versionids->push(ident->toChars()); -@@ -151,7 +166,10 @@ int VersionSymbol::addMember(Scope *sc, - else - { - if (!m) -+ { - error("level declaration must be at module level"); -+ errors = true; -+ } - else - m->versionlevel = level; - } ---- a/src/gcc/d/dfrontend/version.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/dfrontend/version.h 2014-04-01 16:32:51.000000000 +0100 -@@ -20,8 +20,9 @@ - struct OutBuffer; - struct HdrGenState; - --struct DebugSymbol : Dsymbol -+class DebugSymbol : public Dsymbol - { -+public: - unsigned level; - - DebugSymbol(Loc loc, Identifier *ident); -@@ -34,8 +35,9 @@ struct DebugSymbol : Dsymbol - const char *kind(); - }; - --struct VersionSymbol : Dsymbol -+class VersionSymbol : public Dsymbol - { -+public: - unsigned level; - - VersionSymbol(Loc loc, Identifier *ident); ---- a/src/gcc/d/d-glue.cc 1970-01-01 01:00:00.000000000 +0100 -+++ b/src/gcc/d/d-glue.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -0,0 +1,373 @@ -+// d-glue.cc -- D frontend for GCC. -+// Copyright (C) 2013 Free Software Foundation, Inc. -+ -+// GCC is free software; you can redistribute it and/or modify it under -+// the terms of the GNU General Public License as published by the Free -+// Software Foundation; either version 3, or (at your option) any later -+// version. -+ -+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -+// WARRANTY; without even the implied warranty of MERCHANTABILITY or -+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+// for more details. -+ -+// You should have received a copy of the GNU General Public License -+// along with GCC; see the file COPYING3. If not see -+// . -+ -+#include "d-system.h" -+#include "d-objfile.h" -+ -+#include "mars.h" -+#include "module.h" -+ -+Global global; -+ -+void -+Global::init (void) -+{ -+ this->mars_ext = "d"; -+ this->sym_ext = "d"; -+ this->hdr_ext = "di"; -+ this->doc_ext = "html"; -+ this->ddoc_ext = "ddoc"; -+ this->json_ext = "json"; -+ this->map_ext = "map"; -+ -+ this->obj_ext = "o"; -+ this->lib_ext = "a"; -+ this->dll_ext = "so"; -+ -+ this->version = "v" -+#include "verstr.h" -+ ; -+ -+ this->compiler.vendor = "GNU D"; -+ this->stdmsg = stdout; -+ this->main_d = "__main.d"; -+ -+ memset (&this->params, 0, sizeof (Param)); -+} -+ -+unsigned -+Global::startGagging (void) -+{ -+ this->gag++; -+ return this->gaggedErrors; -+} -+ -+bool -+Global::endGagging (unsigned oldGagged) -+{ -+ bool anyErrs = (this->gaggedErrors != oldGagged); -+ this->gag--; -+ -+ // Restore the original state of gagged errors; set total errors -+ // to be original errors + new ungagged errors. -+ this->errors -= (this->gaggedErrors - oldGagged); -+ this->gaggedErrors = oldGagged; -+ -+ return anyErrs; -+} -+ -+bool -+Global::isSpeculativeGagging (void) -+{ -+ if (!this->gag) -+ return false; -+ -+ if (this->gag != this->speculativeGag) -+ return false; -+ -+ return true; -+} -+ -+void -+Global::increaseErrorCount (void) -+{ -+ if (gag) -+ this->gaggedErrors++; -+ -+ this->errors++; -+} -+ -+Ungag -+Dsymbol::ungagSpeculative (void) -+{ -+ unsigned oldgag = global.gag; -+ -+ if (global.isSpeculativeGagging() && !isSpeculative()) -+ global.gag = 0; -+ -+ return Ungag (oldgag); -+} -+ -+Ungag::~Ungag (void) -+{ -+ global.gag = this->oldgag; -+} -+ -+ -+char * -+Loc::toChars (void) -+{ -+ OutBuffer buf; -+ -+ if (this->filename) -+ buf.printf ("%s", this->filename); -+ -+ if (this->linnum) -+ buf.printf (":%u", this->linnum); -+ -+ buf.writeByte (0); -+ -+ return (char *)buf.extractData(); -+} -+ -+Loc::Loc (Module *mod, unsigned linnum) -+{ -+ this->linnum = linnum; -+ this->filename = mod ? mod->srcfile->toChars() : NULL; -+} -+ -+bool -+Loc::equals (const Loc& loc) -+{ -+ if (this->linnum != loc.linnum) -+ return false; -+ -+ if (!FileName::equals (this->filename, loc.filename)) -+ return false; -+ -+ return true; -+} -+ -+ -+// Print a hard error message. -+ -+void -+error (Loc loc, const char *format, ...) -+{ -+ va_list ap; -+ va_start (ap, format); -+ verror (loc, format, ap); -+ va_end (ap); -+} -+ -+void -+error (const char *filename, unsigned linnum, const char *format, ...) -+{ -+ Loc loc; -+ va_list ap; -+ -+ loc.filename = CONST_CAST (char *, filename); -+ loc.linnum = linnum; -+ -+ va_start (ap, format); -+ verror (loc, format, ap); -+ va_end (ap); -+} -+ -+void -+verror (Loc loc, const char *format, va_list ap, -+ const char *p1, const char *p2, const char *) -+{ -+ if (!global.gag) -+ { -+ location_t location = get_linemap (loc); -+ char *msg; -+ -+ // Build string and emit. -+ if (p2) -+ format = concat (p2, " ", format, NULL); -+ -+ if (p1) -+ format = concat (p1, " ", format, NULL); -+ -+ if (vasprintf (&msg, format, ap) >= 0 && msg != NULL) -+ error_at (location, "%s", msg); -+ -+ // Moderate blizzard of cascading messages -+ if (global.errors >= 20) -+ fatal(); -+ } -+ else -+ global.gaggedErrors++; -+ -+ global.errors++; -+} -+ -+// Print supplementary message about the last error. -+// Doesn't increase error count. -+ -+void -+errorSupplemental (Loc loc, const char *format, ...) -+{ -+ va_list ap; -+ va_start (ap, format); -+ verrorSupplemental (loc, format, ap); -+ va_end (ap); -+} -+ -+void -+verrorSupplemental (Loc loc, const char *format, va_list ap) -+{ -+ if (!global.gag) -+ { -+ location_t location = get_linemap (loc); -+ char *msg; -+ -+ if (vasprintf (&msg, format, ap) >= 0 && msg != NULL) -+ inform (location, "%s", msg); -+ } -+} -+ -+// Print a warning message. -+ -+void -+warning (Loc loc, const char *format, ...) -+{ -+ va_list ap; -+ va_start (ap, format); -+ vwarning (loc, format, ap); -+ va_end (ap); -+} -+ -+void -+vwarning (Loc loc, const char *format, va_list ap) -+{ -+ if (global.params.warnings && !global.gag) -+ { -+ location_t location = get_linemap (loc); -+ char *msg; -+ -+ if (vasprintf (&msg, format, ap) >= 0 && msg != NULL) -+ warning_at (location, 0, "%s", msg); -+ -+ // Warnings don't count if gagged. -+ if (global.params.warnings == 1) -+ global.warnings++; -+ } -+} -+ -+// Print a deprecation message. -+ -+void -+deprecation (Loc loc, const char *format, ...) -+{ -+ va_list ap; -+ va_start (ap, format); -+ vdeprecation (loc, format, ap); -+ va_end (ap); -+} -+ -+void -+vdeprecation (Loc loc, const char *format, va_list ap, -+ const char *p1, const char *p2) -+{ -+ if (global.params.useDeprecated == 0) -+ verror (loc, format, ap, p1, p2); -+ else if (global.params.useDeprecated == 2 && !global.gag) -+ { -+ location_t location = get_linemap (loc); -+ char *msg; -+ -+ // Build string and emit. -+ if (p2) -+ format = concat (p2, " ", format, NULL); -+ -+ if (p1) -+ format = concat (p1, " ", format, NULL); -+ -+ if (vasprintf (&msg, format, ap) >= 0 && msg != NULL) -+ warning_at (location, OPT_Wdeprecated, "%s", msg); -+ } -+} -+ -+// Call this after printing out fatal error messages to clean up and exit -+// the compiler. -+ -+void -+fatal (void) -+{ -+ exit (FATAL_EXIT_CODE); -+} -+ -+ -+void -+escapePath (OutBuffer *buf, const char *fname) -+{ -+ while (1) -+ { -+ switch (*fname) -+ { -+ case 0: -+ return; -+ -+ case '(': -+ case ')': -+ case '\\': -+ buf->writebyte('\\'); -+ -+ default: -+ buf->writebyte(*fname); -+ break; -+ } -+ fname++; -+ } -+} -+ -+void -+readFile (Loc loc, File *f) -+{ -+ if (f->read()) -+ { -+ error (loc, "Error reading file '%s'", f->name->toChars()); -+ fatal(); -+ } -+} -+ -+void -+writeFile (Loc loc, File *f) -+{ -+ if (f->write()) -+ { -+ error (loc, "Error writing file '%s'", f->name->toChars()); -+ fatal(); -+ } -+} -+ -+void -+ensurePathToNameExists (Loc loc, const char *name) -+{ -+ const char *pt = FileName::path (name); -+ if (*pt) -+ { -+ if (FileName::ensurePathExists(pt)) -+ { -+ error (loc, "cannot create directory %s", pt); -+ fatal(); -+ } -+ } -+} -+ -+// Binary search for P in TAB between the range 0 to HIGH. -+ -+int binary(const char *p , const char **tab, int high) -+{ -+ int low = 0; -+ do -+ { -+ int pos = (low + high) / 2; -+ int cmp = strcmp(p, tab[pos]); -+ if (! cmp) -+ return pos; -+ else if (cmp < 0) -+ high = pos; -+ else -+ low = pos + 1; -+ } while (low != high); -+ -+ return -1; -+} -+ ---- a/src/gcc/d/d-gt.c 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-gt.c 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - /* d-gt.c -- D frontend for GCC. -- Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+ Copyright (C) 2011-2013 Free Software Foundation, Inc. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free ---- a/src/gcc/d/d-incpath.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-incpath.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-incpath.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -145,8 +145,8 @@ add_import_path (Strings *paths) - - for (size_t i = 0; i < paths->dim; i++) - { -- String p = (*paths)[i]; -- char *target_dir = make_absolute (p.toChars()); -+ char *path = (*paths)[i]; -+ char *target_dir = make_absolute (path); - - if (!FileName::exists (target_dir)) - { -@@ -171,8 +171,8 @@ add_fileimp_path (Strings *paths) - - for (size_t i = 0; i < paths->dim; i++) - { -- String p = (*paths)[i]; -- char *target_dir = make_absolute (p.toChars()); -+ char *path = (*paths)[i]; -+ char *target_dir = make_absolute (path); - - if (!FileName::exists (target_dir)) - { ---- a/src/gcc/d/d-ir.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-ir.cc 1970-01-01 01:00:00.000000000 +0100 -@@ -1,549 +0,0 @@ --// d-ir.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -- --// GCC is free software; you can redistribute it and/or modify it under --// the terms of the GNU General Public License as published by the Free --// Software Foundation; either version 3, or (at your option) any later --// version. -- --// GCC is distributed in the hope that it will be useful, but WITHOUT ANY --// WARRANTY; without even the implied warranty of MERCHANTABILITY or --// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --// for more details. -- --#include "d-system.h" -- --#include "id.h" --#include "enum.h" --#include "module.h" --#include "init.h" --#include "d-lang.h" --#include "d-codegen.h" -- -- --void --Statement::toIR (IRState *) --{ -- ::error ("Statement::toIR: don't know what to do (%s)", toChars()); -- gcc_unreachable(); --} -- --void --LabelStatement::toIR (IRState *irs) --{ -- FuncDeclaration *func = irs->func; -- LabelDsymbol *label = irs->isReturnLabel (ident) ? func->returnLabel : func->searchLabel (ident); -- tree t_label = irs->getLabelTree (label); -- -- if (t_label != NULL_TREE) -- { -- irs->pushLabel (label); -- irs->doLabel (t_label); -- if (irs->isReturnLabel (ident) && func->fensure) -- func->fensure->toIR (irs); -- else if (statement) -- statement->toIR (irs); -- if (fwdrefs) -- { -- irs->checkPreviousGoto (fwdrefs); -- delete fwdrefs; -- fwdrefs = NULL; -- } -- } -- // else, there was an error --} -- --void --GotoStatement::toIR (IRState *irs) --{ -- tree t_label; -- -- object_file->setLoc (loc); /* This makes the 'undefined label' error show up on the correct line... -- The extra doLineNote in doJump shouldn't cause a problem. */ -- if (!label->statement) -- error ("label %s is undefined", label->toChars()); -- else if (tf != label->statement->tf) -- error ("cannot goto forward out of or into finally block"); -- else -- irs->checkGoto (this, label); -- -- t_label = irs->getLabelTree (label); -- if (t_label != NULL_TREE) -- irs->doJump (this, t_label); -- // else, there was an error --} -- --void --GotoCaseStatement::toIR (IRState *irs) --{ -- // assumes cblocks have been set in SwitchStatement::toIR -- irs->doJump (this, cs->cblock); --} -- --void --GotoDefaultStatement::toIR (IRState *irs) --{ -- // assumes cblocks have been set in SwitchStatement::toIR -- irs->doJump (this, sw->sdefault->cblock); --} -- --void --SwitchErrorStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- irs->addExp (d_assert_call (loc, LIBCALL_SWITCH_ERROR)); --} -- --void --ThrowStatement::toIR (IRState *irs) --{ -- ClassDeclaration *class_decl = exp->type->toBasetype()->isClassHandle(); -- // Front end already checks for isClassHandle -- InterfaceDeclaration *intfc_decl = class_decl->isInterfaceDeclaration(); -- tree arg = exp->toElemDtor (irs); -- -- if (!flag_exceptions) -- { -- static int warned = 0; -- if (!warned) -- { -- error ("exception handling disabled, use -fexceptions to enable"); -- warned = 1; -- } -- } -- -- if (intfc_decl) -- { -- if (!intfc_decl->isCOMclass()) -- arg = convert_expr (arg, exp->type, build_object_type()); -- else -- error ("cannot throw COM interfaces"); -- } -- irs->doLineNote (loc); -- irs->addExp (build_libcall (LIBCALL_THROW, 1, &arg)); --} -- --void --TryFinallyStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- irs->startTry (this); -- if (body) -- body->toIR (irs); -- -- irs->startFinally(); -- if (finalbody) -- finalbody->toIR (irs); -- -- irs->endFinally(); --} -- --void --TryCatchStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- irs->startTry (this); -- if (body) -- body->toIR (irs); -- -- irs->startCatches(); -- if (catches) -- { -- for (size_t i = 0; i < catches->dim; i++) -- { -- Catch *a_catch = (*catches)[i]; -- -- irs->startCatch (a_catch->type->toCtype()); -- irs->doLineNote (a_catch->loc); -- irs->startScope(); -- -- if (a_catch->var) -- { -- tree exc_obj = convert_expr (build_exception_object(), -- build_object_type(), a_catch->type); -- tree catch_var = a_catch->var->toSymbol()->Stree; -- // need to override initializer... -- // set DECL_INITIAL now and emitLocalVar will know not to change it -- DECL_INITIAL (catch_var) = exc_obj; -- irs->emitLocalVar (a_catch->var); -- } -- -- if (a_catch->handler) -- a_catch->handler->toIR (irs); -- irs->endScope(); -- irs->endCatch(); -- } -- } -- irs->endCatches(); --} -- --void --OnScopeStatement::toIR (IRState *) --{ --} -- --void --WithStatement::toIR (IRState *irs) --{ -- irs->startScope(); -- if (wthis) -- irs->emitLocalVar (wthis); -- -- if (body) -- body->toIR (irs); -- -- irs->endScope(); --} -- --void --SynchronizedStatement::toIR (IRState *) --{ -- ::error ("SynchronizedStatement::toIR: we shouldn't emit this (%s)", toChars()); -- gcc_unreachable(); --} -- --void --ContinueStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- irs->continueLoop (ident); --} -- --void --BreakStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- irs->exitLoop (ident); --} -- --void --ReturnStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- -- if (exp == NULL || exp->type->toBasetype()->ty == Tvoid) -- { -- // Return has no value. -- irs->doReturn (NULL_TREE); -- return; -- } -- -- FuncDeclaration *func = irs->func; -- TypeFunction *tf = (TypeFunction *) func->type; -- Type *ret_type = func->tintro ? func->tintro->nextOf() : tf->nextOf(); -- -- if (func->isMain() && ret_type->toBasetype()->ty == Tvoid) -- ret_type = Type::tint32; -- -- tree result_decl = DECL_RESULT (irs->func->toSymbol()->Stree); -- -- if (func->nrvo_can && func->nrvo_var) -- { -- // Just refer to the RESULT_DECL; this is a nop, but differs from using -- // NULL_TREE in that it indicates that we care about the value of the RESULT_DECL. -- irs->doReturn (result_decl); -- } -- else -- { -- tree result_value = convert_expr (exp->toElemDtor (irs), exp->type, ret_type); -- // %% convert for init -- if we were returning a reference, -- // would want to take the address... -- if (tf->isref) -- result_value = build_address (result_value); -- -- tree result_assign = build2 (INIT_EXPR, TREE_TYPE (result_decl), -- result_decl, result_value); -- -- irs->doReturn (result_assign); -- } --} -- --void --DefaultStatement::toIR (IRState *irs) --{ -- irs->checkSwitchCase (this, 1); -- irs->doCase (NULL_TREE, cblock); -- if (statement) -- statement->toIR (irs); --} -- --void --CaseStatement::toIR (IRState *irs) --{ -- tree case_value; -- -- if (exp->type->isscalar()) -- case_value = exp->toElem (irs); -- else -- case_value = build_integer_cst (index, Type::tint32->toCtype()); -- -- irs->checkSwitchCase (this); -- irs->doCase (case_value, cblock); -- if (statement) -- statement->toIR (irs); --} -- --void --SwitchStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- -- tree cond_tree = condition->toElemDtor (irs); -- Type *cond_type = condition->type->toBasetype(); -- -- if (condition->type->isString()) -- { -- Type *elem_type = cond_type->nextOf()->toBasetype(); -- LibCall libcall; -- switch (elem_type->ty) -- { -- case Tchar: -- libcall = LIBCALL_SWITCH_STRING; -- break; -- -- case Twchar: -- libcall = LIBCALL_SWITCH_USTRING; -- break; -- -- case Tdchar: -- libcall = LIBCALL_SWITCH_DSTRING; -- break; -- -- default: -- ::error ("switch statement value must be an array of some character type, not %s", -- elem_type->toChars()); -- gcc_unreachable(); -- } -- -- // Apparently the backend is supposed to sort and set the indexes -- // on the case array, have to change them to be useable. -- cases->sort(); -- -- tree args[2]; -- Symbol *s = new Symbol(); -- dt_t **pdt = &s->Sdt; -- -- for (size_t i = 0; i < cases->dim; i++) -- { -- CaseStatement *cs = (*cases)[i]; -- cs->index = i; -- -- if (cs->exp->op != TOKstring) -- error("case '%s' is not a string", cs->exp->toChars()); -- else -- pdt = cs->exp->toDt (pdt); -- } -- -- s->Sreadonly = true; -- d_finish_symbol (s); -- -- args[0] = d_array_value (cond_type->arrayOf()->toCtype(), -- size_int (cases->dim), -- build_address (s->Stree)); -- args[1] = cond_tree; -- -- cond_tree = build_libcall (libcall, 2, args); -- } -- else if (!cond_type->isscalar()) -- { -- ::error ("cannot handle switch condition of type %s", cond_type->toChars()); -- gcc_unreachable(); -- } -- -- if (cases) -- { -- // Build LABEL_DECLs now so they can be refered to by goto case -- for (size_t i = 0; i < cases->dim; i++) -- { -- CaseStatement *case_stmt = (*cases)[i]; -- case_stmt->cblock = d_build_label (case_stmt->loc, NULL); -- } -- if (sdefault) -- sdefault->cblock = d_build_label (sdefault->loc, NULL); -- } -- cond_tree = fold (cond_tree); -- -- if (hasVars) -- { -- // Write cases as a series of if-then-else blocks. -- for (size_t i = 0; i < cases->dim; i++) -- { -- CaseStatement *case_stmt = (*cases)[i]; -- tree case_cond = build2 (EQ_EXPR, cond_type->toCtype(), cond_tree, -- case_stmt->exp->toElemDtor (irs)); -- irs->startCond (this, case_cond); -- irs->doJump (NULL, case_stmt->cblock); -- irs->endCond(); -- } -- if (sdefault) -- irs->doJump (NULL, sdefault->cblock); -- } -- -- // Emit body. -- irs->startCase (this, cond_tree, hasVars); -- if (body) -- body->toIR (irs); -- irs->endCase(); --} -- -- --void --IfStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- irs->startScope(); -- irs->startCond (this, convert_for_condition (condition->toElemDtor (irs), -- condition->type)); -- if (ifbody) -- ifbody->toIR (irs); -- -- if (elsebody) -- { -- irs->startElse(); -- elsebody->toIR (irs); -- } -- irs->endCond(); -- irs->endScope(); --} -- --void --ForeachStatement::toIR (IRState *) --{ -- ::error ("ForeachStatement::toIR: we shouldn't emit this (%s)", toChars()); -- gcc_unreachable(); --} -- --void --ForeachRangeStatement::toIR (IRState *) --{ -- ::error ("ForeachRangeStatement::toIR: we shouldn't emit this (%s)", toChars()); -- gcc_unreachable(); --} -- --void --ForStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- if (init) -- init->toIR (irs); -- irs->startLoop (this); -- if (condition) -- { -- irs->doLineNote (condition->loc); -- irs->exitIfFalse (convert_for_condition (condition->toElemDtor (irs), -- condition->type)); -- } -- if (body) -- body->toIR (irs); -- irs->continueHere(); -- if (increment) -- { -- // force side effects? -- irs->doLineNote (increment->loc); -- irs->addExp (increment->toElemDtor (irs)); -- } -- irs->endLoop(); --} -- --void --DoStatement::toIR (IRState *irs) --{ -- irs->doLineNote (loc); -- irs->startLoop (this); -- if (body) -- body->toIR (irs); -- irs->continueHere(); -- irs->doLineNote (condition->loc); -- irs->exitIfFalse (convert_for_condition (condition->toElemDtor (irs), -- condition->type)); -- irs->endLoop(); --} -- --void --WhileStatement::toIR (IRState *) --{ -- ::error ("WhileStatement::toIR: we shouldn't emit this (%s)", toChars()); -- gcc_unreachable(); --} -- --void --ScopeStatement::toIR (IRState *irs) --{ -- if (statement) -- { -- irs->startScope(); -- statement->toIR (irs); -- irs->endScope(); -- } --} -- --void --CompoundStatement::toIR (IRState *irs) --{ -- if (!statements) -- return; -- -- for (size_t i = 0; i < statements->dim; i++) -- { -- Statement *statement = (*statements)[i]; -- if (statement) -- statement->toIR (irs); -- } --} -- --void --UnrolledLoopStatement::toIR (IRState *irs) --{ -- if (!statements) -- return; -- -- irs->startLoop (this); -- irs->continueHere(); -- for (size_t i = 0; i < statements->dim; i++) -- { -- Statement *statement = (*statements)[i]; -- if (statement) -- { -- irs->setContinueLabel (d_build_label (loc, NULL)); -- statement->toIR (irs); -- irs->continueHere(); -- } -- } -- irs->exitLoop (NULL); -- irs->endLoop(); --} -- --void --ExpStatement::toIR (IRState *irs) --{ -- if (exp) -- { -- irs->doLineNote (loc); -- tree exp_tree = exp->toElemDtor (irs); -- irs->addExp (exp_tree); -- } --} -- --void --DtorExpStatement::toIR (IRState *irs) --{ -- FuncDeclaration *fd = irs->func; -- -- /* Do not call destructor if var is returned as the -- nrvo variable. */ -- bool noDtor = (fd->nrvo_can && fd->nrvo_var == var); -- -- if (!noDtor) -- ExpStatement::toIR (irs); --} -- --void --PragmaStatement::toIR (IRState *) --{ --} -- --void --ImportStatement::toIR (IRState *) --{ --} -- ---- a/src/gcc/d/d-irstate.cc 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-irstate.cc 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-irstate.cc -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -22,20 +22,33 @@ - - #include "init.h" - --IRBase::IRBase (void) -+IRState::IRState (void) - { - this->parent = NULL; - this->func = NULL; -- this->varsInScope = NULL; - this->mod = NULL; - this->sthis = NULL_TREE; -+ this->varsInScope = vNULL; -+ this->statementList_ = vNULL; -+ this->scopes_ = vNULL; -+ this->loops_ = vNULL; -+ this->labels_ = vNULL; -+} -+ -+IRState::~IRState (void) -+{ -+ this->varsInScope.release(); -+ this->statementList_.release(); -+ this->scopes_.release(); -+ this->loops_.release(); -+ this->labels_.release(); - } - - IRState * --IRBase::startFunction (FuncDeclaration *decl) -+IRState::startFunction (FuncDeclaration *decl) - { - IRState *new_irs = new IRState(); -- new_irs->parent = cirstate; -+ new_irs->parent = current_irstate; - new_irs->func = decl; - - for (Dsymbol *p = decl->parent; p; p = p->parent) -@@ -47,45 +60,45 @@ IRBase::startFunction (FuncDeclaration * - } - } - -- cirstate = (IRState *) new_irs; -- ModuleInfo & mi = *object_file->moduleInfo; -+ current_irstate = (IRState *) new_irs; -+ ModuleInfo *mi = current_module_info; - - if (decl->isSharedStaticCtorDeclaration()) -- mi.sharedctors.push (decl); -+ mi->sharedctors.safe_push (decl); - else if (decl->isStaticCtorDeclaration()) -- mi.ctors.push (decl); -+ mi->ctors.safe_push (decl); - else if (decl->isSharedStaticDtorDeclaration()) - { - VarDeclaration *vgate; - if ((vgate = decl->isSharedStaticDtorDeclaration()->vgate)) -- mi.sharedctorgates.push (vgate); -- mi.shareddtors.push (decl); -+ mi->sharedctorgates.safe_push (vgate); -+ mi->shareddtors.safe_push (decl); - } - else if (decl->isStaticDtorDeclaration()) - { - VarDeclaration *vgate; - if ((vgate = decl->isStaticDtorDeclaration()->vgate)) -- mi.ctorgates.push (vgate); -- mi.dtors.push (decl); -+ mi->ctorgates.safe_push (vgate); -+ mi->dtors.safe_push (decl); - } - else if (decl->isUnitTestDeclaration()) -- mi.unitTests.push (decl); -+ mi->unitTests.safe_push (decl); - - return new_irs; - } - - void --IRBase::endFunction (void) -+IRState::endFunction (void) - { -- gcc_assert (this->scopes.dim == 0); -- cirstate = (IRState *) this->parent; -+ gcc_assert (this->scopes_.is_empty()); -+ current_irstate = (IRState *) this->parent; - } - - - // Emit statement E into function body. - - void --IRBase::addExp (tree e) -+IRState::addExp (tree e) - { - /* Need to check that this is actually an expression; it - could be an integer constant (statement with no effect.) -@@ -104,24 +117,24 @@ IRBase::addExp (tree e) - if (EXPR_P (e) && !EXPR_HAS_LOCATION (e)) - SET_EXPR_LOCATION (e, input_location); - -- tree stmt_list = (tree) this->statementList.pop(); -+ tree stmt_list = this->statementList_.pop(); - append_to_statement_list_force (e, &stmt_list); -- this->statementList.push (stmt_list); -+ this->statementList_.safe_push (stmt_list); - } - - - void --IRBase::pushStatementList (void) -+IRState::pushStatementList (void) - { - tree t = alloc_stmt_list(); -- this->statementList.push (t); -+ this->statementList_.safe_push (t); - d_keep (t); - } - - tree --IRBase::popStatementList (void) -+IRState::popStatementList (void) - { -- tree t = (tree) this->statementList.pop(); -+ tree t = this->statementList_.pop(); - - /* If the statement list is completely empty, just return it. This is - just as good small as build_empty_stmt, with the advantage that -@@ -147,7 +160,7 @@ IRBase::popStatementList (void) - - - tree --IRBase::getLabelTree (LabelDsymbol *label) -+IRState::getLabelTree (LabelDsymbol *label) - { - if (!label->statement) - return NULL_TREE; -@@ -162,13 +175,13 @@ IRBase::getLabelTree (LabelDsymbol *labe - } - - Label * --IRBase::getLabelBlock (LabelDsymbol *label, Statement *from) -+IRState::getLabelBlock (LabelDsymbol *label, Statement *from) - { - Label *l = new Label(); - -- for (int i = this->loops.dim - 1; i >= 0; i--) -+ for (int i = this->loops_.length() - 1; i >= 0; i--) - { -- Flow *flow = this->loops[i]; -+ Flow *flow = this->loops_[i]; - - if (flow->kind != level_block - && flow->kind != level_switch) -@@ -188,167 +201,168 @@ IRBase::getLabelBlock (LabelDsymbol *lab - - - Flow * --IRBase::getLoopForLabel (Identifier *ident, bool want_continue) -+IRState::getLoopForLabel (Identifier *ident, bool want_continue) - { - if (ident) - { -- LabelStatement *lbl_stmt = this->func->searchLabel (ident)->statement; -- gcc_assert (lbl_stmt != 0); -- Statement *stmt = lbl_stmt->statement; -- ScopeStatement *scope_stmt = stmt->isScopeStatement(); -- -- if (scope_stmt) -- stmt = scope_stmt->statement; -+ LabelStatement *lstmt = this->func->searchLabel (ident)->statement; -+ gcc_assert (lstmt != NULL); -+ // The break label for a loop may actually be some levels up; -+ // eg: on a try/finally wrapping a loop. -+ Statement *stmt = lstmt->statement->getRelatedLabeled(); - -- for (int i = this->loops.dim - 1; i >= 0; i--) -+ for (int i = this->loops_.length() - 1; i >= 0; i--) - { -- Flow *flow = this->loops[i]; -+ Flow *flow = this->loops_[i]; - -- if (flow->statement == stmt) -+ if (flow->statement->getRelatedLabeled() == stmt) - { - if (want_continue) -- gcc_assert (stmt->hasContinue()); -+ gcc_assert (flow->statement->hasContinue()); - return flow; - } - } -- gcc_unreachable(); - } - else - { -- for (int i = this->loops.dim - 1; i >= 0; i--) -+ for (int i = this->loops_.length() - 1; i >= 0; i--) - { -- Flow *flow = this->loops[i]; -+ Flow *flow = this->loops_[i]; - - if ((!want_continue && flow->statement->hasBreak()) - || flow->statement->hasContinue()) - return flow; - } -- gcc_unreachable(); - } -+ -+ return NULL; - } - - - Flow * --IRBase::beginFlow (Statement *stmt) -+IRState::beginFlow (Statement *stmt) - { - Flow *flow = new Flow (stmt); -- this->loops.push (flow); -- pushStatementList(); -+ this->loops_.safe_push (flow); -+ this->pushStatementList(); - return flow; - } - - void --IRBase::endFlow (void) -+IRState::endFlow (void) - { -- Flow *flow; -+ gcc_assert (!this->loops_.is_empty()); - -- gcc_assert (this->loops.dim); -+ Flow *flow = this->loops_.pop(); - -- flow = (Flow *) this->loops.pop(); - if (flow->exitLabel) -- doLabel (flow->exitLabel); -- //%% delete flow; -+ this->doLabel (flow->exitLabel); - } - - void --IRBase::doLabel (tree t_label) -+IRState::doLabel (tree label) - { - /* Don't write out label unless it is marked as used by the frontend. - This makes auto-vectorization possible in conditional loops. - The only excemption to this is in LabelStatement::toIR, in which - all computed labels are marked regardless. */ -- if (TREE_USED (t_label)) -- addExp (build1 (LABEL_EXPR, void_type_node, t_label)); -+ if (TREE_USED (label)) -+ this->addExp (build1 (LABEL_EXPR, void_type_node, label)); - } - - - void --IRBase::startScope (void) -+IRState::startScope (void) - { - unsigned *p_count = new unsigned; - *p_count = 0; -- this->scopes.push (p_count); -- startBindings(); -+ -+ this->scopes_.safe_push (p_count); -+ this->startBindings(); - } - - void --IRBase::endScope (void) -+IRState::endScope (void) - { -- unsigned *p_count = currentScope(); -+ unsigned *p_count = this->currentScope(); - while (*p_count) -- endBindings(); -+ this->endBindings(); - -- this->scopes.pop(); -+ this->scopes_.pop(); - } - - - void --IRBase::startBindings (void) -+IRState::startBindings (void) - { -- pushlevel (0); -- tree block = make_node (BLOCK); -- set_block (block); -+ tree block; - -- pushStatementList(); -+ push_binding_level(); -+ block = make_node (BLOCK); -+ current_binding_level->this_block = block; - -- ++(*currentScope()); -+ this->pushStatementList(); -+ -+ ++(*this->currentScope()); - } - - void --IRBase::endBindings (void) -+IRState::endBindings (void) - { -- tree block = poplevel (1,0,0); -+ tree block = pop_binding_level (1, 0); -+ TREE_USED (block) = 1; - -- tree t_body = popStatementList(); -- addExp (build3 (BIND_EXPR, void_type_node, -- BLOCK_VARS (block), t_body, block)); -+ tree body = this->popStatementList(); -+ this->addExp (build3 (BIND_EXPR, void_type_node, -+ BLOCK_VARS (block), body, block)); - -- // Because we used set_block, the popped level/block is not automatically recorded -- insert_block (block); -+ // The popped level/block is not automatically recorded -+ current_binding_level->blocks = block_chainon (current_binding_level->blocks, block); - -- --(*currentScope()); -- gcc_assert (*(int *) currentScope() >= 0); -+ --(*this->currentScope()); -+ gcc_assert (*(int *) this->currentScope() >= 0); - } - - - // Routines for building statement lists around if/else conditions. --// STMT contains the statement to be executed if T_COND is true. -+// STMT contains the statement to be executed if COND is true. - - void --IRBase::startCond (Statement *stmt, tree t_cond) -+IRState::startCond (Statement *stmt, tree cond) - { -- Flow *f = beginFlow (stmt); -- f->condition = t_cond; -+ Flow *flow = this->beginFlow (stmt); -+ flow->condition = cond; - } - - // Start a new statement list for the false condition branch. - - void --IRBase::startElse (void) -+IRState::startElse (void) - { -- currentFlow()->trueBranch = popStatementList(); -- pushStatementList(); -+ Flow *flow = this->currentFlow(); -+ flow->trueBranch = this->popStatementList(); -+ this->pushStatementList(); - } - - // Wrap up our constructed if condition into a COND_EXPR. - - void --IRBase::endCond (void) -+IRState::endCond (void) - { -- Flow *f = currentFlow(); -- tree t_brnch = popStatementList(); -- tree t_false_brnch = NULL_TREE; -+ Flow *flow = this->currentFlow(); -+ tree branch = this->popStatementList(); -+ tree false_branch = NULL_TREE; - -- if (f->trueBranch == NULL_TREE) -- f->trueBranch = t_brnch; -+ if (flow->trueBranch == NULL_TREE) -+ flow->trueBranch = branch; - else -- t_false_brnch = t_brnch; -+ false_branch = branch; - -- object_file->doLineNote (f->statement->loc); -- tree t_stmt = build3 (COND_EXPR, void_type_node, -- f->condition, f->trueBranch, t_false_brnch); -- endFlow(); -- addExp (t_stmt); -+ this->doLineNote (flow->statement->loc); -+ tree stmt = build3 (COND_EXPR, void_type_node, -+ flow->condition, flow->trueBranch, false_branch); -+ this->endFlow(); -+ this->addExp (stmt); - } - - -@@ -356,240 +370,307 @@ IRBase::endCond (void) - // STMT is the body of the loop. - - void --IRBase::startLoop (Statement *stmt) -+IRState::startLoop (Statement *stmt) - { -- Flow *f = beginFlow (stmt); -+ Flow *flow = this->beginFlow (stmt); - // should be end for 'do' loop -- f->continueLabel = d_build_label (stmt ? stmt->loc : 0, NULL); -+ flow->continueLabel = d_build_label (stmt ? stmt->loc : Loc(), NULL); - } - - // Emit continue label for loop. - - void --IRBase::continueHere (void) -+IRState::continueHere (void) - { -- doLabel (currentFlow()->continueLabel); -+ Flow *flow = this->currentFlow(); -+ this->doLabel (flow->continueLabel); - } - - // Set LBL as the continue label for the current loop. - // Used in unrolled loop statements. - - void --IRBase::setContinueLabel (tree lbl) -+IRState::setContinueLabel (tree label) - { -- currentFlow()->continueLabel = lbl; -+ Flow *flow = this->currentFlow(); -+ flow->continueLabel = label; - } - - // Emit exit loop condition. - - void --IRBase::exitIfFalse (tree t_cond) -+IRState::exitIfFalse (tree cond) - { -- addExp (build1 (EXIT_EXPR, void_type_node, -- build1 (TRUTH_NOT_EXPR, TREE_TYPE (t_cond), t_cond))); -+ this->addExp (build1 (EXIT_EXPR, void_type_node, -+ build1 (TRUTH_NOT_EXPR, TREE_TYPE (cond), cond))); - } - - // Emit a goto to the continue label IDENT of a loop. - - void --IRBase::continueLoop (Identifier *ident) -+IRState::continueLoop (Identifier *ident) - { -- doJump (NULL, getLoopForLabel (ident, true)->continueLabel); -+ Flow *flow = this->getLoopForLabel (ident, true); -+ gcc_assert (flow); -+ this->doJump (NULL, flow->continueLabel); - } - - // Emit a goto to the exit label IDENT of a loop. - - void --IRBase::exitLoop (Identifier *ident) -+IRState::exitLoop (Identifier *ident) - { -- Flow *flow = getLoopForLabel (ident); -+ Flow *flow = this->getLoopForLabel (ident); -+ gcc_assert (flow); -+ - if (!flow->exitLabel) - flow->exitLabel = d_build_label (flow->statement->loc, NULL); -- doJump (NULL, flow->exitLabel); -+ -+ this->doJump (NULL, flow->exitLabel); - } - - // Wrap up constructed loop body in a LOOP_EXPR. - - void --IRBase::endLoop (void) -+IRState::endLoop (void) - { - // says must contain an EXIT_EXPR -- what about while (1)..goto;? something other thand LOOP_EXPR? -- tree t_body = popStatementList(); -- tree t_loop = build1 (LOOP_EXPR, void_type_node, t_body); -- addExp (t_loop); -- endFlow(); -+ tree body = this->popStatementList(); -+ tree loop = build1 (LOOP_EXPR, void_type_node, body); -+ this->addExp (loop); -+ this->endFlow(); - } - - -+// Create a tree node to set multiple elements to a single value -+ -+tree -+IRState::doArraySet(tree ptr, tree value, tree count) -+{ -+ tree t; -+ -+ pushStatementList(); -+ startBindings(); -+ -+ // Build temporary locals for count and ptr, and maybe value. -+ t = build_local_temp (size_type_node); -+ DECL_INITIAL (t) = count; -+ count = t; -+ expand_decl (count); -+ -+ t = build_local_temp (TREE_TYPE (ptr)); -+ DECL_INITIAL (t) = ptr; -+ ptr = t; -+ expand_decl (ptr); -+ -+ if (d_has_side_effects (value)) -+ { -+ t = build_local_temp (TREE_TYPE (value)); -+ DECL_INITIAL (t) = value; -+ value = t; -+ expand_decl (value); -+ } -+ -+ // Build loop to initialise { .length=count, .ptr=ptr } with value. -+ // -+ // while (count != 0) -+ // { -+ // *ptr = value; -+ // ptr += (*ptr).sizeof; -+ // count -= 1; -+ // } -+ tree pesize = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ptr))); -+ tree count_zero = d_convert (TREE_TYPE (count), integer_zero_node); -+ tree count_one = d_convert (TREE_TYPE (count), integer_one_node); -+ -+ startLoop (NULL); -+ continueHere(); -+ exitIfFalse (build_boolop (NE_EXPR, count, count_zero)); -+ -+ addExp (vmodify_expr (build_deref (ptr), value)); -+ addExp (vmodify_expr (ptr, build_offset (ptr, pesize))); -+ addExp (build2 (POSTDECREMENT_EXPR, TREE_TYPE (count), count, count_one)); -+ -+ endLoop(); -+ endBindings(); -+ -+ return popStatementList(); -+} -+ - // Routines for building statement lists around switches. STMT is the body --// of the switch statement, T_COND is the condition to the switch. If HAS_VARS -+// of the switch statement, COND is the condition to the switch. If HAS_VARS - // is true, then the switch statement has been converted to an if-then-else. - - void --IRBase::startCase (Statement *stmt, tree t_cond, int has_vars) -+IRState::startCase (Statement *stmt, tree cond, int has_vars) - { -- Flow *f = beginFlow (stmt); -- f->condition = t_cond; -- f->kind = level_switch; -+ Flow *flow = this->beginFlow (stmt); -+ flow->condition = cond; -+ flow->kind = level_switch; - if (has_vars) - { - // %% dummy value so the tree is not NULL -- f->hasVars = integer_one_node; -+ flow->hasVars = integer_one_node; - } - } - --// Emit a case statement for T_VALUE. -+// Emit a case statement for VALUE. - - void --IRBase::doCase (tree t_value, tree t_label) -+IRState::doCase (tree value, tree label) - { -- if (currentFlow()->hasVars) -- { -- // SwitchStatement has already taken care of label jumps. -- doLabel (t_label); -- } -+ // SwitchStatement has already taken care of label jumps. -+ if (this->currentFlow()->hasVars) -+ this->doLabel (label); - else - { -- tree t_case = build_case_label (t_value, NULL_TREE, t_label); -- addExp (t_case); -+ tree case_label = build_case_label (value, NULL_TREE, label); -+ this->addExp (case_label); - } - } - - // Wrap up constructed body into a SWITCH_EXPR. - - void --IRBase::endCase (void) -+IRState::endCase (void) - { -- Flow *f = currentFlow(); -- tree t_body = popStatementList(); -- tree t_condtype = TREE_TYPE (f->condition); -- if (f->hasVars) -- { -- // %% switch was converted to if-then-else expression -- addExp (t_body); -- } -+ Flow *flow = this->currentFlow(); -+ tree body = this->popStatementList(); -+ tree condtype = TREE_TYPE (flow->condition); -+ -+ // Switch was converted to if-then-else expression -+ if (flow->hasVars) -+ this->addExp (body); - else - { -- tree t_stmt = build3 (SWITCH_EXPR, t_condtype, f->condition, -- t_body, NULL_TREE); -- addExp (t_stmt); -+ tree stmt = build3 (SWITCH_EXPR, condtype, -+ flow->condition, body, NULL_TREE); -+ this->addExp (stmt); - } -- endFlow(); -+ -+ this->endFlow(); - } - - // Routines for building statement lists around try/catch/finally. - // Start a try statement, STMT is the body of the try expression. - - void --IRBase::startTry (Statement *stmt) -+IRState::startTry (Statement *stmt) - { -- beginFlow (stmt); -- currentFlow()->kind = level_try; -+ Flow *flow = this->beginFlow (stmt); -+ flow->kind = level_try; - } - - // Pops the try body and starts a new statement list for all catches. - - void --IRBase::startCatches (void) -+IRState::startCatches (void) - { -- currentFlow()->tryBody = popStatementList(); -- currentFlow()->kind = level_catch; -- pushStatementList(); -+ Flow *flow = this->currentFlow(); -+ flow->tryBody = this->popStatementList(); -+ flow->kind = level_catch; -+ this->pushStatementList(); - } - --// Start a new catch expression for exception type T_TYPE. -+// Start a new catch expression for exception type TYPE. - - void --IRBase::startCatch (tree t_type) -+IRState::startCatch (tree type) - { -- currentFlow()->catchType = t_type; -- pushStatementList(); -+ this->currentFlow()->catchType = type; -+ this->pushStatementList(); - } - - // Wrap up catch expression into a CATCH_EXPR. - - void --IRBase::endCatch (void) -+IRState::endCatch (void) - { -- tree t_body = popStatementList(); -+ tree body = this->popStatementList(); - // % Wrong loc... can set pass statement to startCatch, set -- // The loc on t_type and then use it here... -- addExp (build2 (CATCH_EXPR, void_type_node, -- currentFlow()->catchType, t_body)); -+ // The loc on type and then use it here... -+ this->addExp (build2 (CATCH_EXPR, void_type_node, -+ this->currentFlow()->catchType, body)); - } - - // Wrap up try/catch into a TRY_CATCH_EXPR. - - void --IRBase::endCatches (void) -+IRState::endCatches (void) - { -- tree t_catches = popStatementList(); -- object_file->doLineNote (currentFlow()->statement->loc); -- addExp (build2 (TRY_CATCH_EXPR, void_type_node, -- currentFlow()->tryBody, t_catches)); -- endFlow(); -+ Flow *flow = this->currentFlow(); -+ tree catches = this->popStatementList(); -+ -+ this->doLineNote (flow->statement->loc); -+ this->addExp (build2 (TRY_CATCH_EXPR, void_type_node, -+ flow->tryBody, catches)); -+ this->endFlow(); - } - - // Start a new finally expression. - - void --IRBase::startFinally (void) -+IRState::startFinally (void) - { -- currentFlow()->tryBody = popStatementList(); -- currentFlow()->kind = level_finally; -- pushStatementList(); -+ Flow *flow = this->currentFlow(); -+ flow->tryBody = this->popStatementList(); -+ flow->kind = level_finally; -+ this->pushStatementList(); - } - - // Wrap-up try/finally into a TRY_FINALLY_EXPR. - - void --IRBase::endFinally (void) -+IRState::endFinally (void) - { -- tree t_finally = popStatementList(); -- object_file->doLineNote (currentFlow()->statement->loc); -- addExp (build2 (TRY_FINALLY_EXPR, void_type_node, -- currentFlow()->tryBody, t_finally)); -- endFlow(); -+ Flow *flow = this->currentFlow(); -+ tree finally = this->popStatementList(); -+ -+ this->doLineNote (flow->statement->loc); -+ this->addExp (build2 (TRY_FINALLY_EXPR, void_type_node, -+ flow->tryBody, finally)); -+ this->endFlow(); - } - --// Emit a return expression of value T_VALUE. -+// Emit a return expression of value VALUE. - - void --IRBase::doReturn (tree t_value) -+IRState::doReturn (tree value) - { -- addExp (build1 (RETURN_EXPR, void_type_node, t_value)); -+ this->addExp (build1 (RETURN_EXPR, void_type_node, value)); - } - --// Emit goto expression to T_LABEL. -+// Emit goto expression to LABEL. - - void --IRBase::doJump (Statement *stmt, tree t_label) -+IRState::doJump (Statement *stmt, tree label) - { - if (stmt) -- object_file->doLineNote (stmt->loc); -- addExp (build1 (GOTO_EXPR, void_type_node, t_label)); -- TREE_USED (t_label) = 1; -+ this->doLineNote (stmt->loc); -+ -+ this->addExp (build1 (GOTO_EXPR, void_type_node, label)); -+ TREE_USED (label) = 1; - } - - // Routines for checking goto statements don't jump to invalid locations. - // In particular, it is illegal for a goto to be used to skip initializations. --// Saves the block label L is declared in for analysis later. -+// Saves the block LABEL is declared in for analysis later. - - void --IRBase::pushLabel (LabelDsymbol *l) -+IRState::pushLabel (LabelDsymbol *label) - { -- this->labels.push (getLabelBlock (l)); -+ Label *lblock = this->getLabelBlock (label); -+ this->labels_.safe_push (lblock); - } - - // Error if STMT is in it's own try statement separate from other - // cases in the switch statement. - - void --IRBase::checkSwitchCase (Statement *stmt, int default_flag) -+IRState::checkSwitchCase (Statement *stmt, int default_flag) - { -- Flow *flow = currentFlow(); -+ Flow *flow = this->currentFlow(); - -- gcc_assert (flow); - if (flow->kind != level_switch && flow->kind != level_block) - { - stmt->error ("%s cannot be in different try block level from switch", -@@ -601,18 +682,18 @@ IRBase::checkSwitchCase (Statement *stmt - // catch block. STMT is required to error on the correct line. - - void --IRBase::checkGoto (Statement *stmt, LabelDsymbol *label) -+IRState::checkGoto (Statement *stmt, LabelDsymbol *label) - { - Statement *curBlock = NULL; -- unsigned curLevel = this->loops.dim; -+ unsigned curLevel = this->loops_.length(); - int found = 0; - - if (curLevel) -- curBlock = currentFlow()->statement; -+ curBlock = this->currentFlow()->statement; - -- for (size_t i = 0; i < this->labels.dim; i++) -+ for (size_t i = 0; i < this->labels_.length(); i++) - { -- Label *linfo = this->labels[i]; -+ Label *linfo = this->labels_[i]; - gcc_assert (linfo); - - if (label == linfo->label) -@@ -635,9 +716,12 @@ IRBase::checkGoto (Statement *stmt, Labe - // Push forward referenced gotos. - if (!found) - { -+ Label *lblock = this->getLabelBlock (label, stmt); -+ - if (!label->statement->fwdrefs) - label->statement->fwdrefs = new Blocks(); -- label->statement->fwdrefs->push (getLabelBlock (label, stmt)); -+ -+ label->statement->fwdrefs->push (lblock); - } - } - -@@ -645,21 +729,21 @@ IRBase::checkGoto (Statement *stmt, Labe - // if goto is jumping into a try or catch block. - - void --IRBase::checkPreviousGoto (Array *refs) -+IRState::checkPreviousGoto (Blocks *refs) - { - Statement *stmt; // Our forward reference. - - for (size_t i = 0; i < refs->dim; i++) - { -- Label *ref = (Label *) refs->data[i]; -+ Label *ref = (*refs)[i]; - int found = 0; - - gcc_assert (ref && ref->from); - stmt = ref->from; - -- for (size_t i = 0; i < this->labels.dim; i++) -+ for (size_t i = 0; i < this->labels_.length(); i++) - { -- Label *linfo = this->labels[i]; -+ Label *linfo = this->labels_[i]; - gcc_assert (linfo); - - if (ref->label == linfo->label) ---- a/src/gcc/d/d-irstate.h 2013-06-01 16:19:09.000000000 +0100 -+++ b/src/gcc/d/d-irstate.h 2014-04-01 16:32:51.000000000 +0100 -@@ -1,5 +1,5 @@ - // d-irstate.h -- D frontend for GCC. --// Copyright (C) 2011, 2012 Free Software Foundation, Inc. -+// Copyright (C) 2011-2013 Free Software Foundation, Inc. - - // GCC is free software; you can redistribute it and/or modify it under - // the terms of the GNU General Public License as published by the Free -@@ -88,27 +88,25 @@ struct Flow - }; - - --typedef ArrayBase